[Qt 教程之Widgets模块] —— QComboBox 组合框

Qt系列教程总目录

文章目录

    • 一、创建QComboBox
    • 二、数据结构
    • 三、成员函数
      • 1. 添加选项
      • 2. 插入选项
      • 3. 删除选项
      • 4. 选项属性
      • 5. 当前选择的item
      • 6. 用户是否可编辑组合框
      • 7. 设置显示item的个数
      • 8. 组合框的item个数
      • 9. 添加重复的item
      • 10. 是否绘制边框
      • 11. 查找item
      • 12. 插入策略
      • 13. 大小调整策略
      • 14. 占位符文本
      • 15. 自定义数据模型

组合框 QComboBox即我们常用的下拉列表,如下是一些使用示例:

office word 中的字体字号设置、段落设置等,很普遍的使用了类似 QComboBox 的下拉列表。

[Qt 教程之Widgets模块] —— QComboBox 组合框_第1张图片

[Qt 教程之Widgets模块] —— QComboBox 组合框_第2张图片

QComboBox 不仅可以用于多选项选择,还节省屏幕空间。

一、创建QComboBox

他只有一个构造函数

QComboBox(QWidget *parent = nullptr);

使用时一般传入父级窗口对象指针。

二、数据结构

QComboBox 可以看做是一个类似列表的容器,列表每一项是一个item对象,该对象有类似 Map 的成员,Map包含类似texticonkey,并在value域存储对应的数据。

[Qt 教程之Widgets模块] —— QComboBox 组合框_第3张图片

对于 key ,Qt有自己的枚举定义,如下:

enum ItemDataRole {
    DisplayRole = 0,
    DecorationRole = 1,
    EditRole = 2,
    ToolTipRole = 3,
    StatusTipRole = 4,
    WhatsThisRole = 5,
    // Metadata
    FontRole = 6,
    TextAlignmentRole = 7,
    BackgroundRole = 8,
    ForegroundRole = 9,
    CheckStateRole = 10,
    // Accessibility
    AccessibleTextRole = 11,
    AccessibleDescriptionRole = 12,
    // More general purpose
    SizeHintRole = 13,
    InitialSortOrderRole = 14,
    // Internal UiLib roles. Start worrying when public roles go that high.
    DisplayPropertyRole = 27,
    DecorationPropertyRole = 28,
    ToolTipPropertyRole = 29,
    StatusTipPropertyRole = 30,
    WhatsThisPropertyRole = 31,
    // Reserved
    UserRole = 0x0100
};

枚举说明如下:

常量 描述 value的数据类型
Qt::DisplayRole 0 要以文本形式呈现的数据 QString
Qt::DecorationRole 1 要以图标形式呈现的数据 QColor/QIcon/QPixmap
Qt::EditRole 2 适合在编辑器中编辑的数据 QString
Qt::ToolTipRole 3 显示在item的工具提示中的数据 QString
Qt::StatusTipRole 4 状态栏中显示的数据 QString
Qt::WhatsThisRole 5 显示在项目的“what is this?”模式下的数据 QString
Qt::FontRole 6 item的默认字体 QFont
Qt::TextAlignmentRole 7 item的文本对齐方式 Qt::Alignment
Qt::BackgroundRole 8 item的背景笔刷 QBrush
Qt::ForegroundRole 9 item的前景笔刷(通常为文本颜色) QBrush
Qt::CheckStateRole 10 用于获取item的已检查状态 Qt::CheckState
Qt::AccessibleTextRole 11 可访问性扩展和插件(如屏幕阅读器)要使用的文本 QString
Qt::AccessibleDescriptionRole 12 出于可访问性目的对item的描述 QString
Qt::SizeHintRole 13 提供给视图的项目的建议尺寸 QSize
Qt::InitialSortOrderRole 14 获取页眉视图部分的初始排序顺序(Qt 4.8引入) Qt::SortOrder
Qt::DisplayPropertyRole 27 Qt内部使用 -
Qt::DecorationPropertyRole 28 Qt内部使用 -
Qt::ToolTipPropertyRole 29 Qt内部使用 -
Qt::StatusTipPropertyRole 30 Qt内部使用 -
Qt::WhatsThisPropertyRole 31 Qt内部使用 -
Qt::UserRole 0x0100 存储用户数据 由用户决定使用哪些类型,并确保组件在访问和设置数据时使用正确的类型

三、成员函数

1. 添加选项

void addItem(const QString &text, const QVariant &userData = QVariant());
void addItem(const QIcon &icon, const QString &text,
             const QVariant &userData = QVariant());
void addItems(const QStringList &texts){ insertItems(count(), texts); }

该函数在列表的末尾添加item,其中userData是用户数据,用户可以把 QComboBox 作为选择列表使用,也可以看作是类似 Map 的存储容器,在选择时操作用户自定义数据。

2. 插入选项

void insertItem(int index, const QString &text, const QVariant &userData = QVariant());
void insertItem(int index, const QIcon &icon, const QString &text,
                const QVariant &userData = QVariant());
void insertItems(int index, const QStringList &texts);

