我们在前面分别介绍了两种输入控件:纯键盘文本输入和步长调节器,下面我们来学习下组合框(下拉选择输入)。

一.简介

  1.下拉框是一个组合控件(包含一个文本显示控件和一个按钮)。它默认显示最小的控件给用户来操作,并且可以用下拉选择的界面提供给用户更多的预置选项。

  

  2.它是直接继承自QWidget。

二.功能作用

  1.构造函数。

  可以直接实例化,不用传递参数。

  2.数据操作

  数据的操作主要分对数据项的增删改和一些其他的操作

    a.增加项目

     下拉框的内容有两种增加方式:追加和指定位置添加。

QComboBox.addItem(self, text: str, userData: typing.Any = ...)                                     #追加内容
QComboBox.addItem(self, icon: QtGui.QIcon, text: str, userData: typing.Any = ...) #追加内容(带图标)
QComboBox.insertItem(self, index: int, text: str, userData: typing.Any = ...)        #指定位置添加内容
QComboBox.insertItem(self, indx: int, icon: QtGui.QIcon, text: str, userData: typing.Any = ...) #指定位置添加内容(带图标)

可以看到有个参数是userdata,其实就是可以附带的内容,在面板上不显示,但是可以包含的内容。比方我们选择区号,面板上只显示地名,选择好后后台接收的内容是地名对应的数字。

     还有一种增加的方法:批量增加。用一个可迭代的数据就可以

QComboBox.addItems(self, texts: typing.Iterable[str])
QComboBox.insertItems(self, index: int, texts: typing.Iterable[str])

这里的可迭代对象可以是元组、列表,但内容必须是字符串类型的。但要注意的是虽然字符串也属于可迭代对象,但这里是不能用的。

    b.删除项目

        删除项目很简单,只要指定需要删除的项目的所索引值就可以了

QComboBox.removeItem(self, index: int)   #删除项目

    c.改指定项目

QComboBox.setItemIcon(self, index: int, icon: QtGui.QIcon)                  #改指定的项目图标
QComboBox.(self, index: int, text: str) #改指定项目的显示文本
QComboBox.setItemData(self, index: int, value: typing.Any, role: int = ...) #改指定项目的userdata

    D.编辑当前显示文本

     如果没有指定的索引值或文本内容,则显示状态不变。

QComboBox.setCurrentIndex(self, index: int)     #按指定索引值显示
QComboBox.setCurrentText(self, text: str) #按指定文本显示

    E.插入分割线

QComboBox.insertSeparator(self, index: int)     #在指定索引位置插入分割线

    F.被编辑状态

        如果控件设置了可被编辑,就可以用键盘输入新的内容。在有新的文本被输入,控件失去焦点后,所输入的文本会自动添加在最后面,就像qq登陆时的记住账号一样,只要输入一遍就有这个选项了。

QComboBox.setEditable(self, editable: bool)         #设置可被编辑

       这个编辑状态还可以结合当前文本的显示

QComboBox.setEditText(self, text: str)                #设置当前显示的文本

这里有个现象,就是如果在调用上面这条指令前文本框里显示的有图标,在用这条这里后图标时不会变化的,只是后面的文本改了。敲一下回车就好了。

    G.插入模型(树形表)

        这个用法以后再详细讲,现在就说一下是怎么用的

from PyQt5.Qt import *
import sys class Window(QWidget):
def __init__(self):
super().__init__()
self.UI_test() def UI_test(self):
cb = QComboBox(self)
model = QStandardItemModel() #创建标准树形视图模型
item1 = QStandardItem('item1')
item2 = QStandardItem('item2')
item2_1 = QStandardItem('item2_1')
item2.appendRow(item2_1) #把item2_1列为item2的子列表
model.appendRow(item1)
model.appendRow(item2)
cb.setModel(model)
cb.setView(QTreeView(cb)) #试图设置
pass
if __name__ == '__main__':
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())

树形结构

    H.数据的获取

QComboBox.count()                       #获取项目个数——>int
QComboBox.itemIcon(index=) #获取指定项目的图标对象——>QIcon
QComboBox.itemText(index=) #获取指定项目的文本——>str
QComboBox.itemData(index=) #获取指定项目的userdat——>Any
QComboBox.currentIndex() #获取当前项目的索引值——>int
QComboBox.currentText() #获取当前项目文本——>str
QComboBox.currentData() #获取当前项目的userdata——>Any

