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):# 如果值不能转换为浮点数,忽略颜色设置passreturn super().data(index, role)
一个工程中实际使用的demo
# 表格显示的模型,交替背景色,点击单元格选定整行import sysfrom 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) # 交替背景色1self.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.color1else:return self.color2return super().data(index, role) # 继承父类函数中的其余角色# 自定义的表格视图
class TableView(QTableView): # 继承QTableViewdef __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 = tableself.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())