通过指定索引插入 item

3. 删除选项

void removeItem(int index);

通过指定索引删除 item

4. 选项属性

void setItemText(int index, const QString &text); // 设置item的文本
void setItemIcon(int index, const QIcon &icon); // 设置item的图标
void setIconSize(const QSize &size); // 设置item的图标尺寸
// 设置item的用户数据
void setItemData(int index, const QVariant &value, int role = Qt::UserRole);
void setMaxCount(int max); // 设置item的允许最大数量

QString itemText(int index) const; // 获取item的文本
QIcon itemIcon(int index) const; // 获取item的图标
QSize iconSize() const; // 获取item的图标尺寸
QVariant itemData(int index, int role = Qt::UserRole) const; // 获取item的用户数据
int count() const; // 获取item的数量
int maxCount() const; // 获取item的允许最大数量

5. 当前选择的item

int currentIndex() const;
QString currentText() const;
QVariant currentData(int role = Qt::UserRole) const;

获取当前选择的 item 的文本、图标和用户数据。

6. 用户是否可编辑组合框

bool isEditable() const;
void setEditable(bool editable);

下拉列表不仅可供选择,也可以让用户输入列表中没有的选项(默认不可编辑),如下图:

[Qt 教程之Widgets模块] —— QComboBox 组合框_第4张图片

另外还有一个函数也可以实现组合框可编辑:

void setLineEdit(QLineEdit *edit);
QLineEdit *lineEdit() const;

他将行编辑框的编辑权赋予组合框,实际上在函数setEditable 内部也调用了 setLineEdit,如下:

[Qt 教程之Widgets模块] —— QComboBox 组合框_第5张图片

7. 设置显示item的个数

int maxVisibleItems() const;
void setMaxVisibleItems(int maxItems);

一般情况下,下拉列表有多少 item 就会显示多少,如下:

[Qt 教程之Widgets模块] —— QComboBox 组合框_第6张图片

item 过多,会显得不美观,可以通过该函数设置显示item的个数,如下设置最大显示个数为 5,其余会隐藏在滚动条中:

[Qt 教程之Widgets模块] —— QComboBox 组合框_第7张图片

关于这个函数有一个很迷的现象,官方文档有如下描述:

[Qt 教程之Widgets模块] —— QComboBox 组合框_第8张图片

对于不可编辑的组合框,QStyle::SH_ComboBox_Popup返回true,该属性将被忽略,例如 Mac styleGtk+ Style

然而,在 ubuntu 系统下,对于不可编辑的组合框,QStyle::SH_ComboBox_Popup返回 0,该属性仍然未生效;在windows 系统下,对于不可编辑的组合框,QStyle::SH_ComboBox_Popup返回 0,该属性生效。

如你知道原因欢迎评论区留言。

有图有真相:

Ubuntu下:

[Qt 教程之Widgets模块] —— QComboBox 组合框_第9张图片

Windows下:

[Qt 教程之Widgets模块] —— QComboBox 组合框_第10张图片

该问题可以通过以下方法规避,即使该属性在 Ubuntu 系统中生效:

方法一:设置组合框可编辑,setEditable(true);

方法二:设置setStyleSheet("QComboBox{combobox-popup:0;}");

8. 组合框的item个数

int count() const;	// 当前存储的item个数
void setMaxCount(int max);  // 设置允许存储的item最大个数
int maxCount() const; // 获取允许存储的item最大个数

如果设置的最大个数小于当前存储的个数,多余的item会被删除。

9. 添加重复的item

有时会在组合框中添加重复的项,如下:

[Qt 教程之Widgets模块] —— QComboBox 组合框_第11张图片

有两种方式添加重复项,一种是通过代码(Qt总是允许通过代码添加重复项),如下:

ui->comboBox->addItem("item1");
ui->comboBox->addItem("item2");
ui->comboBox->addItem("item3");
ui->comboBox->addItem("item4");
ui->comboBox->addItem("item4");

第二种是用户编辑输入,但Qt默认不允许这种方式,需要设置属性:

bool duplicatesEnabled() const;
void setDuplicatesEnabled(bool enable);

10. 是否绘制边框

void setFrame(bool);
bool hasFrame() const;

11. 查找item

// 通过text查找
inline int findText(const QString &text, Qt::MatchFlags flags = static_cast<Qt::MatchFlags>(Qt::MatchExactly|Qt::MatchCaseSensitive)) const
{ return findData(text, Qt::DisplayRole, flags); }

// 通过data查找
int findData(const QVariant &data, int role = Qt::UserRole, Qt::MatchFlags flags = static_cast<Qt::MatchFlags>(Qt::MatchExactly|Qt::MatchCaseSensitive)) const;

可以发现 findText 也是通过 findData 实现的,所以对于其他属性的搜索,我们也可以通过 findData 实现,因为 findDatadata 参数是通用类型,使用时只需指定相应的 role 即可(role枚举见ItemDataRole)。

第三个参数 flags 定义了匹配方式,Qt::MatchFlags 枚举如下:

