使用QSqlQueryModel创建交替背景色的表格模型

发布于:2025-02-10 ⋅ 阅读:(11) ⋅ 点赞:(0)
class UserModel(QSqlQueryModel):
    def __init__(self):
        super().__init__()
        self._query = "SELECT name, age FROM users"
        self.refresh()

    def refresh(self):
        self.setQuery(self._query)

    # 重新定义data()方法
    def data(self, index, role):   
        if role == Qt.BackgroundRole :  # 如果角色是背景色
            if index.row() % 2 == 0:    # 偶数行
                return QColor("#a0a0a0")
            else:
                return QColor("#f0f0f0")
        return super().data(index, role)   # 其余角色继承父类的data()方法



        这段代码重新定义模型的data()方法,接收参数 index 和 role。如果 role 的值等于 Qt.BackgroundRole,表示设置背景色。如果 index 的行索引值除以 2 的余数为 0,即偶数行,返回颜色对象 QColor ("#a0a0a0"),否则返回 QColor ("#f0f0f0")。如果 role 不是 Qt.BackgroundRole,就调用父类的 data 方法并返回结果。

        利用这个方法,可以实现一些其他的特制显示,比如,在上面的基础上增加一个功能:判断一个单元格的数字是否大于某一个设定值,如果大于设定值就显示为红色:

class UserModel(QSqlQueryModel):
    def __init__(self):
        super().__init__()
        self._query = "SELECT name, age FROM users"
        self.refresh()

    def refresh(self):
        self.setQuery(self._query)

    def data(self, index, role):
        if role == Qt.BackgroundRole :  # 检查是否是背景颜色角色
            if index.row() % 2 == 0:
                return QColor("#a0a0a0")
            else:
                return QColor("#f0f0f0")
        elif role == Qt.ForegroundRole:  # 检查是否是文字颜色角色
            if index.column() == 1:  # 检查是否是 age 列
                value = self.record(index.row()).value(index.column())  # 获取单元格的值

                try:
                # 尝试将值转换为浮点数进行比较
                    if float(value) > 10:
                        return QColor(Qt.red)  # 如果大于设定值,返回红色
                except (ValueError, TypeError):
                    # 如果值不能转换为浮点数,忽略颜色设置
                    pass


        return super().data(index, role)

一个工程中实际使用的demo

# 表格显示的模型,交替背景色,点击单元格选定整行

import sys

from PySide6.QtCore import Qt, Signal, Slot
from PySide6.QtGui import QColor
from PySide6.QtSql import QSqlDatabase, QSqlQueryModel
from PySide6.QtWidgets import QApplication, QTableView, QMainWindow, QWidget, QVBoxLayout, QPushButton



# 自定义的表格模型
class TableModel(QSqlQueryModel):
    query = Signal(str)  # 信号,用于传递查询语句
    refresh = Signal()  # 信号,用于传递刷新提示

    def __init__(self, color1="#f0e0f0", color2="#fdfdfd"):
        super().__init__()
        self.color1 = QColor(color1)  # 交替背景色1
        self.color2 = QColor(color2)  # 交替背景色2
        # self.setQuery("")
        self._query = ""  # 重新定义查询语句
        self.run()  # 运行函数

    def run(self):
        @Slot()
        # 槽函数,用于执行查询
        def run_query(query):
            self._query = query  # 重新定义查询语句
            self.setQuery(self._query)  # 执行查询
            self.refresh.emit()  # 发射信号,传递刷新数据信号
        self.query.connect(run_query)  # 将槽函数与信号连接

    # 重新定义data函数,返回背景色
    def data(self, index, role):
        if role == Qt.BackgroundRole:  # 检查是否是背景颜色角色
            if index.row() % 2 == 0:
                return self.color1
            else:
                return self.color2
        return super().data(index, role)  # 继承父类函数中的其余角色


# 自定义的表格视图
class TableView(QTableView):  # 继承QTableView

    def __init__(self, parent=None):
        super().__init__(parent)
        self.model = TableModel()  # 创建一个自定义的TableModel对象
        self.setSelectionBehavior(QTableView.SelectRows)  # 设置表格视图的选择行为为选择整行,而不是单个单元格
        self.run()  # 运行函数

    def run(self):
        @Slot()
        # 槽函数,用于刷新表格的显示
        def refresh():
            self.setModel(self.model)  # 设置表格视图的模型
            self.resizeColumnsToContents()  # 根据内容调整列宽

        self.model.refresh.connect(refresh)  # 将槽函数与信号连接

# 设置数据库
def db_setup():
    db = QSqlDatabase.addDatabase("QSQLITE")  # 添加SQLite数据库驱动作为基础数据库
    db.setDatabaseName("example.db")  # 设置数据库名称
    db.open()  # 打开数据库


if __name__ == "__main__":
    app = QApplication(sys.argv)
    db_setup()   # 设置数据库

    tabview = TableView()  # 创建一个自定义的TableView对象
    tabview.model.query.emit("SELECT name, age  FROM users")  # 设置初始化的查询语句


    # 创建一个主窗口,将自定义的TableView对象作为主窗口的中央部件
    class MainWindow(QMainWindow):
        def __init__(self, table, parent=None):
            super().__init__(parent)
            self.table = table
            self.initUI()

        def initUI(self):
            layout = QVBoxLayout()  # 创建一个垂直布局
            layout.addWidget(self.table)  # 将自定义的TableView对象添加到布局中
            button = QPushButton("刷新")  # 创建一个按钮
            layout.addWidget(button)  # 将按钮添加到布局中
            central_widget = QWidget()  # 创建一个中央部件
            central_widget.setLayout(layout)  # 将布局添加到中央部件
            self.setCentralWidget(central_widget)  # 将中央部件设置为窗口的主部件

            button.clicked.connect(lambda: tabview.model.query.emit("SELECT name FROM users"))  # 设置刷新的查询语句


    window = MainWindow(tabview)
    window.show()
    sys.exit(app.exec())