这里插播一个lambda的用法:有些信号是带有传递的参数的,但是如果我们不想用这个参数时,可以把这个参数屏蔽掉,比如我们添加一个按钮,点击按钮后获取最后一个项的文本

cb = QComboBox(self)
cb.addItems(['a','b','c'])
cb.move(100,200)
btn = QPushButton('test',self)
btn.move(100,150)
btn.clicked.connect(lambda val-1 = cb.count():print(cb.itemText(val)))

点击按钮发现打印的时False,为什么呢?因为按钮再被clicked的时候是会发送一个布尔量作为参数的,那么val再有参数进来时时用实际传递的参数。这时候就需要把这个参数屏蔽掉

btn.clicked.connect(lambda _,val = cb.count()-1:print(cb.itemText(val)))

    I.数据的限制

          一般数据的限制是和可编辑的状态同时使用的,用了数据限制可以限制数据的条数。

QComboBox.setMaxCount()                     #设置可以存储的最大项数
QComboBox.maxCount() #获取可以存储的最大项数
QComboBox.setMaxVisibleItems() #设置展示的最大项数
QComboBox.maxVisibleItems() #获取展示的最大项数

存储个数达到上限了是不会有新的顶进来的,条目是不会变化的。而展示个数是限制了展示的个数,超出后会有个滚动条展示出来,可以用滚动条切换显示的内容

图中的最大展示数量就是6,而项目数应该有10个。

    J.常规操作

QComboBox.setDuplicatesEnabled(self, enable: bool)    #设置可重复性
QComboBox.duplicatesEnabled() #是否可以被重复
QComboBox.setFrame(self, a0: bool) #设置框架边框
QComboBox.hasFrame() #是否有框架边框
QComboBox.setIconSize(self, size: QtCore.QSize) #设置图标尺寸
QComboBox.iconSize() #获取图标尺寸

    K.调整尺寸策略

QComboBox.setSizeAdjustPolicy(self, policy: 'QComboBox.SizeAdjustPolicy')
type: 'QComboBox.SizeAdjustPolicy'
AdjustToContents #始终根据内容调整
AdjustToContentsOnFirstShow #固定在提一次提示时的大小
AdjustToMinimumContentsLength #最小宽度
AdjustToMinimumContentsLengthWithIcon #包含图标的最小宽度

    L.清除内容和弹出列表

QComboBox.clear()                           #清空空间里的所有项目
QComboBox.clearEditText() #清除当前显示内容
QComboBox.showPopup() #弹出项目列表

    M.完成器和验证器

     完成器的用法和QLineEdit的方法差不多,但是一般都是结合了下拉列表框里的文本内容生成一个可迭代对象给setCompleter()。验证器的用法也和前面讲的验证器差不多。包含了验证规则和修正方法。

QComboBox.setCompleter(self, c: 'QCompleter')           #完成器具
QComboBox.setValidator(self, v: QtGui.QValidator) #验证器

三.信号

1.条目改变

QComboBox.activated(self, index: int)           #参数为int
QComboBox.activated(self, a0: str) #重载后的用法,参数为str

条目改变的信号必须是用户选中的,用代码操作时是不发送信号的。

2.当前条目改变

QComboBox.currentIndexChanged(self, index: int)           #参数为int
QComboBox.currentIndexChanged(self, a0: str) #重载后的用法,参数为str
QComboBox.currentTextChanged(self, a0: str) #当前文本发生变化
QComboBox.editTextChanged(self, a0: str) #当前编辑文本变化

当前条目改变是有些情况下可以通过代码调用信号的。而当前文本发生变化,是只要显示的字符串发生变化就发送信号(被编辑时只要有变化就每变化一次发送一次),而索引变化时被编辑只要不确认就不会发送信号。当前文本发生变化和编辑文本发生变化的效果基本一致。

3.高亮发生变化

QComboBox.highlighted(self, index: int)               #高亮发生变化,参数为int
QComboBox.highlighted(self, a0: str) #高亮发生变化的重构,参数为str

高亮发生变化是只只要鼠标指向的条目发生变化就发送信号。

四.案例

如图,有这些要求

1.下拉控件1是省份,2是城市,还有一个显示控件显示城市对应的区号

2.城市随着省份的变化会变化

3.省份、城市和区号始终显示,不能改完城市才显示。

