当前位置:   article > 正文

PyQt6 基础操作:下拉列表框 QComboBox (Part1)_pyqt的下拉选择框

pyqt的下拉选择框

1. 官方文档

https://www.riverbankcomputing.com/static/Docs/PyQt6/api/qtwidgets/qcombobox.html

2. 概述

枚举值

使用示例

描述

InsertPolicy

参考代码部分

<about_InsetPolicy>

可编辑模式下使用;

设置用户在可编辑的文本框中,输入一个新的字符串后,新字符插入的策略;

如InsertAtBottom、InsertBeforeCurrent、InsertAlphabetically等。

SizeAdjustPolicy

参考代码部分

<about_SizeAdjustPolicy>

指定窗口部件的大小调整策略;

AdjustToContents:

自动调整大小以适应内容;

AdjustToContentsOnFirstShow:

第一次显示时自动调整大小以适应内容;

AdjustToMinimumContentsLength

WithIcon:将控件宽度调整为minimumContentLength()值加一个图标的大小。出于性能原因,请在大型模型上使用此策略。

方法

使用示例

描述

addItem(Optional[str], userData: Any = None)

<about_add_insert>

添加一个选项

addItem(QIcon, Optional[str], userData: Any = None)

<about_add_insert>

添加一个带图标的选项

addItems(Iterable[Optional[str]])

<about_add_insert>

添加一个或多个选项

insertItem(int, Optional[str], userData: Any = None)

<about_add_insert>

插入一个选项

insertItem(int, QIcon, Optional[str], userData: Any = None)

<about_add_insert>

插入一个带图标的选项

insertItems(int, Iterable[Optional[str]])

<about_add_insert>

插入一个或多个选项

insertSeparator(int)

<about_add_insert>

如果插入了分隔线,分割线会占用一个index

setItemText(int, Optional[str]))

<about_item_current_1>

设置指定索引对应选项的内容

setItemData(int, Any, role: int = UserRole)

<about_add_insert>

<about_item_current_1>

设置指定索引对应选项的数据

setItemIcon(int, QIcon)

<about_item_current_1>

<about_item_current_2>

设置指定索引对应选项的图片

itemText(int) → str

<about_item_current_2>

获取指定索引对应选项的内容

itemData(int, role: int = UserRole) → Any

<about_add_insert>

<about_item_current_2>

获取指定索引对应选项的数据

itemIcon(int) → QIcon

<about_item_current_2>

获取指定索引对应选项的图片

clear()

<about_editable>

删除所有选项

clearEditText()

<about_editable>

可编辑模式或通过setLineEdit

添加了文本框时,可使用此命令清空文本框内容;不存在文本框时无操作

currentIndex() → int

<about_item_current_1>

获取当前选择的选项索引

currentText() → str

<about_item_current_1>

获取当前选择的选项内容

currentData(role: int = UserRole) → Any

<about_item_current_1>

获取当前选择的选项数据

setCurrentIndex(int)

<about_item_current_2>

设置当前选项的索引

setCurrentText(Optional[str])

<about_item_current_2>

设置当前选项的内容

setIconSize(QSize)

<about_add_insert>

设置选项中图尺寸

iconSize() → QSize

<about_add_insert>

获取图尺寸

count() → int

<about_count>

返回下拉选项总数

setMaxCount(int)

<about_count>

超过的选项将不被显示

maxCount() → int

<about_count>

最多选项数

setMaxVisibleItems(int)

<about_count>

超过的选项将在下一页显示,需要拖动滑块

maxVisibleItems() → int

<about_count>

一页最大项目数

setEditable(bool)

<about_editable>

设置可编辑模式

isEditable() → bool

<about_editable>

是否可编辑

setDuplicatesEnabled(bool)

<about_editable>

设置是否允许重复添加,默认为False;仅针对可编辑模式下,用户通过文本框输入的内容,下拉框中已存在时,是否重复添加。

