zoukankan      html  css  js  c++  java
  • 自定义实现 PyQt5 下拉复选框 ComboCheckBox

    一、前言

      由于最近的项目需要具有复选功能,但过多的复选框会影响界面布局和美观,因而想到把 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(" 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(" 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_())
  • 相关阅读:
    四则运算3
    结对编程
    2016年秋季-软件需求分析-UML图
    2016年秋季-学习进度条
    2016年秋季-学习进度条
    2016年秋季-《UML大战需求分析》-阅读笔记1
    2016年秋季-课堂练习1-Liz开发问题账户分析系统
    2016年秋季-《UML大战需求分析》-个人阅读计划
    2016年秋季-软件需求与分析-基本知识
    用户体验
  • 原文地址:https://www.cnblogs.com/TM0831/p/12588841.html
Copyright © 2011-2022 走看看