自定义实现 PyQt5 下拉复选框 ComboCheckBox的完整代码


Posted in Python onMarch 30, 2020

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

一、前言

由于最近的项目需要具有复选功能,但过多的复选框会影响界面布局和美观,因而想到把 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 中,具体代码如下:

class ComboCheckBox(QComboBox):
  def __init__(self, items: list):
    """
    initial function
    :param items: the items of the list
    """
    super(ComboCheckBox, self).__init__()
    self.items = items # items list
    self.box_list = [] # selected items
    self.text = QLineEdit() # use to selected items
    self.text.setReadOnly(True)
    q = QListWidget()
    for i in range(len(self.items)):
      self.box_list.append(QCheckBox())
      self.box_list[i].setText(self.items[i])
      item = QListWidgetItem(q)
      q.setItemWidget(item, self.box_list[i])
      self.box_list[i].stateChanged.connect(self.show_selected)
    self.setLineEdit(self.text)
    self.setModel(q.model())
    self.setView(q)
  def get_selected(self) -> list:
    """
    get selected items
    :return:
    """
    ret = []
    for i in range(len(self.items)):
      if self.box_list[i].isChecked():
        ret.append(self.box_list[i].text())
    return ret
  def show_selected(self):
    """
    show selected items
    :return:
    """
    self.text.clear()
    ret = '; '.join(self.get_selected())
    self.text.setText(ret)

其中 show_selected() 用于显示被选中的内容,get_selected() 则用于获取所有被选中的内容并返回。

3.增加全选

要增加全选功能,首先是要在最前面加一个全选的选择框,然后为这个全选的选择框绑定相应的方法,用于实现全选功能和取消全选功能,具体代码如下:

def all_selected(self):
  """
  decide whether to check all
  :return:
  """
  # change state
  if self.state == 0:
    self.state = 1
    for i in range(1, len(self.items)):
      self.box_list[i].setChecked(True)
  else:
    self.state = 0
    for i in range(1, len(self.items)):
      self.box_list[i].setChecked(False)
  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")

三、完整程序

完善后的下拉复选框的运行程序代码如下:

from PyQt5.QtWidgets import QComboBox, QLineEdit, QListWidgetItem, QListWidget, QCheckBox, \
  QApplication, QVBoxLayout, QWidget
import sys
class ComboCheckBox(QComboBox):
  def __init__(self, items: list):
    """
    initial function
    :param items: the items of the list
    """
    super(ComboCheckBox, self).__init__()
    self.items = ["全选"] + items # items list
    self.box_list = [] # selected items
    self.text = QLineEdit() # use to selected items
    self.state = 0 # use to record state
    q = QListWidget()
    for i in range(len(self.items)):
      self.box_list.append(QCheckBox())
      self.box_list[i].setText(self.items[i])
      item = QListWidgetItem(q)
      q.setItemWidget(item, self.box_list[i])
      if i == 0:
        self.box_list[i].stateChanged.connect(self.all_selected)
      else:
        self.box_list[i].stateChanged.connect(self.show_selected)
    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")
    self.text.setReadOnly(True)
    self.setLineEdit(self.text)
    self.setModel(q.model())
    self.setView(q)
  def all_selected(self):
    """
    decide whether to check all
    :return:
    """
    # change state
    if self.state == 0:
      self.state = 1
      for i in range(1, len(self.items)):
        self.box_list[i].setChecked(True)
    else:
      self.state = 0
      for i in range(1, len(self.items)):
        self.box_list[i].setChecked(False)
    self.show_selected()
  def get_selected(self) -> list:
    """
    get selected items
    :return:
    """
    ret = []
    for i in range(1, len(self.items)):
      if self.box_list[i].isChecked():
        ret.append(self.box_list[i].text())
    return ret
  def show_selected(self):
    """
    show selected items
    :return:
    """
    self.text.clear()
    ret = '; '.join(self.get_selected())
    self.text.setText(ret)
class UiMainWindow(QWidget):
  def __init__(self):
    super(UiMainWindow, self).__init__()
    self.setWindowTitle('Test')
    self.resize(600, 400)
    combo = ComboCheckBox(["Python", "Java", "Go", "C++", "JavaScript", "PHP"])
    layout = QVBoxLayout()
    layout.addWidget(combo)
    self.setLayout(layout)
