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())