3.6 下拉列表框QComboBox
3.6.1 QComboBox功能概述
QComboBox是下拉列表框组件,它提供一个下拉列表供用户选择,也可以直接当作一个QLineEdit用于字符串输入。QComboBox除了显示可见下拉列表外,每个项(item,或称列表项)还可以关联一个QVariant类型的用户数据,用于存储一些在列表中不可见的数据。
示例Demo3_6演示了QComboBox的用法,其运行时界面如图3-8所示。
图3-8 示例Demo3_6运行时界面
窗口左侧“简单的ComboBox”分组框里是一个不带用户数据的简单的ComboBox,右侧“有用户数据的ComboBox”分组框里是每个项带有一个用户数据的ComboBox,每个项是一个城市名,关联的数据是城市的区号。
QComboBox主要的功能是提供一个下拉列表供选择输入。在可视化设计窗体时,在界面上放置一个QComboBox组件后,双击此组件会出现如图3-9所示的对话框,可以对QComboBox组件的下拉列表的项进行编辑。在此对话框中可以进行编辑、添加、删除、上移、下移等操作,可以设置项的图标。
图3-9 QComboBox组件设计时的列表项编辑器
窗体UI文件Widget.ui在UI Designer里可视化设计,界面上组件的布局和属性设置见源文件Widget.ui。
下面是myWidget.py文件中的import部分和QmyWidget类构造函数的代码:
import sys from PyQt5.QtWidgets import QApplication, QWidget from PyQt5.QtCore import pyqtSlot from PyQt5.QtGui import QIcon from ui_Widget import Ui_Widget class QmyWidget(QWidget): def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui=Ui_Widget() #创建UI对象 self.ui.setupUi(self) #构造UI
import部分显示了本示例用到的一些PyQt5的类及其所在的模块,构造函数显示了窗体构建时的初始化工作,其余的代码在后面逐渐展开介绍。QmyWidget的构造只是创建了窗体,没有做其他初始化工作。
3.6.2 简单的ComboBox操作
1.初始化列表
“初始化列表”按钮用于创建“简单的ComboBox”分组框里的ComboBox组件的列表内容,其槽函数代码如下:
def on_btnIniItems_clicked(self): ##"初始化列表"按钮 ##设置图标的操作 icon=QIcon(":/icons/images/aim.ico") self.ui.comboBox.clear() #清除列表 provinces=["山东", "河北", "河南", "湖北", "湖南", "广东"] #列表数据 for i in range(len(provinces)): self.ui.comboBox.addItem(icon, provinces[i])
其中,icon是图标类QIcon的实例,从资源文件获取图标数据;provinces是一个字符串列表。
QComboBox的addItem()函数用于添加一个项到列表里,它是一个overload型函数,其两种带参数的原型定义如下:
addItem(self, str, userData: Any = None) addItem(self, QIcon, str, userData: Any = None)
第一种参数的addItem()函数添加一个项的文字,用户数据是可选添加的。第二种参数的addItem()函数添加一个项的图标和文字,用户数据是可选添加的。
槽函数on_btnIniItems_clicked()的代码为每个项设置了一个图标。如果不需要为每个项设置图标,只是添加一个字符串列表,可以简化为如下代码:
def on_btnIniItems_clicked(self): ##"初始化列表"按钮 self.ui.comboBox.clear() #清除列表 provinces=["山东", "河北", "河南", "湖北", "湖南", "广东"] #列表数据 self.ui.comboBox.addItems(provinces) #直接添加列表,但无法加图标
这里使用了QComboBox的addItems()函数将字符串列表provinces的内容全部添加到列表框里,provinces的每一项作为列表框的一个条目,只是没有图标。
2.可编辑操作的ComboBox
窗体上的“可编辑”复选框可设置组件ComboBox的editable属性的值,其槽函数代码如下:
@pyqtSlot(bool) ##"可编辑"CheckBox def on_chkBoxEditable_clicked(self, checked): self.ui.comboBox.setEditable(checked)
当editable属性为False时,只能从ComboBox组件的下拉列表中选择,而不能直接输入;当editable属性为True时,ComboBox组件具有QLineEdit的功能,可以直接输入内容,并且按回车键后,新输入的内容会添加到下拉列表里。
3.ComboBox的项选择操作
在一个QComboBox组件上的选择项发生变化时,会发射currentIndexChanged信号,这是一个overload型信号,有两种类型的参数,其定义如下:
currentIndexChanged(int) currentIndexChanged(str)
这两个信号中的一个传递的是当前项的索引号,另一个传递的是当前项的文字。
选择为currentIndexChanged(str)信号编写槽函数(必须使用@pyqtSlot修饰符标明参数类型),将当前选择项的字符串显示到编辑框里,代码如下:
@pyqtSlot(str) ##"简单的ComboBox"的当前项变化 def on_comboBox_currentIndexChanged(self, curText): self.ui.lineEdit.setText(curText)
3.6.3 带用户数据的ComboBox
在使用QComboBox的addItem()函数添加一个条目时,还可以为每个项设定一个用户数据,这个用户数据是不显示在下拉列表里的。
界面上另一个ComboBox组件使用了用户数据,“初始化城市+区号”按钮的槽函数代码如下:
def on_btnIni2_clicked(self): ##有用户数据的comboBox2的初始化 icon=QIcon(":/icons/images/unit.ico") self.ui.comboBox2.clear() cities={"北京":10, "上海":21, "天津":22, "徐州":516, "福州":591, "青岛":532} #字典数据 for k in cities: self.ui.comboBox2.addItem(icon, k, cities[k])
这里使用了一个字典数据cities,它的每一个条目存储的是城市名称及其对应的区号。为comboBox2添加项时,区号作为项的用户数据。
为comboBox2的currentIndexChanged(str)信号编写槽函数,代码如下:
@pyqtSlot(str) ##当前项变化 def on_comboBox2_currentIndexChanged(self, curText): self.ui.lineEdit.setText(curText) zone=self.ui.comboBox2.currentData() #读取关联数据 if (zone ! = None): #必须加此判断,因为有可能是None self.ui.lineEdit.setText(curText+":区号=%d"%zone)
这里通过QComboBox的currentData()函数读取当前项的用户数据。
3.6.4 QComboBox常用函数总结
QComboBox存储的项是一个列表,但是QComboBox不提供整个列表用于访问,而可以通过索引访问某个项。访问项的一些函数主要有以下几个。
· currentIndex():返回当前项的序号,第一项的序号为0。
· currentText():返回当前项的文字。
· currentData(role):返回当前项的关联数据,参数role表示数据角色,角色role的默认值为Qt.UserRole。可以为一个项定义多个角色的用户数据,更多自定义角色的编号从Qt.UserRole开始增加,如Qt.UserRole + 1、Qt.UserRole + 2。
· itemText(index):返回索引号为index的项的文字。
· itemData(index, role):返回索引号为index的项的角色为role的关联数据,角色role的默认值为Qt.UserRole。
· count():返回项的个数。