自定义实现 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 相关文章推荐
在Mac OS上部署Nginx和FastCGI以及Flask框架的教程
May 02 Python
python通过apply使用元祖和列表调用函数实例
May 26 Python
Python yield 使用方法浅析
May 20 Python
对pycharm代码整体左移和右移缩进快捷键的介绍
Jul 16 Python
python简单贪吃蛇开发
Jan 28 Python
pyqt5 禁止窗口最大化和禁止窗口拉伸的方法
Jun 18 Python
关于python导入模块import与常见的模块详解
Aug 28 Python
python RC4加密操作示例【测试可用】
Sep 26 Python
Django对接支付宝实现支付宝充值金币功能示例
Dec 17 Python
python3 requests库实现多图片爬取教程
Dec 18 Python
python ubplot使用方法解析
Jan 10 Python
python软件都是免费的吗
Jun 18 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(视频)Http下载
2006/12/12 PHP
一个基于phpQuery的php通用采集类分享
2014/04/09 PHP
浅谈PHP中pack、unpack的详细用法
2018/03/12 PHP
PHP registerXPathNamespace()函数讲解
2019/02/03 PHP
javascript类型转换示例
2014/04/29 Javascript
node.js中Socket.IO的进阶使用技巧
2014/11/04 Javascript
简单实现异步编程promise模式
2015/07/31 Javascript
JS实现Select的option上下移动的方法
2016/03/01 Javascript
javascript获取网页各种高宽及位置的方法总结
2016/07/27 Javascript
Javascript中八种遍历方法的执行速度深度对比
2017/04/25 Javascript
在vue-cli脚手架中配置一个vue-router前端路由
2017/07/03 Javascript
微信小程序富文本渲染引擎的详解
2017/09/30 Javascript
vue 中的keep-alive实例代码
2018/07/20 Javascript
Python实现list反转实例汇总
2014/11/11 Python
python通过百度地图API获取某地址的经纬度详解
2018/01/28 Python
在Python中实现替换字符串中的子串的示例
2018/10/31 Python
python正则表达式去除两个特殊字符间的内容方法
2018/12/24 Python
详解django2中关于时间处理策略
2019/03/06 Python
Python基础之函数的定义与使用示例
2019/03/23 Python
python实现证件照换底功能
2019/08/20 Python
Django实现auth模块下的登录注册与注销功能
2019/10/10 Python
如何使用Python抓取网页tag操作
2020/02/14 Python
学习Python爬虫的几点建议
2020/08/05 Python
Python3+RIDE+RobotFramework自动化测试框架搭建过程详解
2020/09/23 Python
Python命令行参数argv和argparse该如何使用
2021/02/08 Python
HTML5 拖放功能实现代码
2016/07/14 HTML / CSS
解锁canvas导出图片跨域的N种姿势小结
2019/01/24 HTML / CSS
荷兰网上药店:Drogisterij.net
2019/09/03 全球购物
记帐员岗位责任制
2014/02/08 职场文书
咖啡厅商业计划书
2014/09/15 职场文书
大四优秀党员个人民主评议
2014/09/19 职场文书
单位工作证明格式模板
2014/10/04 职场文书
地方白酒代理协议书
2014/10/25 职场文书
指导教师推荐意见
2015/06/05 职场文书
《赵州桥》教学反思
2016/02/17 职场文书
Filebeat 采集 Nginx 日志的方法
2021/03/31 Servers