python - QListView 中自定义 IndexWidget 的平滑延迟加载和卸载

标签 python qt user-interface pyqt qtableview

我正在编写一个应用程序,它使用自定义 QWidget 代替 PyQt 中的常规列表项或委托(delegate)。我已经按照 Render QWidget in paint() method of QWidgetDelegate for a QListView 中的答案进行操作-- 除其他外 -- 实现带有自定义小部件的 QTableModel。生成的示例代码位于该问题的底部。实现中有一些问题不知如何解决:

  1. 卸载未展示的元素。我计划为一个包含数千个条目的列表构建我的应用程序,但我无法在内存中保留那么多小部件。
  2. 加载尚未显示的项目或至少异步加载它们。小部件需要一些时间来呈现,下面的示例代码在列表中滚动时有一些明显的滞后。
  3. 在下面的实现中滚动列表时,每个新加载的按钮在加载时会在 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()

最佳答案

您可以使用代理模型来避免加载所有小部件。代理模型可以使用视口(viewport)和小部件的高度计算行数。他可以计算出带有滚动条值的项目的索引。

这是一个不稳定的解决方案,但它应该有效。

如果您修改 data() 方法:

button = QtGui.QPushButton("This is item #%s" % index.row())
self.list.setIndexWidget(index, button)
button.setVisible(False)

这些项目只有在它们移动到它们的位置后才会显示(这对我有用)。

关于python - QListView 中自定义 IndexWidget 的平滑延迟加载和卸载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15465677/

相关文章:

c++ - MFC GUI 自定义控件 : how to draw cursor updates in response to mouse moves?

Python Tkinter : How to modify the font of the Menu widget?

python - 在系列中使用 join() 时出现键错误 0

c++ - Qt:槽返回值的含义?

c++ - 信号上的 QT 未定义引用编译错误

java - 如何使用eclipse生成多个包的可执行jar文件

java - Netbeans - 将使用 GUI Builder 制作的 GUI 组件存储在数组中

python - Raspberry Pi 上的 PyQt5 Python 线程 RFID

python - 使用 Python、Twisted 和 Flask 的服务器发送事件 : is this a correct approach for sleeping?

qt - QML ListView : Flickable as delegate cannot be scrollable