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. 2019牛客暑期多校训练营(第五场)E.independent set 1(状压dp)

    题意:给你n个点 m条边 问你所有子图的最大独立集的和 思路:我们可以设f state 为当前点集下的最大独立集的大小 所以我们可以把集合分为两个部分 绝对包含了这个一个点 绝对不包含这个点 两种情况 ...

  2. Java 窗口 绘制图形 #3

    写在前面: 高数下学到第二章,突发奇想要写一个程序画二元函数图像 思路分了三层: ①抽象层: 因变量z,自变量x.y,坐标原点x0.y0.z0 ②投影实现层: 屏幕投影坐标px.py,x轴与屏幕水平方 ...

  3. hdu5247 找连续数

    Problem Description 小度熊拿到了一个无序的数组,对于这个数组,小度熊想知道是否能找到一个k 的区间,里面的 k 个数字排完序后是连续的. 现在小度熊增加题目难度,他不想知道是否有这 ...

  4. Educational Codeforces Round 89 (Rated for Div. 2) C. Palindromic Paths (思维)

    题意:有一个\(n\)x\(m\)的矩阵,从\((1,1)\)出发走到\((n,m)\),问最少修改多少个数,使得所有路径上的数对应相等(e.g:\((1,2)\)和\((n-1,m)\)或\((2, ...

  5. liunx命令二

    声明:以下资料全部摘自实验楼 常用快捷键 按键 作用 Table 补全命令 Ctrl+c 强制结束 Ctrl+d 键盘输入结束或退出终端 Ctrl+s 暂停当前程序,暂停后按下任意键恢复运行 Ctrl ...

  6. 018-019 NET5_内置容器支持依赖注入+IServiceCollection的生命周期

    概念: DI依赖注入: IServiceCollection仅支持构造函数注入 什么是依赖注入? 如果对象A依赖对象B,对象B依赖对象C,就可以先构造对象C,然后传递给对象B,再把对象B传递给A.得到 ...

  7. Flutter CLI commands All In One

    Flutter CLI commands All In One Flutter run key commands. r Hot reload. R Hot restart. h Repeat this ...

  8. CSS font-weight all in one

    CSS font-weight all in one font-weight: bolder: 没毛病呀! /* 关键字值 */ font-weight: normal; font-weight: b ...

  9. Microsoft Lifecycle Policy

    Microsoft Lifecycle Policy The Microsoft Lifecycle Policy gives you consistent and predictable guide ...

  10. Android Studio show whitespace & Android studio 设置注释缩进

    Android Studio show whitespace & Android studio 设置注释缩进 https://github.com/xgqfrms/flutter/issues ...