我正在编写一个应用程序,它使用自定义 QWidget 代替 PyQt 中的常规列表项或委托。我已经按照QWidgetDelegate 的 paint() 方法中的 Render QWidget 中的答案为 QListView实现了带有自定义小部件的 QTableModel。生成的示例代码位于此问题的底部。实现中有一些我不知道如何解决的问题:
- 不显示时卸载项目。我计划为一个包含数千个条目的列表构建我的应用程序,但我无法在内存中保留那么多小部件。
- 加载尚未在视图中的项目或至少异步加载它们。小部件需要一些时间来呈现,下面的示例代码在滚动列表时有一些明显的滞后。
- 在下面的实现中滚动列表时,加载时每个新加载的按钮都会在 QListView 的左上角显示一瞬间,然后弹回原位。怎么能避免呢?
--
import sys
from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import Qt
class TestListModel(QtCore.QAbstractListModel):
def __init__(self, parent=None):
QtCore.QAbstractListModel.__init__(self, parent)
self.list = parent
def rowCount(self, index):
return 1000
def data(self, index, role):
if role == Qt.DisplayRole:
if not self.list.indexWidget(index):
button = QtGui.QPushButton("This is item #%s" % index.row())
self.list.setIndexWidget(index, button)
return QtCore.QVariant()
if role == Qt.SizeHintRole:
return QtCore.QSize(100, 50)
def columnCount(self, index):
pass
def main():
app = QtGui.QApplication(sys.argv)
window = QtGui.QWidget()
list = QtGui.QListView()
model = TestListModel(list)
list.setModel(model)
list.setVerticalScrollMode(QtGui.QAbstractItemView.ScrollPerPixel)
layout = QtGui.QVBoxLayout(window)
layout.addWidget(list)
window.setLayout(layout)
window.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()