PyQt5之 QTableView 添加复选框(自定义委托)
import sys from untitled import Ui_Form
from PyQt5.QtWidgets import QApplication, QWidget, QStyleOptionButton, QAbstractItemDelegate, QStyle, QCheckBox, QStyledItemDelegate, QStyleOptionViewItem, QItemDelegate
from PyQt5.QtCore import Qt, QAbstractTableModel, QModelIndex, QVariant, QThread, pyqtSignal, QEvent, QRect
from PyQt5.QtGui import QColor, QMouseEvent class WorkThread(QThread):
scrollBottomSignal = pyqtSignal()
addDataSignal = pyqtSignal() def __init__(self, model):
super(WorkThread, self).__init__()
self.model = model
self.run_flag = True def run(self):
while self.run_flag:
self.addDataSignal.emit()
self.scrollBottomSignal.emit()
self.usleep(1) # 不加延迟界面会卡顿。 def stop(self):
self.run_flag = False class MyTableModel(QAbstractTableModel):
def __init__(self):
super(MyTableModel, self).__init__()
self._data = [] # 要显示的数据
self._headers = ['选项', '姓名', '年龄', '性别'] # 表头 def rowCount(self, parent=QModelIndex()):
"""
返回行数量。
"""
return len(self._data) def columnCount(self, parent=QModelIndex()):
"""
返回列数量。
"""
return len(self._headers) def insertRows(self, row, count, parent):
"""
插入行。
:param row: 插入起始行。
:param count: 插入行数量。
:param parent:
:return:
"""
self.beginInsertRows(QModelIndex(), row, row + count - 1)
for i in range(count):
self._data.insert(row, [Qt.Checked, 'CZ', '25', '男'])
self.endInsertRows()
return True def removeRows(self, row, count, parent):
self.beginRemoveRows(QModelIndex(), 0, row + count - 1)
for i in range(count):
self._data.pop(row + count - 1 - i) # 倒着删
self.endRemoveRows() def clearView(self):
self.removeRows(0, self.rowCount(), QModelIndex()) def addData(self):
self.insertRows(self.rowCount(), 1, QModelIndex()) def headerData(self, section, orientation, role):
"""
设置表头。
"""
if role == Qt.DisplayRole and orientation == Qt.Horizontal: # 限定只更改行表头
return self._headers[section] def data(self, index, role=Qt.DisplayRole):
if not index.isValid() or not 0 <= index.row() < self.rowCount():
return QVariant() row = index.row()
col = index.column() if role == Qt.DisplayRole:
if col != 0:
return str(self._data[row][col]) # 数据
elif role == Qt.TextColorRole:
return QColor(Qt.red)
elif Qt.UserRole:
if col == 0:
return self._data[row][col] return QVariant() def setData(self, index, value, role):
if not index.isValid() or not 0 <= index.row() < self.rowCount():
return False
col = index.column()
row = index.row() if role == Qt.UserRole or role == Qt.CheckStateRole:
if col == 0:
self._data[row][col] = value
self.layoutChanged.emit()
return True return False def flags(self, index):
flags = Qt.ItemFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable)
return flags class MyDelegate(QStyledItemDelegate):
def __init__(self):
super(MyDelegate, self).__init__() def paint(self, painter, option, index):
if index.column() == 0:
data = index.model().data(index, Qt.UserRole) ckbtn = QStyleOptionButton()
ckbtn.state = QStyle.State_On if data == Qt.Checked else QStyle.State_Off
ckbtn.state |= QStyle.State_Enabled
ckbtn.rect = option.rect QApplication.style().drawControl(QStyle.CE_CheckBox, ckbtn, painter)
else:
QStyledItemDelegate.paint(self, painter, option, index) def editorEvent(self, event, model, option, index):
if event.type() == QEvent.KeyPress:
return False
if event.type() == QEvent.MouseButtonRelease:
event = QMouseEvent(event) # 类型强转
if event.button() == Qt.LeftButton:
value = index.data(Qt.UserRole) if value == Qt.Checked:
rev_value = Qt.Unchecked
else:
rev_value = Qt.Checked return model.setData(index, rev_value, Qt.UserRole)
else:
return False
else:
return False class MainUI(QWidget, Ui_Form):
def __init__(self):
super(MainUI, self).__init__()
self.setupUi(self)
self.workThread = None self.pushButton.clicked.connect(self.buttonClickedStart)
self.pushButton_2.clicked.connect(self.buttonClickedStop)
self.pushButton_3.clicked.connect(self.buttonClickedClear) self.model = MyTableModel()
self.myDelegate = MyDelegate()
self.tableView.setItemDelegate(self.myDelegate)
self.tableView.setModel(self.model) self.tableView.show() def buttonClickedStart(self):
"""开启线程,向表中插入数据。"""
self.workThread = WorkThread(self.model)
self.workThread.addDataSignal.connect(self.model.addData)
self.workThread.scrollBottomSignal.connect(self.scrollBottom)
self.workThread.start() def buttonClickedStop(self):
"""停止线程向表中插入数据。"""
self.workThread.stop() def buttonClickedClear(self):
"""清空表。"""
self.model.clearView() def scrollBottom(self):
"""右侧滑动条保持在最下面。"""
self.tableView.scrollToBottom() if __name__ == '__main__':
app = QApplication(sys.argv) ui = MainUI()
ui.show()
sys.exit(app.exec_())
程序运行界面图:

