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 添加复选框(自定义委托)的更多相关文章

  1. Qt之QTableView添加复选框(QAbstractItemDelegate)

    简述 上节分享了使用自定义模型QAbstractTableModel来实现复选框.下面我们来介绍另外一种方式: 自定义委托-QAbstractItemDelegate. 简述 效果 QAbstract ...

  2. Qt之QTableView添加复选框(QAbstractTableModel)

    简述 使用QTableView,经常会遇到复选框,要实现一个好的复选框,除了常规的功能外,还应注意以下几点: 三态:不选/半选/全选 自定义风格(样式) 下面我们介绍一下常见的实现方式: 编辑委托. ...

  3. Qt之QHeaderView添加复选框

    简述 前面分享了QTableView中如何添加复选框.本节主要介绍QTableView中的表头-QHeaderView添加复选框的功能,下面以水平表头为例,垂直表头类似! 简述 效果 QHeaderV ...

  4. QListWidget的QComboBox下拉列表添加复选框及消息处理

    要在QComboBox下拉列表项中添加复选框,并进行消息处理,在网上搜索了很久没有找到太多有用的信息和实际的例子,但从中还是找到了一些提示性的资料,根据这些简短的介绍,最终实现了这个功能. QComb ...

  5. excel添加复选框和去掉复选框

    添加复选框 我测试的excel版本是最新版2016,所有版本都是找开发者工具里面包含很多工具呢,大家可以慢慢测试 excel的右上角 点击文件-->选项-->自定义功能区-->添加开 ...

  6. 组合框里添加复选框的方法(使用勾选的假象,用图片代替而已,并非QT原生支持)

    组合框可以看作是列表框和文本框的组合,因其占据的空间少,使用操作方便,常被界面设计人员用于界面开发设计中,在有限个输入的条件下,组合框常用来代替文本框,这样从用户使用角度来看,更趋人性化,所见即所得. ...

  7. 雷林鹏分享:jQuery EasyUI 数据网格 - 添加复选框

    jQuery EasyUI 数据网格 - 添加复选框 本实例演示如何放置一个复选框列到数据网格(DataGrid).通过复选框,用户将可以选择 选中/取消选中 网格行数据. 为了添加一个复选框列,我们 ...

  8. dojo:为数据表格添加复选框

    一.添加复选框 此时应该选用EnhancedGrid,而不是普通的DataGrid.添加复选框需要设置EnhancedGrid的plugins属性,如下: gridLayout =[{ default ...

  9. DateGridView标题列头添加复选框

    第一:添加列标题时,添加两个空格——用于显示复选框: 第二:实现列标题添加复选框,代码如下: private void AddCheckeBoxToDGVHeader(DataGridView dgv ...

随机推荐

  1. HDU-6703 array (线段树)

    题意 一个长度为n的排列a,\(\forall i\in [1,n] ,1\le a_i \le n\) , m次操作,每次操作: (1,pos),把 \(a_{pos}\) 变为\(a_{pos} ...

  2. 1155 Heap Paths

    题干前半略. Sample Input 1: 8 98 72 86 60 65 12 23 50   Sample Output 1: 98 86 23 98 86 12 98 72 65 98 72 ...

  3. MySQL8.0数据库出现的问题——外码创建方式、外键约束两个引用列不兼容问题、check约束问题、用触发器代替check约束、关键字DELIMITER、删除添加索引、删除添加外键约束、和一些数据库方面的操作

    一.首先先说一下我们都需要建立那些表 mysql> CREATE TABLE IF NOT EXISTS `student`( -> `sno` CHAR(8) NOT NULL, -&g ...

  4. hdu517 Triple

    Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submissio ...

  5. Detect the Virus ZOJ - 3430 AC自动机

    One day, Nobita found that his computer is extremely slow. After several hours' work, he finally fou ...

  6. Successor HDU - 4366 分块

    代码+注释: 1 /* 2 题意: 3 一共有n个人,其中0号是总裁(金字塔顶尖).后面输入其他n-1个人的信息啊a.b.c,分别代表第i个人的上级是a,他的 4 忠诚度为b,他的能力为c.后面有m次 ...

  7. RSA 加密解密使用实例

    http://www.dtmao.cc/news_show_692109.shtml 本文不讨论RSA加密解密本身,只记录使用方法及遇到的坑,RSA原理及注意事项可在网上查找. 背景:公司的一个需求, ...

  8. [Golang]-8 工作池、速率限制、原子计数器、互斥锁

    目录 工作池 速率限制 原子计数器 互斥锁 工作池 在这个例子中,我们将看到如何使用 Go 协程和通道实现一个工作池 . func worker(id int, jobs <-chan int, ...

  9. Chrome Enhanced Protection

    Chrome Enhanced Protection chrome://settings/security?q=enhanced 站内外链跳转拦截 refs xgqfrms 2012-2020 www ...

  10. Chrome & console.log & color & js

    Chrome & console.log & color & js console.log & color // OK log(`%cchat_list =\n%c${ ...