duplicatesEnabled() → bool

<about_editable>

否允许重复添加

setFrame(bool)

<about_editable>

设置文本框是否有外框

针对可编辑模式

hasFrame() → bool

<about_editable>

文本框是否有外框

setLineEdit(QLineEdit)

<about_editable>

设置文本框

lineEdit() → QLineEdit

<about_editable>

非可编辑模式下默认为None;在可编辑模式下,或已经通过setLineEdit添加过文本框时,为QLineEdit对象

setEditText(Optional[str])

<about_editable>

设置文本框中的内容

setInsertPolicy(insertPolicy)

<about_InsetPolicy>

参考InsertPolicy

insertPolicy() → insertPolicy

<about_InsetPolicy>

参考InsertPolicy

setSizeAdjustPolicy(

SizeAdjustPolic)

<about_SizeAdjustPolicy>

参考SizeAdjustPolicy

sizeAdjustPolicy() → 

sizeAdjustPolicy

<about_SizeAdjustPolicy>

参考SizeAdjustPolicy

3. 完整代码

  1. from PyQt6.QtCore import QSize
  2. from PyQt6.QtGui import QIcon
  3. from PyQt6.QtWidgets import QApplication, QMainWindow, QPushButton, QComboBox, QLineEdit, QCompleter, QLabel
  4. import sys
  5. class Ui_Study(QMainWindow):
  6. def __init__(self):
  7. super().__init__()
  8. self.resize(500, 500)
  9. self.setMinimumSize(500, 500)
  10. # 增加3个下拉选项框、3个按钮、3个label、3个文本框,便于验证各个功能点
  11. self.combobox0 = QComboBox(self)
  12. self.combobox1 = QComboBox(self)
  13. self.combobox2 = QComboBox(self)
  14. self.pushbutton0 = QPushButton(self)
  15. self.pushbutton1 = QPushButton(self)
  16. self.pushbutton2 = QPushButton(self)
  17. self.label0 = QLabel(self)
  18. self.label1 = QLabel(self)
  19. self.label2 = QLabel(self)
  20. self.lineedit0 = QLineEdit(self)
  21. self.lineedit1 = QLineEdit(self)
  22. self.lineedit2 = QLineEdit(self)
  23. self.initial_add()
  24. self.name_list = ['Oliver', 'Emma', 'Noah', 'Ava', 'William',
  25. 'Sophia', 'James', 'Isabella', 'Benjamin', 'Mia',
  26. 'Lucas', 'Charlotte', 'Henry', 'Amelia', 'Alexander',
  27. 'Harper', 'Michael', 'Evelyn', 'Ethan', 'Abigail']
  28. self.name_count = 0
  29. func_name = 'about_editable'
  30. # 'about_InsetPolicy', 'about_SizeAdjustPolicy', 'about_editable', 'about_add_insert',
  31. # 'about_item_current_1', 'about_item_current_2', 'about_count'
  32. getattr(self, func_name)()
  33. self.show()
  34. def initial_add(self):
  35. self.combobox0.move(20, 20)
  36. self.combobox1.move(20, 60)
  37. self.combobox2.move(20, 100)
  38. self.pushbutton0.move(20, 140)
  39. self.pushbutton0.resize(200, 30)
  40. self.pushbutton1.move(20, 180)
  41. self.pushbutton1.resize(200, 30)
  42. self.pushbutton2.move(20, 220)
  43. self.pushbutton2.resize(200, 30)
  44. self.label0.move(20, 260)
  45. self.label0.resize(200, 30)
  46. self.label1.move(20, 300)
  47. self.label1.resize(200, 30)
  48. self.label2.move(20, 340)
  49. self.label2.resize(200, 30)
  50. self.lineedit0.move(230, 260)
  51. self.lineedit0.resize(200, 30)
  52. self.lineedit1.move(230, 300)
  53. self.lineedit1.resize(200, 30)
  54. self.lineedit2.move(230, 340)
  55. self.lineedit2.resize(200, 30)
  56. def about_InsetPolicy(self):
  57. self.combobox0.resize(200, 30)
  58. self.combobox1.resize(200, 30)
  59. self.combobox0.setInsertPolicy(QComboBox.InsertPolicy.InsertAtCurrent)
  60. self.combobox1.addItems(["InsertAfterCurrent", "InsertAlphabetically", "InsertAtBottom", "InsertAtCurrent",
  61. "InsertAtTop", "InsertBeforeCurrent", "NoInsert"])
  62. self.combobox1.currentTextChanged.connect(
  63. lambda text: self.combobox0.setInsertPolicy(getattr(QComboBox.InsertPolicy, text)))
  64. self.combobox0.setEditable(True)
  65. self.combobox0.addItems(["A", "B", "C", "D"])
  66. self.pushbutton0.setText("AddItem(固定添加在列表最后)")
  67. def addName():
  68. self.combobox1.setInsertPolicy(getattr(QComboBox.InsertPolicy, self.combobox1.currentText()))
  69. self.combobox0.addItem(f'{self.name_list[self.name_count]}')
  70. self.name_count += 1
  71. self.pushbutton0.clicked.connect(addName)
  72. def about_SizeAdjustPolicy(self):
  73. self.combobox0.addItems(self.name_list + ['Lucas Candy MILLER Mary'])
  74. self.combobox0.setEditable(True) # 可以注释掉对比看看
  75. print(self.combobox0.minimumContentsLength())
  76. print(self.combobox0.sizeAdjustPolicy())
  77. print(self.combobox1.width())
  78. print('\n')
  79. # 如果用resize设置了控件尺寸,SizeAdjustPolicy不起作用,可以设置self.combobox0.resize(200, 30)对比看一看
  80. # self.combobox1.addItems(self.name_list + ['Lucas Candy MILLER Mary'])
  81. self.combobox1.setMinimumContentsLength(30) # 可以设置为0、20、30对比看一看
  82. self.combobox1.setEditable(True) # 可以注释掉对比看看
  83. self.combobox1.lineEdit().setReadOnly(True) # 可以注释掉对比看看
  84. self.combobox1.setSizeAdjustPolicy(QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLengthWithIcon)
  85. print(self.combobox1.minimumContentsLength())
  86. print(self.combobox1.sizeAdjustPolicy())
  87. print(self.combobox1.width())
  88. self.combobox2.setSizeAdjustPolicy(QComboBox.SizeAdjustPolicy.AdjustToContents)
  89. self.combobox2.addItems(self.name_list + ['Lucas Candy MILLER Mary'])
  90. print(self.combobox2.minimumContentsLength())
  91. print(self.combobox2.sizeAdjustPolicy())
  92. def addName():
  93. self.combobox0.addItem('Charles André Joseph Pierre Marie de Gaulle')
  94. self.combobox1.addItem('Charles André Joseph Pierre Marie de Gaulle')
  95. self.combobox2.addItem('Charles André Joseph Pierre Marie de Gaulle')
  96. self.pushbutton0.setText("添加一个长内容")
  97. self.pushbutton0.clicked.connect(addName)
  98. def about_editable(self):
  99. self.combobox0.resize(200, 30)
  100. self.combobox1.resize(200, 30)
  101. self.combobox2.resize(200, 30)
  102. # combobox0
  103. self.combobox0.setEditable(True)
  104. self.combobox0.addItems(self.name_list[:5])
  105. self.label0.setText('combobox0是否可编辑: ')
  106. self.lineedit0.setText(str(self.combobox0.isEditable()))
  107. print(f'可编辑模式下的lineEdit: {self.combobox0.lineEdit()}')
  108. # combobox1
  109. # 关于lineEdit()
  110. self.combobox1.addItems(self.name_list[:5])
  111. self.label1.setText('combobox1是否可编辑: ')
  112. self.lineedit1.setText(str(self.combobox1.isEditable()))
  113. print(f'不可编辑模式下的lineEdit: {self.combobox1.lineEdit()}') # 非可编辑模式下,不存在linedit,返回None
  114. self.combobox1.setLineEdit(QLineEdit(self.combobox1)) # 可以通过setLineEdit添加一个linedit
  115. print(f'不可编辑模式+通过setlineEdit设置后: {self.combobox1.lineEdit()}')
  116. self.combobox1.currentIndexChanged.connect(
  117. lambda: self.combobox1.lineEdit().setText(str(self.combobox1.currentIndex()))
  118. ) # 可以设置lineEdit()的内容
  119. self.combobox1.lineEdit().setReadOnly(True) # 加一个readonly,用户不能编辑其内容
  120. # combobox2
  121. # duplicate\frame
  122. self.combobox2.addItems((self.name_list[:5]))
  123. self.combobox2.clearEditText()
  124. self.combobox2.setEditable(True)
  125. print(f'默认值-是否有框架:{self.combobox2.hasFrame()}')
  126. print(f'默认值-是否可重复:{self.combobox2.duplicatesEnabled()}')
  127. self.combobox2.setFrame(False)
  128. # 在文本框内输入内容,看一看无frame、不可重复的效果
  129. self.combobox2.addItems(self.name_list[:5]) # 对addItem无效
  130. self.combobox2.setEditText('This is a sentence')
  131. # pushbutton0-clear()
  132. self.pushbutton0.setText('combobox1执行clear()')
  133. def combobox1_clear():
  134. self.combobox1.clear()
  135. self.pushbutton0.clicked.connect(combobox1_clear)
  136. self.pushbutton1.setText('combobox1添加内容')
  137. # pushbutton0-addItems()
  138. def combobox1_add():
  139. self.combobox1.addItems(self.name_list[:5])
  140. self.pushbutton1.clicked.connect(combobox1_add)
  141. # pushbutton2-clearEditText()
  142. self.pushbutton2.setText('combobox0和1执行clearEditText()')
  143. def combobox0_clearEditText():
  144. self.combobox0.clearEditText()
  145. self.combobox1.clearEditText()
  146. self.pushbutton2.clicked.connect(combobox0_clearEditText)
  147. def about_add_insert(self):
  148. self.combobox0.resize(200, 30)
  149. self.combobox1.resize(200, 30)
  150. # Combobox1
  151. print(self.combobox1.iconSize())
  152. self.combobox1.setIconSize(QSize(40, 40))
  153. self.combobox1.addItem(QIcon('Flower.PNG'), 'add-0')
  154. # Combobox0
  155. self.combobox0.addItem('add-1', 'dataA of add-1') # addItem
  156. self.combobox0.setItemData(0, 'dataB of add-1', 3) # setItemData
  157. self.combobox0.setItemData(0, QIcon('C.PNG'), 1)
  158. self.label0.setText('data-role')
  159. self.lineedit0.setText(self.combobox0.itemData(0)) # UserRole # itemData
  160. self.label1.setText('data-role=3 ')
  161. self.lineedit1.setText(self.combobox0.itemData(0, 3))
  162. self.label2.setText('data-role=2')
  163. self.lineedit2.setText(self.combobox0.itemData(0, 2))
  164. self.combobox0.setItemData(0, 'add-1-new', 2)
  165. self.combobox0.addItem(QIcon('C.PNG'), 'add-2') # addItem
  166. self.combobox0.addItems(self.name_list[:3]) # addItems
  167. self.pushbutton0.setText("No1: 0-插入带图at0;2-插入at2")
  168. self.pushbutton1.setText("No1: 2-插入分割线;4-插入at4")
  169. def combobox0_insert0():
  170. self.combobox0.insertItem(0, QIcon('C.PNG'), 'at0') # insertItem
  171. self.combobox0.insertItem(2, 'at2') # insetItem
  172. def combobox0_insert1():
  173. self.combobox0.insertSeparator(2)
  174. self.combobox0.insertItems(4, ['at4-1', 'at4-2', 'at4-3']) # insertItems
  175. self.pushbutton0.clicked.connect(combobox0_insert0)
  176. self.pushbutton1.clicked.connect(combobox0_insert1)
  177. pass
  178. def about_item_current_1(self):
  179. self.combobox0.resize(200, 30)
  180. self.combobox0.addItems(self.name_list[:5])
  181. self.pushbutton0.setText('修改选项1的内容、数据、图片')
  182. def setItem1():
  183. self.combobox0.setItemText(1, 'A')
  184. self.combobox0.setItemData(1, 'LALALALA')
  185. self.combobox0.setItemIcon(1, QIcon('Flower.PNG'))
  186. self.pushbutton0.clicked.connect(setItem1)
  187. self.label0.setText('当前选项Index')
  188. self.label1.setText('当前选项内容')
  189. self.label2.setText('当前选项数据')
  190. self.combobox0.currentIndexChanged.connect(
  191. lambda: self.lineedit0.setText(str(self.combobox0.currentIndex()))
  192. )
  193. self.combobox0.currentIndexChanged.connect(
  194. lambda: self.lineedit1.setText(str(self.combobox0.currentText()))
  195. )
  196. self.combobox0.currentIndexChanged.connect(
  197. lambda: self.lineedit2.setText(str(self.combobox0.currentData()))
  198. )
  199. pass
  200. def about_item_current_2(self):
  201. self.combobox0.resize(200, 30)
  202. self.combobox0.addItems(self.name_list[:5])
  203. self.combobox0.insertItem(1, QIcon('Flower.PNG'), 'A', 'LALALALA')
  204. self.pushbutton0.setText('给选项3添加选项1的图片')
  205. self.pushbutton0.clicked.connect(lambda: self.combobox0.setItemIcon(3, self.combobox0.itemIcon(1)))
  206. self.pushbutton1.setText('将当前选项设置为选项1(基于索引)')
  207. self.pushbutton1.clicked.connect(lambda: self.combobox0.setCurrentIndex(1))
  208. self.pushbutton2.setText('将当前选项设置为A(选项1的内容)')
  209. self.pushbutton2.clicked.connect(lambda: self.combobox0.setCurrentText('A'))
  210. self.label0.setText('第1个选项的内容')
  211. self.label1.setText('第1个选项的数据')
  212. self.combobox0.currentIndexChanged.connect(
  213. lambda: self.lineedit0.setText(str(self.combobox0.itemText(1)))
  214. )
  215. self.combobox0.currentIndexChanged.connect(
  216. lambda: self.lineedit1.setText(str(self.combobox0.itemData(1)))
  217. )
  218. def about_count(self):
  219. self.combobox0.addItems(self.name_list)
  220. self.pushbutton0.setText('最大项目数设置为10')
  221. self.pushbutton0.clicked.connect(lambda: self.combobox0.setMaxCount(10))
  222. self.pushbutton1.setText('一页最大项目数设置为5')
  223. self.pushbutton1.clicked.connect(lambda: self.combobox0.setMaxVisibleItems(5))
  224. self.pushbutton2.setText('更新配置')
  225. self.label0.setText('当前项目总数')
  226. self.label1.setText('最大项目数')
  227. self.label2.setText('一页最大项目数')
  228. def update_count():
  229. self.lineedit0.setText(str(self.combobox0.count()))
  230. self.lineedit1.setText(str(self.combobox0.maxCount()))
  231. self.lineedit2.setText(str(self.combobox0.maxVisibleItems()))
  232. self.pushbutton2.clicked.connect(update_count)
  233. if __name__ == '__main__':
  234. app = QApplication(sys.argv)
  235. my_ui = Ui_Study()
  236. sys.exit(app.exec())

