widget_file_list/checkbox_header_table.py

100 lines
3.8 KiB
Python
Raw Permalink Normal View History

2025-02-14 15:00:10 +08:00
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())