if __name__ == "__main__":
  app = QApplication(sys.argv)
  ui = UiMainWindow()
  ui.show()
  sys.exit(app.exec_())

总结

到此这篇关于自定义实现 PyQt5 下拉复选框 ComboCheckBox的完整代码的文章就介绍到这了,更多相关PyQt5 下拉复选框 ComboCheckBox内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python统计日志ip访问数的方法
Jul 06 Python
Django框架中处理URLconf中特定的URL的方法
Jul 20 Python
python3使用urllib模块制作网络爬虫
Apr 08 Python
Python温度转换实例分析
Jan 17 Python
Python 忽略warning的输出方法
Oct 18 Python
python pandas读取csv后,获取列标签的方法
Nov 12 Python
网易2016研发工程师编程题 奖学金(python)
Jun 19 Python
利用python在大量数据文件下删除某一行的例子
Aug 21 Python
python 命令行传入参数实现解析
Aug 30 Python
解决paramiko执行命令超时的问题
Apr 16 Python
Python基于xlutils修改表格内容过程解析
Jul 28 Python
解决numpy数组互换两行及赋值的问题
Apr 17 Python
动态设置django的model field的默认值操作步骤
Mar 30 #Python
python数据库操作mysql:pymysql、sqlalchemy常见用法详解
Mar 30 #Python
django 实现手动存储文件到model的FileField
Mar 30 #Python
解决django FileFIELD的编码问题
Mar 30 #Python
Python动态导入模块:__import__、importlib、动态导入的使用场景实例分析
Mar 30 #Python
Django 删除upload_to文件的步骤
Mar 30 #Python
python with语句的原理与用法详解
Mar 30 #Python
You might like
加强版phplib的DB类
2008/03/31 PHP
解析:使用php mongodb扩展时 需要注意的事项
2013/06/18 PHP
简单实现php上传文件功能
2017/09/21 PHP
PHP5.0 TIDY_PARSE_FILE缓冲区溢出漏洞的解决方案
2018/10/14 PHP
Javascript this关键字使用分析
2008/10/21 Javascript
复制小说文本时出现的随机乱码的去除方法
2010/09/07 Javascript
js加密解密字符串可自定义密码因子
2014/05/13 Javascript
简单的jquery左侧导航栏和页面选中效果
2014/08/21 Javascript
jquery+html5烂漫爱心表白动画代码分享
2015/08/24 Javascript
JavaScript的String字符串对象常用操作总结
2016/05/26 Javascript
简单实现Bootstrap标签页
2020/08/09 Javascript
详解百度百科目录导航树小插件
2017/01/08 Javascript
浅谈JavaScript异步编程
2017/01/20 Javascript
BackBone及其实例探究_动力节点Java学院整理
2017/07/14 Javascript
vue scroller返回页面记住滚动位置的实例代码
2018/01/29 Javascript
ionic4+angular7+cordova上传图片功能的实例代码
2019/06/19 Javascript
浅谈vue中使用编辑器vue-quill-editor踩过的坑
2020/08/03 Javascript
angular8.5集成TinyMce5的使用和详细配置(推荐)
2020/11/16 Javascript
python base64 decode incorrect padding错误解决方法
2015/01/08 Python
Python中使用strip()方法删除字符串中空格的教程
2015/05/20 Python
python打造爬虫代理池过程解析
2019/08/15 Python
关于django 1.10 CSRF验证失败的解决方法
2019/08/31 Python
Python pandas.DataFrame 找出有空值的行
2019/09/09 Python
python多进程重复加载的解决方式
2019/12/13 Python
pytorch torch.nn.AdaptiveAvgPool2d()自适应平均池化函数详解
2020/01/03 Python
基于Python爬取fofa网页端数据过程解析
2020/07/13 Python
日本航空官方网站:JAL
2019/06/19 全球购物
医学院护理专业应届生求职信
2013/11/12 职场文书
大四学年自我鉴定
2013/11/13 职场文书
餐饮管理自我介绍信
2014/01/15 职场文书
学生保证书范文
2014/04/28 职场文书
铅球加油稿100字
2014/09/26 职场文书
教师业务学习材料
2014/12/16 职场文书
公务员的复习计划书,请收下!
2019/07/15 职场文书
教你做个可爱的css滑动导航条
2021/06/15 HTML / CSS
Java8 Stream API 提供了一种高效且易于使用的处理数据的方式
2022/04/13 Java/Android