100 lines
3.8 KiB
Python
100 lines
3.8 KiB
Python
from PySide6.QtWidgets import (QApplication, QMainWindow, QTableWidget,
|
|
QTableWidgetItem, QHeaderView)
|
|
from PySide6.QtCore import Qt, Signal
|
|
from PySide6.QtGui import QPainter
|
|
import sys
|
|
|
|
class CheckBoxHeader(QHeaderView):
|
|
checkbox_clicked = Signal(bool) # 创建信号用于传递复选框状态
|
|
|
|
def __init__(self, orientation, parent=None):
|
|
super().__init__(orientation, parent)
|
|
self.is_checked = False
|
|
self.checkbox_rect = None
|
|
self.setSectionsClickable(True)
|
|
self.sectionClicked.connect(self.handle_section_clicked)
|
|
|
|
def paintSection(self, painter: QPainter, rect, logical_index):
|
|
painter.save()
|
|
|
|
if logical_index == 0: # 在第一列绘制复选框
|
|
checkbox_size = 15
|
|
self.checkbox_rect = rect
|
|
|
|
# 计算复选框位置,稍微向左偏移
|
|
x = rect.x() + 5 # 从左边留出5像素的间距
|
|
y = rect.y() + (rect.height() - checkbox_size) // 2
|
|
|
|
# 绘制复选框
|
|
painter.setPen(Qt.black)
|
|
painter.drawRect(x, y, checkbox_size, checkbox_size)
|
|
|
|
if self.is_checked:
|
|
painter.drawLine(x + 3, y + 7, x + 6, y + 10)
|
|
painter.drawLine(x + 6, y + 10, x + 12, y + 4)
|
|
|
|
# 绘制文字
|
|
text_rect = rect.adjusted(checkbox_size + 10, 0, 0, 0) # 文字位置在复选框右侧
|
|
painter.drawText(text_rect, Qt.AlignVCenter, "选择")
|
|
else:
|
|
# 其他列正常绘制
|
|
super().paintSection(painter, rect, logical_index)
|
|
|
|
painter.restore()
|
|
|
|
def handle_section_clicked(self, logical_index):
|
|
if logical_index == 0 and self.checkbox_rect:
|
|
self.is_checked = not self.is_checked
|
|
self.checkbox_clicked.emit(self.is_checked)
|
|
self.updateSection(0)
|
|
|
|
class MainWindow(QMainWindow):
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.setWindowTitle("表头复选框示例")
|
|
self.resize(400, 300)
|
|
|
|
# 创建表格
|
|
self.table = QTableWidget(5, 3)
|
|
self.setCentralWidget(self.table)
|
|
|
|
# 设置表头
|
|
header = CheckBoxHeader(Qt.Horizontal, self.table)
|
|
self.table.setHorizontalHeader(header)
|
|
header.checkbox_clicked.connect(self.on_header_checkbox_clicked)
|
|
|
|
# 设置表头标题
|
|
self.table.setHorizontalHeaderLabels(["选择", "列1", "列2"])
|
|
|
|
# 调整列宽
|
|
self.table.horizontalHeader().setStretchLastSection(True) # 最后一列自动拉伸
|
|
self.table.horizontalHeader().resizeSection(0, 80) # 设置第一列宽度为80像素
|
|
|
|
# 调整表格样式
|
|
self.table.setShowGrid(True) # 显示网格线
|
|
self.table.setAlternatingRowColors(True) # 交替行颜色
|
|
|
|
# 填充表格数据
|
|
for row in range(5):
|
|
# 添加复选框
|
|
checkbox_item = QTableWidgetItem()
|
|
checkbox_item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
|
|
checkbox_item.setCheckState(Qt.Unchecked)
|
|
self.table.setItem(row, 0, checkbox_item)
|
|
|
|
# 添加其他数据
|
|
self.table.setItem(row, 1, QTableWidgetItem(f"数据 {row+1}-1"))
|
|
self.table.setItem(row, 2, QTableWidgetItem(f"数据 {row+1}-2"))
|
|
|
|
def on_header_checkbox_clicked(self, checked):
|
|
# 处理表头复选框点击事件
|
|
for row in range(self.table.rowCount()):
|
|
item = self.table.item(row, 0)
|
|
if item:
|
|
item.setCheckState(Qt.Checked if checked else Qt.Unchecked)
|
|
|
|
if __name__ == "__main__":
|
|
app = QApplication(sys.argv)
|
|
window = MainWindow()
|
|
window.show()
|
|
sys.exit(app.exec()) |