4. 细节说明

1. InsertPolicy、insertPolicy()、setInsetPolicy()

(1)上述枚举值和方法均仅针对editable combobox,即在文本框输入一定内容后,内容放置在列表的哪个位置,由insetPolicy()对应值决定。

(2)与addItem无关,addItem方法固定将文本添加到最后。

 2. SizeAdjustPolicy、minimumContentsLength()、setMinimumContentsLength()

(1)如果用resize设置了控件尺寸,此功能无效。

(2)Combobox默认值为AdjustToContentsOnFirstShow。

(3)AdjustToContentsOnFirstShow和AdjustToMinimumContentsLengthWithIcon均需要在可编辑模式下使用,才能达到预期效果(如果想使用这两种策略,但又不希望用户真的通过编辑文本框增加项目,可以在设置可编辑模式后,增加一行代码:combobox.lineEdit().setReadOnly(True));另外,对于AdjustToContentsOnFirstShow,一定要确保在展示控件前,就已经添加了内容,AdjustToMinimumContentsLengthWithIcon则无此要求。

(4)SizeAdjustPolicy策略是ComboBox独有的。

效果说明

(1)非可编辑模式,展示控件前已经添加了很多内容,但AdjustToContentsOnFirstShow模式 和AdjustToMinimumContentsLengthWithIcon模式下的宽度都没有达到预期效果:

