一、前言

  由于最近的项目需要具有复选功能,但过多的复选框会影响界面布局和美观,因而想到把 PyQt5 的下拉列表和复选框结合起来,但在 PyQt5 中并没有这样的组件供我们使用,所以想要自己实现一个下拉复选框,主要就是继承 QComboBox 类,然后将复选框 QCheckBox 加入其中,并实现相应的功能。

  最终实现的下拉复选框效果如下:

  

二、代码实现

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的更多相关文章

  1. 同上! 下拉复选框 点击当前的checkbox 选中后面li 添加到指定区域

    (function() { $(".cxbtntj").click(function(){ console.log($("#jsLi1").attr(" ...

  2. finereport 下拉复选框多选

  3. Jquery 插件 chosen_v1.8.7 下拉复选框带搜索功能

    地址:https://harvesthq.github.io/chosen/ 效果: 因为只需要这个功能,就只研究这个功能了,代码: <!doctype html> <html la ...

  4. 我的第一个jquery插件:下拉多选框

    <!DOCTYPE HTML> <html> <head> <title> New Document </title> <meta n ...

  5. 品优购商城项目(二)AngularJS、自动代码生成器、select2下拉多选框

    品优购商城想项目第二阶段 AngularJS.自动代码生成器.select2下拉多选框 完成了课程第三天.第四天的的任务. 1.学习了AngularJs前端的mvc分层思想,js部分分成control ...

  6. 使用jQuery为文本框、单选框、多选框、下拉框、下拉多选框设值及返回值的处理

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...

  7. angular2.x 下拉多选框选择组件

    angular2.x - 5.x 的下拉多选框选择组件 ng2 -- ng5.最近在学angular4,经常在交流群看见很多人问 下拉多选怎么做... 今天就随便写的个. 组件源码 百度云   链接: ...

  8. 自己用ul模拟实现下拉多选框,

    模拟实现下拉多选框 效果如下 <!DOCTYPE html> <html lang="en"> <head> <meta charset= ...

  9. jquery--获取多选框的值、获取下拉多选框的值

    获取多选框的值 var packageCodeList=new Array(); $('#server_id:checked').each(function(){ packageCodeList.pu ...

随机推荐

  1. javascript中this的四种用法

    javascript中this的四种用法 投稿:hebedich 字体:[增加 减小] 类型:转载 时间:2015-05-11我要评论 在javascript当中每一个function都是一个对象,所 ...

  2. 微软推出中文学习AI助手Microsoft Learn Chinese

    ​ 编者按:美国总统特朗普访华期间,他6岁的外孙女阿拉贝拉用中文普通话演唱和背诵传统诗歌的视频在中国社交媒体上引起广泛关注,可以感受得到,越来越多的人对中文学习充满了兴趣.智能私教微软小英帮助很多中国 ...

  3. 以后的IT路还很长(1)

    以后的IT路还很长(1) 最近有两位兄弟同事离职了,蛮可惜了,在一个战壕一起一.两年了,人各有志嘛!希望他们发展更好些! 目前的公司是个创业型的公司,公司从08年的50来个人,扩张到今年11年400多 ...

  4. 什么是SNAT

    SNAT是源地址转换,其作用是将ip数据包的源地址转换成另外一个地址,可能有人觉得奇怪,好好的为什么要进行ip地址转换啊,为了弄懂这个问题,我们要看一下局域网用户上公网的原理,假设内网主机A(192. ...

  5. Spring aop(1)--- 寻找切面和代理对象执行流程源码分析

    1.基于注解,首先我们是通过@EnableAspectJAutoProxy()这个注解开起AOP功能,这个注解会导入AspectJAutoProxyRegistrar组件从而将AnnotationAw ...

  6. ElasticSearch实战系列五: ElasticSearch的聚合查询基础使用教程之度量(Metric)聚合

    Title:ElasticSearch实战系列四: ElasticSearch的聚合查询基础使用教程之度量(Metric)聚合 前言 在上上一篇中介绍了ElasticSearch实战系列三: Elas ...

  7. PHP压缩文件夹 php

    $path = PUBLIC_DIR.'/images/'; //待压缩文件夹父目录 $zipPath = PUBLIC_DIR.'/images_zip/'; //压缩文件保存目录 !is_dir( ...

  8. node--CommonJS

    1.CommonJS 1)弥补js没有标准的缺陷 2.Node模块 1)分为核心模块和用户自定义模块 2)我们可以把公共的功能抽离为一个单独的js文件作为一个模块 其中的成员和属性外界无法访问,若要设 ...

  9. 小白学 Python 数据分析(13):Pandas (十二)数据表拼接

    人生苦短,我用 Python 前文传送门: 小白学 Python 数据分析(1):数据分析基础 小白学 Python 数据分析(2):Pandas (一)概述 小白学 Python 数据分析(3):P ...

  10. startUML5.0中的tools下怎么没有java、c等选项

    这也是帮一个直系学妹弄得,哈哈~~~ 具体做法如下: 进入到StartUML\modules目录下,里面有很多文件夹,比如startuml-cpp.startuml-csharp等等, 进入到每个文件 ...