自定义实现 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的Django框架中的中间件
Jul 24 Python
python记录程序运行时间的三种方法
Jul 14 Python
Python线程下使用锁的技巧分享
Sep 13 Python
Python面向对象程序设计类变量与成员变量、类方法与成员方法用法分析
Apr 12 Python
解决Django 在ForeignKey中出现 non-nullable field错误的问题
Aug 06 Python
python每天定时运行某程序代码
Aug 16 Python
Python 导入文件过程图解
Oct 15 Python
python 解决print数组/矩阵无法完整输出的问题
Feb 19 Python
django rest framework serializers序列化实例
May 13 Python
pycharm激活方法到2099年(激活流程)
Sep 22 Python
python 逐步回归算法
Apr 06 Python
Pandas-DataFrame知识点汇总
Mar 16 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
PHP 和 COM
2006/10/09 PHP
dedecms系统常用术语汇总
2007/04/03 PHP
php操作xml入门之xml标签的属性分析
2015/01/23 PHP
PHP处理大量表单字段的便捷方法
2015/02/07 PHP
PHP 生成微信红包代码简单
2016/03/25 PHP
PHP面向对象程序设计之命名空间与自动加载类详解
2016/12/02 PHP
在Laravel中使用MongoDB的方法示例
2019/11/11 PHP
处理及遍历XML文档DOM元素属性及方法整理
2013/08/23 Javascript
浏览器图片选择预览、旋转、批量上传的JS代码实现
2013/12/04 Javascript
javascript新闻跑马灯实例代码
2020/07/29 Javascript
JavaScript实现图片滑动切换的代码示例分享
2016/03/06 Javascript
基于vue的下拉刷新指令和滚动刷新指令
2016/12/23 Javascript
node.js中cluster的使用教程
2017/06/09 Javascript
js实现图片轮播效果学习笔记
2017/07/26 Javascript
微信小程序switch开关选择器使用详解
2018/01/31 Javascript
如何手动实现es5中的bind方法详解
2018/12/07 Javascript
浅谈微信小程序列表埋点曝光指南
2019/10/15 Javascript
JS表单验证插件之数据与逻辑分离操作实例分析【策略模式】
2020/05/01 Javascript
[02:48]DOTA2超级联赛专访海涛:你们的选择没有错
2013/06/07 DOTA
[11:44]Ti9 OG夺冠时刻
2019/08/25 DOTA
windows下wxPython开发环境安装与配置方法
2014/06/28 Python
用Python登录好友QQ空间点赞的示例代码
2017/11/04 Python
人脸识别经典算法一 特征脸方法(Eigenface)
2018/03/13 Python
python使用sqlite3时游标使用方法
2018/03/13 Python
python之pymysql模块简单应用示例代码
2019/12/16 Python
如何编写python的daemon程序
2021/01/07 Python
Office DEPOT法国官网:欧迪办公用品采购
2018/01/03 全球购物
高职助产应届生自荐信
2013/09/24 职场文书
职业规划实施方案
2014/06/10 职场文书
2014年校长工作总结
2014/12/11 职场文书
酒店员工辞职信范文
2015/02/28 职场文书
收入证明申请书
2015/06/12 职场文书
2015年秋季灭鼠工作总结
2015/07/27 职场文书
实验心得体会范文
2016/01/25 职场文书
python自动化调用百度api解决验证码
2021/04/13 Python
解决Pytorch中关于model.eval的问题
2021/05/22 Python