我知道在 stackoverflow 上有很多次关于如何为 QTableView 设置行高的问题得到了解答。我再问一次,但我的问题并不完全是关于“如何”,至少不是那么简单。我在Qt.SizeHintRole
我的自定义模型的数据方法的帮助下成功设置了行高QAbstractTableModel
- 请参见下面的代码。(也尝试了非常相似的例子,但在sizeHint()
方法的帮助下QStyledItemDelegate
- 结果完全相同。)
当我有大约 100 个时,它工作得很好,MODEL_ROW_COUNT
如下例所示。但是我的数据集有大约 30-40 千行。结果,这个简单的应用程序启动大约 30 秒,MODEL_ROW_COUNT=35000
例如。
这个大延迟的原因是这行代码:如果我要评论这行代码,
self.table_view.verticalHeader().setSectionResizeMode(QHeaderView.ResizeToContents)
一切都会很快。MODEL_ROW_COUNT=35000
但在这种情况下,data()
方法没有被调用,Qt.SizeHintRole
我不能操纵行高。
所以,我的问题是 - 如何为具有数千行的数据集设置每行的行高?下面的示例有效,但需要 30 秒才能从 35 000 行开始(显示窗口后一切都很流畅)...
同时如果我使用QSqlTableModel
它没有这个问题,我可以使用sizeHint()
没有QStyledItemDelegate
大问题。但是有太多的委托是一团糟……我可以继承QStyledItemDelegate
而不是QAbstractTableModel
实现我的自定义模型吗?(我不确定它是否可以作为QAbstractTableModel
自定义模型的子类的每个源推荐......)或者我做错了什么并且有比使用更好的方法QHeaderView.ResizeToContents
?
PS我真的需要不同的高度。数据库中的某些行数据较少,我可能会在几个单元格中显示它们。但其他人有更多数据,我需要额外的空间来显示它。所有行的高度相同意味着要么浪费空间(屏幕上有很多空白),要么缺少某些数据行的基本细节。我CUSTOM_ROW_HEIGHT
也只使用 contant,使示例尽可能简单且易于重现 - 您可以将任何数据库与任何大表一起使用(我想即使没有数据库,我也可以重新创建它......很快就会尝试)
from PySide2.QtWidgets import QApplication, QWidget, QVBoxLayout, QTableView, QHeaderView
from PySide2.QtSql import QSqlDatabase, QSqlQuery
from PySide2.QtCore import Qt, QAbstractTableModel, QSize
class MyWindow(QWidget):
def __init__(self):
QWidget.__init__(self)
self.db = QSqlDatabase.addDatabase("QSQLITE")
self.db.setDatabaseName("/home/db.sqlite")
self.db.open()
self.table_model = MyModel(parent=self, db=self.db)
self.table_view = QTableView()
self.table_view.setModel(self.table_model)
# SizeHint is not triggered without this line but it causes delay
self.table_view.verticalHeader().setSectionResizeMode(QHeaderView.ResizeToContents)
layout = QVBoxLayout(self)
layout.addWidget(self.table_view)
self.setLayout(layout)
class MyModel(QAbstractTableModel):
CUSTOM_ROW_HEIGHT = 300
MODEL_ROW_COUNT = 100
MODEL_COL_COUNT = 5
def __init__(self, parent, db):
QAbstractTableModel.__init__(self, parent)
self.query = QSqlQuery(db)
self.query.prepare("SELECT * FROM big_table")
self.query.exec_()
def rowCount(self, parent=None):
return self.MODEL_ROW_COUNT
def columnCount(self, parent=None):
return self.MODEL_COL_COUNT
def data(self, index, role=Qt.DisplayRole):
if not index.isValid():
return None
if role == Qt.DisplayRole:
if self.query.seek(index.row()):
return str(self.query.value(index.column()))
if role == Qt.SizeHintRole:
return QSize(0, self.CUSTOM_ROW_HEIGHT)
return None
def main():
app = QApplication([])
win = MyWindow()
win.show()
app.exec_()
if __name__ == "__main__":
main()