(2)将前两个控件改为可编辑模式,控件宽度改变,最长的一项也能完整显示,下图中minimumContentsLength()值为0,因而前两个控件宽度相同。

(3)针对第2个控件(AdjustToMinimumContentsLengthWithIcon模式),设置setMinimumContentsLength(30),其宽度明显增加。

(4)控件已经完成展示,又添加了一个很长的内容,AdjustToContents模式能自动调整控件长度,将这个更长的内容完整显示,另外两种模式下,控件宽度保持原状。

3. setDuplicatesEnabled()、duplicatesEnabled()

(1) 仅针对可编辑模式下,用户从文本框输入的内容,对addItem添加的内容无效

(2) 如果想在使用addItem时,自动过滤已经添加过的项目,建议重写addItem方法。

4. addItem()、insertItem()等命令中,itemData及UserRole的含义

(1)UserRole

在combobox的使用中,UserRole可以用于存储每个item的额外信息(如用户信息:性别、年龄),它可以用来存储任何类型的数据,比如字符串、数字、对象等

(2)示例

代码

  1. def about_add_insert(self):
  2. self.combobox0.resize(200, 30)
  3. self.combobox0.addItem('add-1', 'dataA of add-1')
  4. self.combobox0.setItemData(0, 'dataB of add-1', 3)
  5. self.combobox0.setItemData(0, QIcon('C.PNG'), 1)
  6. self.label0.setText('data-role')
  7. self.lineedit0.setText(self.combobox0.itemData(0)) # UserRole
  8. self.label1.setText('data-role=3 ')
  9. self.lineedit1.setText(self.combobox0.itemData(0, 3))
  10. self.label2.setText('data-role=2')
  11. self.lineedit2.setText(self.combobox0.itemData(0, 2))

效果:

(1)用AddItem添加选项时,设置了UserRole对应的数据为‘dataA of add-1‘,因而通过itemData(0)获取的,就是这一条用户信息;

(2)添加选项时没有用QIcon,因为设置DataRole=1(DecorationRole)的数据,出现了图片;

(3)通过设置DataRole=3(ToolTipRole)对应的内容为‘dataB of add 1‘,下方出现了提示框信息;

(4)DataRole=2对应的数据,就是文本框内容,如果通过setItemData修改EditRole(DataRole=2)的内容,这个项目的内容也会随之改变。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/560477
推荐阅读
相关标签
  

闽ICP备14008679号