enum MatchFlag {
    MatchExactly = 0,
    MatchContains = 1,
    MatchStartsWith = 2,
    MatchEndsWith = 3,
    MatchRegularExpression = 4,
    MatchWildcard = 5,
    MatchFixedString = 8,
    MatchTypeMask = 0x0F,
    MatchCaseSensitive = 16,
    MatchWrap = 32,
    MatchRecursive = 64
};

枚举成员描述如下:

常量 描述
Qt::MatchExactly 0 搜索词与item的完全匹配
Qt::MatchContains 1 搜索词包含在item中
Qt::MatchStartsWith 2 搜索词与item的开头匹配
Qt::MatchEndsWith 3 搜索词与item的结尾匹配
Qt::MatchRegularExpression 4 使用正则表达式作为搜索项执行基于字符串的匹配。
Qt::MatchWildcard 5 使用带有通配符的字符串作为搜索词,执行基于字符串的匹配。
Qt::MatchFixedString 8 执行基于字符串的匹配。除非同时指定MatchCaseSensitive标志,否则基于字符串的比较不区分大小写。
Qt::MatchCaseSensitive 16 搜索区分大小写。
Qt::MatchWrap 32 执行一个环绕的搜索,这样,当搜索到达模型中的最后一个项目时,它会从第一个项目开始,并一直持续到检查完所有项目为止。
MatchRecursive 64 搜索整个层次结构。

注意:Qt::MatchExampleteQt::MatchContainsQt::MatchStartsWithQt::MatchEndsWithQt::MatchRegularExpressionQt::MatchWildcardQt::MatchFixedString 是互斥的,Qt还不支持通过 Qt::MatchFlags 参数同时设置多个。

12. 插入策略

当组合框可编辑,用户可以通过手动输入来添加item,这时新的item 插入到哪里,由枚举 InsertPolicy指定,默认为 InsertAtBottom在下方新增,使用如下方法设置插入策略:

InsertPolicy insertPolicy() const;
void setInsertPolicy(InsertPolicy policy);

InsertPolicy枚举如下:

enum InsertPolicy {
    NoInsert,
    InsertAtTop,
    InsertAtCurrent,
    InsertAtBottom,
    InsertAfterCurrent,
    InsertBeforeCurrent,
    InsertAlphabetically
};

说明如下:

常量 描述
QComboBox::NoInsert 0 字符串不会插入到组合框中
QComboBox::InsertAtTop 1 字符串会被插入到组合框的第一个位置
QComboBox::InsertAtCurrent 2 当前选择的item会被新的字符串覆盖
QComboBox::InsertAtBottom 3 字符串会被插入到组合框的最后一个位置
QComboBox::InsertAfterCurrent 4 字符串会被插入到当前选择的后一个位置
QComboBox::InsertBeforeCurrent 5 字符串会被插入到当前选择的前一个位置
QComboBox::InsertAlphabetically 6 字符串按字母顺序插入组合框中

13. 大小调整策略

由于不同item的内容长度不同,组合框的大小调整会有一定策略,默认 AdjustToContentsOnFirstShow,使用如下函数设置该策略:

SizeAdjustPolicy sizeAdjustPolicy() const;
void setSizeAdjustPolicy(SizeAdjustPolicy policy);

策略枚举如下:

enum SizeAdjustPolicy {
    AdjustToContents,
    AdjustToContentsOnFirstShow,
    AdjustToMinimumContentsLengthWithIcon
};

说明如下:

常量 描述
QComboBox::AdjustToContents 0 始终根据item内容进行调整,以使其全部显示
QComboBox::AdjustToContentsOnFirstShow 1 组合框将在第一次显示时根据item内容进行调整
QComboBox::AdjustToMinimumContentsLengthWithIcon 2 组合框将调整为最小内容长度加上图标空间。使用该策略,需要考虑性能问题

其中MinimumContentsLengthiconSize都可以另外设置,方法如下:

int minimumContentsLength() const; // 默认为0
void setMinimumContentsLength(int characters);
QSize iconSize() const;
void setIconSize(const QSize &size);

14. 占位符文本

当组合框没有任何 item 时,可以添加占位符文本,以使组合框显示不为空,如下:

[Qt 教程之Widgets模块] —— QComboBox 组合框_第12张图片

当然,占位符是灰色的不可被选择的。

方法接口如下:

void setPlaceholderText(const QString &placeholderText);
QString placeholderText() const;

15. 自定义数据模型

组合框除了显示为下拉列表,也可以显示自定义的数据模型,比如树或表格,相关方法如下:

QAbstractItemModel *model() const;
virtual void setModel(QAbstractItemModel *model); // 将自定义的数据模型添加到组合框

QModelIndex rootModelIndex() const;
void setRootModelIndex(const QModelIndex &index); // 设置项目的根模型项目索引

int modelColumn() const;
// 设置模型可见列。如果在填充组合框之前设置,则视图不受影响,将显示第一列(使用此属性的默认值0)。
void setModelColumn(int visibleColumn);

你可能感兴趣的:(Qt,qt,开发语言,c++,QComboBox,组合框)