QComboBox 是下拉列表框组件,它可以提供下拉列表供用户选择输入,也可以提供编辑框用于输入文字, 所以 QComboBox 也被称为组合框。下拉列表框的下拉列表的每个项(item, 或称为列表项)可以存储一个或多个 QVariant 类型的用户数据,用户数据并不显示在界面上。
QComboBox 类的主要属性如表所示:
属性 | 属性值类型 | 功能 |
editable | bool | 是否可编辑。如果值为 false,就只能从下拉列表里选择;如果值为 true,会显 示一个编辑框允许输入文字 |
currentText | QString | 当前显示的文字 |
currentIndex | int | 当前选中项的序号,序号从 0 开始。−1 表示没有项被选中 |
maxVisibleItems | int | 下拉列表中显示的项的最大条数,默认值为 10。如果下拉列表里项的条数超过这个值,会自动出现卷滚条 |
maxCount | int | 下拉列表里项的最大条数 |
insertPolicy | InsertPolicy | 用户编辑的新文字插入列表的方式,是枚举类型 QComboBox::InsertPolicy,默认值 是 InsertAtBottom,也就是插入列表的末尾。如果值是 NoInsert,就表示不允许插入 |
placeholderText | QString | 占位文字。当 currentIndex 属性值为−1 时下拉列表框显示的文字。这个文字不会出现在下拉列表里 |
duplicatesEnabled | bool | 是否允许列表中出现重复的项 |
modelColumn | int | 下拉列表中的数据在数据模型中的列编号,默认值为 0 |
QComboBox 使用模型/视图结构存储和显示下拉列表的数据,下拉列表的数据实际上存储在 QStandardItemModel 模型里,下拉列表是用 QListView 的子类组件显示的。modelColumn 属性表 示下拉列表显示的数据在模型中的列编号,默认值为 0。
QComboBox 的接口函数中的一部分是这些属性的读写函数,另一部分主要是操作列表的函数,例如添加、插入或移除列表项。
QComboBox 定义的几个信号的函数原型如下, 函数中的参数 index 是项的序号, text 是项的文字。
void activated(int index)
void currentIndexChanged(int index)
void currentTextChanged(const QString &text)
void editTextChanged(const QString &text)
void highlighted(int index)
void textActivated(const QString &text)
void textHighlighted(const QString &text)
• 选择下拉列表的一个项时,即使选择的项没有发生变化,组件也会发射 activated()信号。
• 当 currentIndex 属性变化时,不管是用户在界面操作还是程序导致 currentIndex 变化,组件都会发射 currentIndexChanged()信号。
• 当 currentText 属性变化时,不管是用户在界面操作还是程序导致 currentText 变化,组件都会发射 currentTextChanged()信号。
• 在编辑框中修改文字时,组件会发射 editTextChanged()信号。
• 移动鼠标使下拉列表中的某一项被高亮显示但还没有完成选择时,组件会发射 highlighted() 信号。
• 在下拉列表中选择某一项时,即使选择的项没有发生变化,组件也会发射 textActivated() 信号。 • 当下拉列表中的某一项被高亮显示但还没有完成选择时,组件会发射 textHighlighted()信号。
示例项目的窗口基类是 QWidget,界面布置如左图:
QComboBox 的主要功能是提供下拉列表供选择输入。 在 Qt Designer 中进行 UI 可视化设计时,在窗体上放置一个 QComboBox 组件后,双击此组件,会出现图右所示的对话框,用于对组件的下拉列表进行编辑。在这个对话框中,我们可以添加、移除、上移、下移列表项,对每个列表项可以设置文字和图标。
下拉列表框有一个下拉列表供用户选择输入,QComboBox 提供了一些接口函数用于操作列表内 容,包括添加项、插入项、移除项等。
(1)添加一个项。函数 addItem()用于向列表添加一个项,它有两种参数形式,其函数原型定义如下:
void addItem(const QString &text, const QVariant &userData = QVariant())
void addItem(const QIcon &icon, const QString &text, const QVariant &userData = QVariant())
使用函数 addItem()添加项时,除了可以设置文字,还可以设置图标,或设置 QVariant 类型数据作为项的用户数据。
上左图所示界面上的“初始化列表”按钮用于初始化左边的下拉列表框的列表内容,其代码如下,为界面上的 QComboBox 组件 comboBox 初始化列表内容,并为每个项设置了图标。
void Widget::on_btnIniItems_clicked()
{//“初始化列表”按钮
QIcon icon;
icon.addFile(":/images/icons/aim.ico"); //从资源文件中获取图标
ui->comboBox->clear(); //清除列表
for (int i=0; i<20; i++)
ui->comboBox->addItem(icon,QString("Item %1").arg(i)); //带有图标
// ui->comboBox->addItem(QString("Item %1").arg(i)); //不带有图标
}
界面右侧的 QComboBox 组件的列表项使用了用户数据,“初始化城市+区号”按 钮的槽函数代码如下:
void Widget::on_btnIni2_clicked()
{//“初始化城市+区号”按钮
//QMap 自动按照 key 排序
QMap City_Zone;
City_Zone.insert("北京",10);
City_Zone.insert("上海",21);
City_Zone.insert("天津",22);
City_Zone.insert("大连",411);
City_Zone.insert("锦州",416);
City_Zone.insert("徐州",516);
City_Zone.insert("福州",591);
City_Zone.insert("青岛",532);
ui->comboBox2->clear();
foreach(const QString &str, City_Zone.keys())
ui->comboBox2->addItem(str,City_Zone.value(str));
}
上述代码里定义了一个关联容器 QMap City_Zone,用于存储映射表。为 City_Zone 填充数据后,给 comboBox2 添加列表项的语句是:
ui->comboBox2->addItem(str, City_Zone.value(str));
城市名称作为列表显示的文字,区号作为项的用户数据,但是在界面上只能看到城市名称。
(2)添加多个项。函数 addItems()可以一次性向列表添加多个项,其函数原型定义如下:
void addItems(const QStringList &texts)
它用一个字符串列表作为输入参数,字符串列表的每一项作为下拉列表的一项。示例代码如下:
ui->comboBox->clear();
QStringList strList;
strList<<"北京"<<"上海"<<"天津"<<"河北省"<<"山东省"<<"山西省";
ui->comboBox->addItems(strList);
用函数 addItems()添加的列表项只有文字,没有图标和用户数据。
(3)插入项。函数 insertItem()可以向列表插入一个项,insertItems()可以一次插入多个项,其函数原型定义如下:
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 &list)
这几个函数中的参数与 addItem()和 addItems()中同名参数的意义相同, 只是多了一个参数 index,表示插入项的位置序号。如果 index 大于列表的总项数,就插入列表末尾。
(4)移除项和清除列表。函数 removeItem()用于移除列表中的某个项,函数 clear()用于清除整 个列表的内容,其函数原型定义如下:
void removeItem(int index) //移除序号为 index 的项
void clear() //清除整个列表
(5)访问列表项。在下拉列表中选择一个项之后就有了当前项,可以获得当前项的序号、文字和用户数据,还可以通过序号访问列表中的某个项。QComboBox 中用于项的访问的一些函数定义如下,各函数的基本功能见注释。
int count() //返回列表中项的总数
int currentIndex() //返回当前项的序号
QString currentText() //返回当前项的文字
QVariant currentData(int role = Qt::UserRole) //返回当前项的用户数据
QString itemText(int index) //返回序号为 index 项的文字
QIcon itemIcon(int index) //返回序号为 index 项的图标
QVariant itemData(int index, int role = Qt::UserRole) //返回序号为 index 项的用户数据
void setItemText(int index, const QString &text) //设置序号为 index 项的文字
void setItemIcon(int index, const QIcon &icon) //设置序号为 index 项的图标
void setItemData(int index, const QVariant &value, int role = Qt::UserRole)
用函数 currentData()或 itemData()访问用户数据时有一个角色参数 role,默认值是 Qt::UserRole,表示用户数据。在使用函数 addItem()添加项时,若传递了用户数据,用户数据的 role 值就是 Qt::UserRole。
实际上,一个项可以设置不止一个用户数据,用函数 setItemData()可以为一个项设置更多的用户数据,例如设置第二个用户数据时,传递 role 的值为 1+Qt::UserRole 即可。
QComboBox 有多个信号,我们应该根据程序要实现的功能选择合适的信号进行处理。对于界面中“简单 ComboBox”分组框里的组件 comboBox,我们为其 currentTextChanged()信号编写槽函数,代码如下:
void Widget::on_comboBox_currentTextChanged(const QString &arg1)
{
ui->plainTextEdit->appendPlainText(arg1);
}
函数中传递的参数 arg1 就是变化之后的文字。如果是通过下拉列表选择,arg1 就是新的当前项的文字;如果是在编辑框里修改文字,arg1 就是编辑框里最新的文字。
对于界面中右边的组件 comboBox2,因为它的项包含用户数据,所以我们为其 currentIndex Changed()信号编写槽函数,代码如下:
void Widget::on_comboBox2_currentIndexChanged(int index)
{
Q_UNUSED(index);
QString city= ui->comboBox2->currentText(); //当前文字
QString zone= ui->comboBox2->currentData().toString(); //当前用户数据
ui->plainTextEdit->appendPlainText(city+": 区号 = "+zone);
}
函数中传递的参数index是当前项的序号, 但是程序中没有使用这个参数, 而是直接通过currentText()获得当前项的文字,通过 currentData()获得当前项的用户数据。用户数据是 QVariant 类型,可以存储任意类型的数据。