from PyQt5.Qt import *
import sys class Window(QWidget):
def __init__(self):
super().__init__()
self.UI_test() def UI_test(self):
province = QComboBox(self)
province.resize(150,30)
province.move(200,200)
self.province = province
city = QComboBox(self)
city.resize(150,30)
city.move(400,200)
le = QLineEdit(self)
le.resize(150,30)
le.move(200,250)
self.le = le
self.city = city
self.city_dic = {'河南':{'郑州':'',
'安阳':'',
'洛阳':''},
'陕西':{'西安':'',
'宝鸡':'',
'渭南':''},
'河北':{'石家庄':'',
'保定':'',
'邯郸':''}}
province.addItems(self.city_dic.keys()) province.currentIndexChanged[str].connect(self.change_pro)
self.change_pro(province.currentText())
city.currentIndexChanged[str].connect(self.change_city)
self.change_city(city.currentText())
pass
def change_pro(self,pro):
self.city.clear()
citys = self.city_dic[pro]
for k,val in citys.items():
self.city.addItem(k,val) #把区号作为userdata保存给控件 def change_city(self,cit):
if len(self.city.currentText()) == 0: #在清除城市列表时会打印空行
pass
else:
self.le.setText(self.city.currentData())
if __name__ == '__main__':
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())

QComboBox案例

注意的几点:

1.因为数据字典是两级的,如果获得区号需要遍历字典才可以,效率太低。可以把第二级字典作为userdata传给控件2

2.要求3里不能用代码调用信号,在程序里直接用代码调用了一遍函数作为初始化。

3.每次改省份时需要把city的内容clear一遍,但是city的内容在clear的时候会调用其对应的函数,每次都会多打印一个空白行,这里做了个if的判断

针对上面的其实还有可以优化的地方

1.对第2条来说,其实初始化时候用的currentIndexChanged()应该是可以调用信号的但为什么不行呢?因为在初始化的时候我们把给控件传递item的时候放在了连接信号槽的前面了,其实放在后面就不用特别手动调用函数了。

2.对第3条,在clear的时候直接断开槽,在clear以后重新连接槽就可以了。

from PyQt5.Qt import *
import sys class Window(QWidget):
def __init__(self):
super().__init__()
self.UI_test() def UI_test(self):
province = QComboBox(self)
province.resize(150,30)
province.move(200,200)
self.province = province
city = QComboBox(self)
city.resize(150,30)
city.move(400,200)
le = QLineEdit(self)
le.resize(150,30)
le.move(200,250)
self.le = le
self.city = city
self.city_dic = {'河南':{'郑州':'',
'安阳':'',
'洛阳':''},
'陕西':{'西安':'',
'宝鸡':'',
'渭南':''},
'河北':{'石家庄':'',
'保定':'',
'邯郸':''}} province.currentIndexChanged[str].connect(self.change_pro)
city.currentIndexChanged[str].connect(self.change_city)
province.addItems(self.city_dic.keys()) pass
def change_pro(self,pro):
self.city.blockSignals(True)
self.city.clear()
self.city.blockSignals(False)
self.city.currentIndexChanged[str].connect(self.change_city)
citys = self.city_dic[pro]
for k,val in citys.items():
self.city.addItem(k,val) #把区号作为userdata保存给控件 def change_city(self,cit):
self.le.setText(self.city.currentData())
if __name__ == '__main__':
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())

QComboBox案例优化版

