自定义实现 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获取CPU、内存和硬盘等windowns系统信息的2个例子
Apr 15 Python
Python实现string字符串连接的方法总结【8种方式】
Jul 06 Python
Python面向对象之类和对象实例详解
Dec 10 Python
详解Python 定时框架 Apscheduler原理及安装过程
Jun 14 Python
Python爬虫实现的根据分类爬取豆瓣电影信息功能示例
Sep 15 Python
python实现全排列代码(回溯、深度优先搜索)
Feb 26 Python
使用K.function()调试keras操作
Jun 17 Python
Python使用Selenium实现淘宝抢单的流程分析
Jun 23 Python
Python map及filter函数使用方法解析
Aug 06 Python
python删除文件、清空目录的实现方法
Sep 23 Python
python可视化 matplotlib画图使用colorbar工具自定义颜色
Dec 07 Python
Python实现制作销售数据可视化看板详解
Nov 27 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
动易数据转成dedecms的php程序
2007/04/07 PHP
php为什么选mysql作为数据库? Mysql 创建用户方法
2007/07/02 PHP
flash用php连接数据库的代码
2011/04/21 PHP
rephactor 优秀的PHP的重构工具
2011/06/09 PHP
PHP信号量基本用法实例详解
2016/02/12 PHP
纯文字版返回顶端的js代码
2013/08/01 Javascript
在JavaScript中使用开平方根的sqrt()方法
2015/06/15 Javascript
jQuery 判断图片是否加载完成方法汇总
2015/08/10 Javascript
js实现简洁大方的二级下拉菜单效果代码
2015/09/01 Javascript
原生node.js案例--前后台交互
2017/02/20 Javascript
AngularJS实现controller控制器间共享数据的方法示例
2017/10/30 Javascript
Node.js中的不安全跳转如何防御详解
2018/10/21 Javascript
浅谈layui 表单元素的选中问题
2019/10/25 Javascript
js将日期格式转换为YYYY-MM-DD HH:MM:SS
2020/09/18 Javascript
微信小程序实现滚动Tab选项卡
2020/11/16 Javascript
js面向对象方式实现拖拽效果
2021/03/03 Javascript
Python中os.path用法分析
2015/01/15 Python
说一说Python logging
2016/04/15 Python
python 计算数组中每个数字出现多少次--“Bucket”桶的思想
2017/12/19 Python
Python实现京东秒杀功能代码
2019/05/16 Python
升级keras解决load_weights()中的未定义skip_mismatch关键字问题
2020/06/12 Python
这76道Java面试题及答案,祝你能成功通过面试
2016/04/16 面试题
家长给幼儿园的表扬信
2014/01/09 职场文书
对孩子的寄语
2014/04/09 职场文书
《她是我的朋友》教学反思
2014/04/26 职场文书
公司的门卫岗位职责
2014/09/09 职场文书
购房委托书
2014/10/15 职场文书
2014年统计工作总结
2014/11/21 职场文书
天下第一关导游词
2015/02/06 职场文书
导盲犬小Q观后感
2015/06/11 职场文书
如何用Navicat操作MySQL
2021/05/12 MySQL
Python import模块的缓存问题解决方案
2021/06/02 Python
微软PC Health Check电脑健康状况检查应用下载(Win11配置检测工具)
2021/06/26 数码科技
解决MultipartFile.transferTo(dest) 报FileNotFoundExcep的问题
2021/07/01 Java/Android
一文搞清楚MySQL count(*)、count(1)、count(col)区别
2022/03/03 MySQL
Java字符串逆序方法详情
2022/03/21 Java/Android