自定义实现 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 相关文章推荐
9种python web 程序的部署方式小结
Jun 30 Python
Python中List.index()方法的使用教程
May 20 Python
对python 矩阵转置transpose的实例讲解
Apr 17 Python
Python列表生成式与生成器操作示例
Aug 01 Python
python在TXT文件中按照某一字符串取出该字符串所在的行方法
Dec 10 Python
利用PyCharm Profile分析异步爬虫效率详解
May 08 Python
浅谈Python大神都是这样处理XML文件的
May 31 Python
如何在VSCode上轻松舒适的配置Python的方法步骤
Oct 28 Python
Python集合操作方法详解
Feb 09 Python
浅析Python迭代器的高级用法
Jul 16 Python
python 利用openpyxl读取Excel表格中指定的行或列教程
Feb 06 Python
Matlab使用Plot函数实现数据动态显示方法总结
Feb 25 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
虹吸壶是谁发明的?煮出来的咖啡好喝吗
2021/03/04 冲泡冲煮
thinkphp诸多限制条件下如何getshell详解
2020/12/09 PHP
Javascript图像处理—平滑处理实现原理
2012/12/28 Javascript
jquery获取div宽度的实现思路与代码
2013/01/13 Javascript
js字母大小写转换实现方法总结
2013/11/13 Javascript
easyui datagrid 键盘上下控制选中行示例
2014/03/31 Javascript
对比分析AngularJS中的$http.post与jQuery.post的区别
2015/02/27 Javascript
jQuery中的ajax async同步和异步详解
2015/09/29 Javascript
babel基本使用详解
2017/02/17 Javascript
浅谈js for循环输出i为同一值的问题
2017/03/01 Javascript
JavaScript实现图片本地预览功能【不用上传至服务器】
2017/09/20 Javascript
Vue SSR 组件加载问题
2018/05/02 Javascript
Nodejs模块的调用操作实例分析
2018/12/25 NodeJs
angular4自定义组件非input元素实现ngModel双向数据绑定的方法
2018/12/28 Javascript
JS中call()和apply()的功能及用法实例分析
2019/06/28 Javascript
Vue数字输入框组件使用方法详解
2020/02/10 Javascript
javascript实现页面的实时时钟显示示例
2020/08/06 Javascript
Vue 使用iframe引用html页面实现vue和html页面方法的调用操作
2020/11/16 Javascript
微信小程序自定义支持图片的弹窗
2020/12/21 Javascript
Python中的Classes和Metaclasses详解
2015/04/02 Python
Python实现的生成格雷码功能示例
2018/01/24 Python
python 中if else 语句的作用及示例代码
2018/03/05 Python
Python自动发送邮件的方法实例总结
2018/12/08 Python
tensorflow实现二维平面模拟三维数据教程
2020/02/11 Python
使用matlab 判断两个矩阵是否相等的实例
2020/05/11 Python
python属于跨平台语言码
2020/06/09 Python
python Matplotlib数据可视化(2):详解三大容器对象与常用设置
2020/09/30 Python
python两种获取剪贴板内容的方法
2020/11/06 Python
加拿大最大的书店:Indigo
2017/01/01 全球购物
一年级班主任寄语
2014/01/19 职场文书
一名老师的自我评价
2014/02/07 职场文书
桥梁工程专业求职信
2014/04/21 职场文书
企业口号大全
2014/06/12 职场文书
2014年度安全生产目标管理责任书
2014/07/25 职场文书
springBoot基于webSocket实现扫码登录
2021/06/22 Java/Android
Python实现照片卡通化
2021/12/06 Python