自定义实现 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错误处理详解
Sep 28 Python
python正则表达式中的括号匹配问题
Dec 14 Python
在Python中关于中文编码问题的处理建议
Apr 08 Python
在Python中使用mongoengine操作MongoDB教程
Apr 24 Python
在Python中操作字典之setdefault()方法的使用
May 21 Python
Python 使用类写装饰器的小技巧
Sep 30 Python
Python3实现爬取简书首页文章标题和文章链接的方法【测试可用】
Dec 11 Python
Python 仅获取响应头, 不获取实体的实例
Aug 21 Python
树莓派4B+opencv4+python 打开摄像头的实现方法
Oct 18 Python
Python实现密钥密码(加解密)实例详解
Apr 26 Python
python怎么判断模块安装完成
Jun 19 Python
Python实现对word文档添加密码去除密码的示例代码
Dec 29 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程序的方法
2009/03/09 PHP
PHP curl 抓取AJAX异步内容示例
2014/09/09 PHP
PHP+jquery+ajax实现即时聊天功能实例
2014/12/23 PHP
php中注册器模式类用法实例分析
2015/11/03 PHP
PHP程序中的文件锁、互斥锁、读写锁使用技巧解析
2016/03/21 PHP
PHP文件系统管理(实例讲解)
2017/09/19 PHP
Yii2框架实现登陆添加验证码功能示例
2018/07/12 PHP
用javascript实现的图片马赛克后显示并切换加文字功能
2007/04/21 Javascript
让网页跳转到指定位置的jquery代码非书签
2013/09/06 Javascript
自己用jQuery写了一个图片的马赛克消失效果
2014/05/04 Javascript
JavaScript阻止浏览器返回按钮的方法
2015/03/18 Javascript
JavaScript中将数组进行合并的基本方法讲解
2016/03/07 Javascript
通过隐藏iframe实现无刷新上传文件操作
2016/03/16 Javascript
JS两个数组比较,删除重复值的巧妙方法(推荐)
2016/06/03 Javascript
js select实现省市区联动选择
2020/04/17 Javascript
Javascript 动态改变imput type属性
2016/11/01 Javascript
js for循环倒序输出数组元素的实例
2017/03/01 Javascript
全局安装 Vue cli3 和 继续使用 Vue-cli2.x操作
2020/09/08 Javascript
Python利用multiprocessing实现最简单的分布式作业调度系统实例
2017/11/14 Python
使用pandas 将DataFrame转化成dict
2019/12/10 Python
python实现tail -f 功能
2020/01/17 Python
python GUI库图形界面开发之PyQt5下拉列表框控件QComboBox详细使用方法与实例
2020/02/27 Python
详解利用css3的var()实现运行时改变scss的变量值
2021/03/02 HTML / CSS
Monnier Freres中文官网:法国领先的奢侈品配饰在线零售商
2017/11/01 全球购物
加拿大在线旅游公司:Flighthub
2019/03/11 全球购物
千禧酒店及度假村官方网站:Millennium Hotels and Resorts
2019/05/10 全球购物
请写出 BOOL flag 与"零值"比较的 if 语句
2016/02/29 面试题
大学生党员自我批评
2014/02/14 职场文书
企业家王石演讲稿:坚持与放下
2014/04/27 职场文书
设备管理实施方案
2014/05/31 职场文书
计算机实训报告总结
2014/11/05 职场文书
python 自动化偷懒的四个实用操作
2021/04/11 Python
python自然语言处理之字典树知识总结
2021/04/25 Python
Python还能这么玩之用Python修改了班花的开机密码
2021/06/04 Python
Java实战之用Swing实现通讯录管理系统
2021/06/13 Java/Android
nginx配置虚拟主机的详细步骤
2021/07/21 Servers