PyQt5开发之QTableWidget表头自定义与美化

1,751 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第16天,点击查看活动详情

前言

  • 博主进行在做PyQt5软件开发的美化工作,其中遇到一个比较困难的问题是QTableWidget控件的样式设置与自定义。众所周知,PyQt5是从Qt5迁移过来了,网上关于QTableWidget的PyQt5样式设置的资料比较零散。
  • 笔者经过一个下午和晚上的时间,查阅了大量资料(包括Python版和大量C++版的资料),终于了解了QTableWidget这个控件的更多细节。
  • 为了帮助遇到与博主类似问题的小伙伴,节省大量查询资料的时间,现单独写了一个QWidget嵌套QTableWidget的一个Demo,实现了设计图99%的美化需求,并完成了基本的交互,这个Demo的代码可以轻松迁移到其他完整窗口设计中。废话不多,见设计图与实现的效果图,后文提供下载链接。

知识点与实现要点

  • QTableWidget的样式设置(美化QSS、单元格样式设置)
  • QTableWidget自定义表头(添加QCheckBox全选复选框,并实现交互逻辑)
  • QScrollBar的样式设置
  • QCheckBox的样式设置
  • 提供向表格插入数据的API
  • 提供情况表格数据的API
  • 表格宽度自适应窗口宽度

QTableWidget实现框架

以下展示部分代码,完成代码请通过最后的链接下载,资源为博主原创!

from PyQt5.QtWidgets import *
from PyQt5.Qt import Qt
from PyQt5.QtGui import *
from PyQt5 import QtCore, QtGui
from UI_TableWidget import Ui_TableWidget
import sys
import resources_qt5
import random


class WidgetWindow(QWidget):
    def __init__(self):
        super(WidgetWindow, self).__init__()
        self.ui = Ui_TableWidget()
        self.ui.setupUi(self)

        # 删除原有的所有行
        self.removeAllRow()
        # self.addCheckBox2Cell(self.ui.tableWidget.rowCount(), 0)

        # 定制水平表头
        self.setCustomHeader()

        # 协调全选按钮与其他按钮事件的状态,避免冲突发生
        self.needCheckAll = True
        self.needCancelAll = True

        # 设置列宽模式
        self.ui.tableWidget.resizeColumnToContents(0)
        self.ui.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)  # 自适应窗口宽度
        self.ui.tableWidget.horizontalHeader().setSectionResizeMode(0, QHeaderView.Fixed)  # 第一列自适应内容
        self.ui.tableWidget.verticalHeader().setVisible(False)

        # 添加演示数据
        for i in range(10):
            self.addRow([str(random.randint(0, 100)) for i in range(self.ui.tableWidget.columnCount() - 1)])

    def setCustomHeader(self):
        '''
        QTableWidget表头自定义,添加控件
        :return:
        '''
        # 初始化表格的model
        _model = QStandardItemModel()
        _hHeaderView = self.ui.tableWidget.horizontalHeader()
        # 自定义QCheckBox控件,父类设置为QHeadView
        self.checkBoxSelectAll = QCheckBox(_hHeaderView)
        self.checkBoxSelectAll.stateChanged.connect(self.setSelectAll)
        self.checkBoxSelectAll.setStyleSheet('margin-left:10px;margin-top:8px;')
        _hHeaderView.setIndexWidget(_model.index(0, 0), self.checkBoxSelectAll)

    def addCheckBox2Cell(self, row, column):
        '''
        向指定单元格添加QCheckBox
        :param row:
        :param column:
        :return:
        '''
        pass  # 请下载完整版代码查看

    def addRow(self, rowData: list):
        '''
        向单元格添加一行数据
        :param rowData:
        :return:
        '''
        self.addCheckBox2Cell(self.ui.tableWidget.rowCount(), 0)
        for i in range(len(rowData)):
            item = QTableWidgetItem(rowData[i])
            item.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
            self.ui.tableWidget.setItem(self.ui.tableWidget.rowCount() - 1, i + 1, item)

    def removeAllRow(self):
        '''
        删除QTableWidget所有单元格
        :return:
        '''
        self.ui.tableWidget.setRowCount(0)

    def setSelectAll(self):
        '''
        点击表头的QCheckBox,表格所有QCheckBox勾选,反之,取消勾选
        :return:
        '''
        pass  # 请下载完整版代码查看

    def checkIsSelectAll(self):
        '''
        当第一列有QCheckBox取消勾选或者勾选时,需要检查所有QCheckBox是否勾选来设置全选QCheckBox的状态
        :return:
        '''
        pass  # 请下载完整版代码查看


if __name__ == '__main__':
    app = QApplication(sys.argv)
    widgetWindow = WidgetWindow()
    widgetWindow.show()
    sys.exit(app.exec_())

设计图

在这里插入图片描述

实现效果图

表格中数据由随机数生成,测试用!

请添加图片描述

实现效果图(Gif动图)

请添加图片描述

源码下载

PyQt5开发之QTableWidget表头自定义与美化Demo