PyQt5之 QTableView 添加复选框(自定义委托)的更多相关文章
- Qt之QTableView添加复选框(QAbstractItemDelegate)
简述 上节分享了使用自定义模型QAbstractTableModel来实现复选框.下面我们来介绍另外一种方式: 自定义委托-QAbstractItemDelegate. 简述 效果 QAbstract ...
- Qt之QTableView添加复选框(QAbstractTableModel)
简述 使用QTableView,经常会遇到复选框,要实现一个好的复选框,除了常规的功能外,还应注意以下几点: 三态:不选/半选/全选 自定义风格(样式) 下面我们介绍一下常见的实现方式: 编辑委托. ...
- Qt之QHeaderView添加复选框
简述 前面分享了QTableView中如何添加复选框.本节主要介绍QTableView中的表头-QHeaderView添加复选框的功能,下面以水平表头为例,垂直表头类似! 简述 效果 QHeaderV ...
- QListWidget的QComboBox下拉列表添加复选框及消息处理
要在QComboBox下拉列表项中添加复选框,并进行消息处理,在网上搜索了很久没有找到太多有用的信息和实际的例子,但从中还是找到了一些提示性的资料,根据这些简短的介绍,最终实现了这个功能. QComb ...
- excel添加复选框和去掉复选框
添加复选框 我测试的excel版本是最新版2016,所有版本都是找开发者工具里面包含很多工具呢,大家可以慢慢测试 excel的右上角 点击文件-->选项-->自定义功能区-->添加开 ...
- 组合框里添加复选框的方法(使用勾选的假象,用图片代替而已,并非QT原生支持)
组合框可以看作是列表框和文本框的组合,因其占据的空间少,使用操作方便,常被界面设计人员用于界面开发设计中,在有限个输入的条件下,组合框常用来代替文本框,这样从用户使用角度来看,更趋人性化,所见即所得. ...
- 雷林鹏分享:jQuery EasyUI 数据网格 - 添加复选框
jQuery EasyUI 数据网格 - 添加复选框 本实例演示如何放置一个复选框列到数据网格(DataGrid).通过复选框,用户将可以选择 选中/取消选中 网格行数据. 为了添加一个复选框列,我们 ...
- dojo:为数据表格添加复选框
一.添加复选框 此时应该选用EnhancedGrid,而不是普通的DataGrid.添加复选框需要设置EnhancedGrid的plugins属性,如下: gridLayout =[{ default ...
- DateGridView标题列头添加复选框
第一:添加列标题时,添加两个空格——用于显示复选框: 第二:实现列标题添加复选框,代码如下: private void AddCheckeBoxToDGVHeader(DataGridView dgv ...
随机推荐
- LightOJ - 1151 Snakes and Ladders(概率dp+高斯消元)
有100个格子,从1开始走,每次抛骰子走1~6,若抛出的点数导致走出了100以外,则重新抛一次.有n个格子会单向传送到其他格子,G[i]表示从i传送到G[i].1和100不会有传送,一个格子也不会有两 ...
- [USACO12FEB]Symmetry
传送门: https://www.luogu.com.cn/problem/P3046 https://ac.nowcoder.com/acm/contest/6306/G 题意 给定n个不同的点,求 ...
- HDU6434 Count【欧拉函数 线性筛】
HDU6434 I. Count T次询问,每次询问\(\sum_{i=1}^{n}\sum_{j=1}^{n-1}[gcd(i-j,i+j)=1]\) \(T\le 1e5, n \le 2e7\) ...
- hdu3436 Queue-jumpers(Splay)
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission ...
- python+requests爬取百度文库ppt
实验网站:https://wenku.baidu.com/view/c7752014f18583d04964594d.html 在下面这种类型文件中的请求头的url打开后会得到一个页面 你会得到如下图 ...
- 考研路茫茫——单词情结 HDU - 2243 AC自动机 && 矩阵快速幂
背单词,始终是复习英语的重要环节.在荒废了3年大学生涯后,Lele也终于要开始背单词了. 一天,Lele在某本单词书上看到了一个根据词根来背单词的方法.比如"ab",放在单词前一般 ...
- Java基础(第二期)
数据类型扩展以及面试题讲解 整数拓展:进制 int i=10; int i2=010; //八进制0 int i3=0x10; //十六进制0x 0~9 A~F 16 相关进制转换自行学习,用的不多 ...
- Ruby on Rails
Ruby on Rails 是一个可以使你开发,部署,维护 web 应用程序变得简单的框架.在2004年7月,由Rails的创始人大卫·海纳梅尔·韩森从37signals公司的项目管理工具Baseca ...
- 微服务架构Day03-SpringBoot之web开发配置
概述 SpringBoot开发: 1.创建SpringBoot应用,选中需要的场景模块. 2.SpringBoot已经默认将场景模块配置好,只需要在配置文件中指定少量的配置(数据库地址,用户名,密码) ...
- Linux内核实现透视---硬中断
Linux的中断处理是驱动中比较重要的一部分内容,要清楚具体的实现才能更好的理解而不是靠记住别人理解后总结的规律,所以今天就打算从从源码来学习一下Linux内核对于中断处理过程,设计中断子系统的初始化 ...