欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

自定义实现 PyQt5 下拉复选框 ComboCheckBox

程序员文章站 2022-03-25 16:57:26
一、前言 由于最近的项目需要具有复选功能,但过多的复选框会影响界面布局和美观,因而想到把 PyQt5 的下拉列表和复选框结合起来,但在 PyQt5 中并没有这样的组件供我们使用,所以想要自己实现一个下拉复选框,主要就是继承 QComboBox 类,然后将复选框 QCheckBox 加入其中,并实现相 ......

一、前言

  由于最近的项目需要具有复选功能,但过多的复选框会影响界面布局和美观,因而想到把 pyqt5 的下拉列表和复选框结合起来,但在 pyqt5 中并没有这样的组件供我们使用,所以想要自己实现一个下拉复选框,主要就是继承 qcombobox 类,然后将复选框 qcheckbox 加入其中,并实现相应的功能。

  最终实现的下拉复选框效果如下:

  自定义实现 PyQt5 下拉复选框 ComboCheckBox

 

二、代码实现

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_())