自定义实现 PyQt5 下拉复选框 ComboCheckBox
程序员文章站
2022-03-25 16:57:26
一、前言 由于最近的项目需要具有复选功能,但过多的复选框会影响界面布局和美观,因而想到把 PyQt5 的下拉列表和复选框结合起来,但在 PyQt5 中并没有这样的组件供我们使用,所以想要自己实现一个下拉复选框,主要就是继承 QComboBox 类,然后将复选框 QCheckBox 加入其中,并实现相 ......
一、前言
由于最近的项目需要具有复选功能,但过多的复选框会影响界面布局和美观,因而想到把 pyqt5 的下拉列表和复选框结合起来,但在 pyqt5 中并没有这样的组件供我们使用,所以想要自己实现一个下拉复选框,主要就是继承 qcombobox 类,然后将复选框 qcheckbox 加入其中,并实现相应的功能。
最终实现的下拉复选框效果如下:
二、代码实现
1.主要方法
在 pyqt5 中,有几个主要的方法需要了解一下,方法名称和对应的含义如下:
-
qtwidgets.qcombobox.setview(itemview):设置组合框弹出窗口中使用的视图
,
组合框获取视图的所有权。 - qtwidgets.qcombobox.setlineedit(qlineedit):设置组合框使用的行,而不是当前行编辑窗口小部件。
- qtwidgets.qlistwidget.setitemwidget(item, widget):设置
要在给定的 item 中的 widget 组件。
2.具体代码
实现下拉复选框的思路为用 setview() 方法将 qcombobox 下拉列表的视图改为 qlistwidget 组件,然后将 qcheckbox 复选框用在 qlistwiget 中,具体代码如下:
1 class combocheckbox(qcombobox): 2 def __init__(self, items: list): 3 """ 4 initial function 5 :param items: the items of the list 6 """ 7 super(combocheckbox, self).__init__() 8 self.items = items # items list 9 self.box_list = [] # selected items 10 self.text = qlineedit() # use to selected items 11 self.text.setreadonly(true) 12 13 q = qlistwidget() 14 for i in range(len(self.items)): 15 self.box_list.append(qcheckbox()) 16 self.box_list[i].settext(self.items[i]) 17 item = qlistwidgetitem(q) 18 q.setitemwidget(item, self.box_list[i]) 19 self.box_list[i].statechanged.connect(self.show_selected) 20 21 self.setlineedit(self.text) 22 self.setmodel(q.model()) 23 self.setview(q) 24 25 def get_selected(self) -> list: 26 """ 27 get selected items 28 :return: 29 """ 30 ret = [] 31 for i in range(len(self.items)): 32 if self.box_list[i].ischecked(): 33 ret.append(self.box_list[i].text()) 34 return ret 35 36 def show_selected(self): 37 """ 38 show selected items 39 :return: 40 """ 41 self.text.clear() 42 ret = '; '.join(self.get_selected()) 43 self.text.settext(ret)
其中 show_selected() 用于显示被选中的内容,get_selected() 则用于获取所有被选中的内容并返回。
3.增加全选
要增加全选功能,首先是要在最前面加一个全选的选择框,然后为这个全选的选择框绑定相应的方法,用于实现全选功能和取消全选功能,具体代码如下:
1 def all_selected(self): 2 """ 3 decide whether to check all 4 :return: 5 """ 6 # change state 7 if self.state == 0: 8 self.state = 1 9 for i in range(1, len(self.items)): 10 self.box_list[i].setchecked(true) 11 else: 12 self.state = 0 13 for i in range(1, len(self.items)): 14 self.box_list[i].setchecked(false) 15 self.show_selected()
4.修改样式
由于默认的样式并不美观,所以我们可以对控件的样式进行自定义,例如字体大小、字体粗细等等,例如:
q.setstylesheet("font-size: 20px; font-weight: bold; height: 40px; margin-left: 5px")
self.setstylesheet("width: 300px; height: 50px; font-size: 21px; font-weight: bold")
三、完整程序
完善后的下拉复选框的运行程序代码如下:
1 from pyqt5.qtwidgets import qcombobox, qlineedit, qlistwidgetitem, qlistwidget, qcheckbox, \ 2 qapplication, qvboxlayout, qwidget 3 import sys 4 5 6 class combocheckbox(qcombobox): 7 def __init__(self, items: list): 8 """ 9 initial function 10 :param items: the items of the list 11 """ 12 super(combocheckbox, self).__init__() 13 self.items = ["全选"] + items # items list 14 self.box_list = [] # selected items 15 self.text = qlineedit() # use to selected items 16 self.state = 0 # use to record state 17 18 q = qlistwidget() 19 for i in range(len(self.items)): 20 self.box_list.append(qcheckbox()) 21 self.box_list[i].settext(self.items[i]) 22 item = qlistwidgetitem(q) 23 q.setitemwidget(item, self.box_list[i]) 24 if i == 0: 25 self.box_list[i].statechanged.connect(self.all_selected) 26 else: 27 self.box_list[i].statechanged.connect(self.show_selected) 28 29 q.setstylesheet("font-size: 20px; font-weight: bold; height: 40px; margin-left: 5px") 30 self.setstylesheet("width: 300px; height: 50px; font-size: 21px; font-weight: bold") 31 self.text.setreadonly(true) 32 self.setlineedit(self.text) 33 self.setmodel(q.model()) 34 self.setview(q) 35 36 def all_selected(self): 37 """ 38 decide whether to check all 39 :return: 40 """ 41 # change state 42 if self.state == 0: 43 self.state = 1 44 for i in range(1, len(self.items)): 45 self.box_list[i].setchecked(true) 46 else: 47 self.state = 0 48 for i in range(1, len(self.items)): 49 self.box_list[i].setchecked(false) 50 self.show_selected() 51 52 def get_selected(self) -> list: 53 """ 54 get selected items 55 :return: 56 """ 57 ret = [] 58 for i in range(1, len(self.items)): 59 if self.box_list[i].ischecked(): 60 ret.append(self.box_list[i].text()) 61 return ret 62 63 def show_selected(self): 64 """ 65 show selected items 66 :return: 67 """ 68 self.text.clear() 69 ret = '; '.join(self.get_selected()) 70 self.text.settext(ret) 71 72 73 class uimainwindow(qwidget): 74 def __init__(self): 75 super(uimainwindow, self).__init__() 76 self.setwindowtitle('test') 77 self.resize(600, 400) 78 combo = combocheckbox(["python", "java", "go", "c++", "javascript", "php"]) 79 layout = qvboxlayout() 80 layout.addwidget(combo) 81 self.setlayout(layout) 82 83 84 if __name__ == "__main__": 85 app = qapplication(sys.argv) 86 ui = uimainwindow() 87 ui.show() 88 sys.exit(app.exec_())
推荐阅读
-
js+csss实现的一个带复选框的下拉框_javascript技巧
-
在React中使用Native如何实现自定义下拉刷新上拉加载的列表
-
android使用Ultra-PullToRefresh实现下拉刷新自定义代码
-
android使用Ultra-PullToRefresh实现下拉刷新自定义代码
-
Android-自定义控件之ListView下拉刷新的实现
-
Android开发使用自定义view实现ListView下拉的视差特效功能
-
Android自定义实现顶部粘性下拉刷新效果
-
Android自定义控件实现下拉刷新效果
-
Android开发使用自定义view实现ListView下拉的视差特效功能
-
Android自定义实现顶部粘性下拉刷新效果