目录
背景
背景
一个工具小需求,需要制作一个表格中表头带有全选/反选功能,网上找了许久,pyqt5 qtablewidget资料很少,找到的要么存在bug无法下手修改
效果 思路如下- 自定义表头类,继承自QHeaderView,在类中自定义全选的信号和该信号的槽方法
- 创建窗口类,在窗口类中调用实现即可
class CheckBoxHeader(QHeaderView):
clicked = pyqtSignal(int, bool) #关键点自定义信号槽,传入了2个参数记录当前选中状态
_x_offset = 3
_y_offset = 0
_width = 20
_height = 20
def __init__(self, column_indices, orientation=Qt.Horizontal, parent=None):
super(CheckBoxHeader, self).__init__(orientation, parent)
self.setSectionResizeMode(QHeaderView.Stretch)
self.setSectionsClickable(True)
if isinstance(column_indices, list) or isinstance(column_indices, tuple):
self.column_indices = column_indices
elif isinstance(column_indices, int):
self.column_indices = [column_indices]
else:
raise RuntimeError('column_indices must be a list, tuple or integer')
self.isChecked = {}
for column in self.column_indices:
self.isChecked[column] = 0
def paintSection(self, painter, rect, logicalIndex):
painter.save()
super(CheckBoxHeader, self).paintSection(painter, rect, logicalIndex)
painter.restore()
self._y_offset = int((rect.height() - self._width) / 2.)
if logicalIndex in self.column_indices:
option = QStyleOptionButton()
option.rect = QRect(rect.x() + self._x_offset, rect.y() + self._y_offset, self._width, self._height)
option.state = QStyle.State_Enabled | QStyle.State_Active
if self.isChecked[logicalIndex] == 2:
option.state |= QStyle.State_NoChange
elif self.isChecked[logicalIndex]:
option.state |= QStyle.State_On
else:
option.state |= QStyle.State_Off
self.style().drawControl(QStyle.CE_CheckBox, option, painter)
def updateCheckState(self, index, state):
'''
记录每个点击checkbox 状态及序号存入dict
:param index:
:param state:
:return:
'''
self.isChecked[index] = state
self.viewport().update()
def mousePressEvent(self, event):
index = self.logicalIndexAt(event.pos())
if 0 <= index < self.count():
x = self.sectionPosition(index)
if x + self._x_offset < event.pos().x() < x + self._x_offset + self._width and self._y_offset < event.pos().y() < self._y_offset + self._height:
if self.isChecked[index] == 1:
self.isChecked[index] = 0
else:
self.isChecked[index] = 1
self.clicked.emit(index, self.isChecked[index])
self.viewport().update()
else:
super(CheckBoxHeader, self).mousePressEvent(event)
else:
super(CheckBoxHeader, self).mousePressEvent(event)
表头复选框checkbox连接信号槽函数方法
def updateModel(index, state):
for i in range(model.rowCount()):
item = model.item(i, index)
item.setCheckState(Qt.Checked if state else Qt.Unchecked)
header.clicked.connect(updateModel)即可更新点击后CheckBox的状态监听每行item改变状态,同时联动CheckBoxHeader的updateCheckState即可
def modelChanged():
for i in range(model.columnCount()):
checked = 0
unchecked = 0
for j in range(model.rowCount()):
if model.item(j, i).checkState() == Qt.Checked:
checked += 1
elif model.item(j, i).checkState() == Qt.Unchecked:
unchecked += 1
if checked and unchecked:
header.updateCheckState(i, 2)
elif checked:
header.updateCheckState(i, 1)
else:
header.updateCheckState(i, 0)
总结
以上就是整个qtablewidget相关表头复选框的操作细节,底下有源码
Pyqt5QTableWidget/QTableView行表头添加复选框全选功能-QT文档类资源-CSDN下载