GUI学习之二十三——QComboBox学习总结的更多相关文章

  1. python3.4学习笔记(二十三) Python调用淘宝IP库获取IP归属地返回省市运营商实例代码

    python3.4学习笔记(二十三) Python调用淘宝IP库获取IP归属地返回省市运营商实例代码 淘宝IP地址库 http://ip.taobao.com/目前提供的服务包括:1. 根据用户提供的 ...

  2. 学习笔记:CentOS7学习之二十三: 跳出循环-shift参数左移-函数的使用

    目录 学习笔记:CentOS7学习之二十三: 跳出循环-shift参数左移-函数的使用 23.1 跳出循环 23.1.1 break和continue 23.2 Shift参数左移指令 23.3 函数 ...

  3. (C/C++学习笔记) 二十三. 运行时类型识别

    二十三. 运行时类型识别 ● 定义 运行时类型识别(Run-time Type Identification, RTTI) 通过RTTI, 程序能够使用基类的指针或引用来检查(check)这些指针或引 ...

  4. Python学习(二)——深度学习入门介绍

    课程二:深度学习入门 讲师:David (数据分析工程师) 这门课主要介绍了很多神经网络的基本原理,非常非常基础的了解. 零.思维导图预览:                一.深度神经网络 1.神经元 ...

  5. web前端学习(二)html学习笔记部分(1) -- html5新增的元素及特性等等

    检查,在浏览器中可以调整设备类型 html5实现水池效果. lang:en为英文语言,中文语言zh <html lang="en"> <head> < ...

  6. GUI学习之二十——QAbstractSlider学习总结

    今天学习一种全新的输入控件——QAbstractSlider()滑块控件的基础控件. 一.描述: QAbstractSlider()是QWidget()的子类,提供了一个范围内的整数值.它是QSlid ...

  7. 智能车学习(二十三)——浅谈心得体会

          因为毕竟是竞赛,跟学校挂钩,没办法开源代码和算法完成思路,所以不能详细写太多,如果可以等价交换的话,应该还是可以向领导申请一下的.       在厦大信科通信系,参加这个比赛,大家都觉得性 ...

  8. java web学习总结(二十三) -------------------编写自己的JDBC框架

    一.元数据介绍 元数据指的是"数据库"."表"."列"的定义信息. 1.1.DataBaseMetaData元数据 Connection.g ...

  9. javaweb学习总结(二十三)——jsp自定义标签开发入门

    一.自定义标签的作用 自定义标签主要用于移除Jsp页面中的java代码. 二.自定义标签开发和使用 2.1.自定义标签开发步骤 1.编写一个实现Tag接口的Java类(标签处理器类) 1 packag ...

随机推荐

  1. php 的路由简介 (一个简单的路由模式)

    <?php $_SERVER['REQUEST_URI'] = '/post/edit/1024?foo=bar'; $uri = explode('/', parse_url($_SERVER ...

  2. 【2】通过Ajax方式上传文件(图片),使用FormData进行Ajax请求

    HTML: <form id= "uploadForm"> <p >指定文件名: <input type="text" name= ...

  3. Octavia 创建 Listener、Pool、Member、L7policy、L7 rule 与 Health Manager 的实现与分析

    目录 文章目录 目录 创建 Listener 创建 Pool 创建 Member CalculateDelta HandleNetworkDeltas AmphoraePostNetworkPlug ...

  4. 分布式消息队列 Celery 的最佳实践

    目录 目录 不使用数据库作为 Broker 不要过分关注任务结果 实现优先级任务 应用 Worker 并发池的动态扩展 应用任务预取数 保持任务的幂等性 应用任务超时限制 善用任务工作流 合理应用 a ...

  5. 阶段3 1.Mybatis_05.使用Mybatis完成CRUD_2 Mybatis的CRUD-保存操作

    增加的方法 修改映射配置 id是方法名 按照原来jdbc的写法 values里面应该是一堆问号,现在这里不能再去写问号了因为要取值 从我们要执行的方法传的参数里面去取值 所以参数的类型我们必须要告诉这 ...

  6. 阶段3 1.Mybatis_03.自定义Mybatis框架_6.自定义Mybatis的编码-实现基于XML的查询所有操作

    接下来就可以写创建代理对象的方法了 类加载器,代理谁,就用谁的加载器,因为这里用daoInterfaceClass.getClassLoader() 第二个代理谁就要和谁有相同的接口,daoInter ...

  7. Unity3D 协程 Coroutine

    协程(Coroutine)的概念存在于很多编程语言,例如Lua.ruby等.而由于Unity3D是单线程的,因此它同样实现了协程机制来实现一些类似于多线程的功能,但是要明确一点协程不是进程或线程,其执 ...

  8. IntlliJ IDEA 注册码获取或离线破解

    JB 的软件还是挺好用的,建议有钱的话支持正版.. IntelliJ IDEA 有开源版,但是要想玩企业级开发,还是得用收费版. 不管哪种方式,使用前都需要把"0.0.0.0 account ...

  9. linux使用ltrace和strace跟踪程序执行过程

    yum install strace yum install ltrace 1.strace  ping -c 1 www.baidu.com 2.ltrace  ping -c 1 www.baid ...

  10. cocos2dx基础篇(9) 滑块控件CCControlSlider

    [3.x] (1)去掉 “CC” (2)对象类 CCObject 改为 Ref (3)CCControlEvent 改为强枚举 Control::EventType (4)CCControlEvent ...