相关文章推荐
气势凌人的稀饭  ·  SparkSQL一行转多行 一列变多列 ...·  4 月前    · 
谦虚好学的铁板烧  ·  Indexer errors and ...·  11 月前    · 
含蓄的铁板烧  ·  BeanDefinitionOverride ...·  1 年前    · 
留胡子的汤圆  ·  VBA-新建工作簿_新建vba_交小通的博客 ...·  2 年前    · 
文雅的领带  ·  根据Cron表达式获取近几次任务执行时间(S ...·  2 年前    · 
Code  ›  自定义IndexWidget在QListView中的平滑延迟加载和卸载开发者社区
按钮 list 延迟加载 qlistview
https://cloud.tencent.com/developer/ask/sof/109757473
想出国的烤地瓜
1 年前
首页
学习
活动
专区
工具
TVP 最新优惠活动
返回腾讯云官网
提问

问 自定义IndexWidget在QListView中的平滑延迟加载和卸载

Stack Overflow用户
提问于 2013-03-17 20:15:15
EN

我正在编写一个应用程序,它使用自定义QWidget代替PyQt中的常规词条或委托。我遵循了 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):
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()
2 2.5K 0 票数 4
EN
python
qt
user-interface
pyqt
qtableview

回答 2

Stack Overflow用户

发布于 2013-03-21 13:20:52

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

这是一个摇摇欲坠的解决方案,但应该有效。

如果使用以下方法修改data()方法:

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

这些项目将不会显示,直到他们被移动到他们的位置(它为我工作)。

票数 2
EN

Stack Overflow用户

发布于 2013-03-22 18:11:44

QTableView 只为其视口中的项向模型请求数据,因此数据的大小不会真正影响速度。因为您已经对 QAbstractListModel 进行了子类化,所以您可以重新实现它,在初始化时只返回一小部分行,并修改它的 canFetchMore 方法,以便在未显示记录总数时返回 True 。尽管在数据大小的情况下,您可能想考虑创建一个数据库,而不是使用 QSqlQueryModel 或 QSqlTableModel ,但它们都是在256个组中延迟加载的。

要获得更流畅的项目负载,您可以连接到 valueChanged 信号的 QTableView.verticalScrollBar() ,并且取决于它的 value 和 maximum 之间的区别,有如下所示:

while xCondition:
   if self.model.canFetchMore():
      self.model.fetchMore()

使用 setIndexWidget 会大大降低应用程序的速度。您可以使用 QItemDelegate 并自定义它的 paint 方法来显示按钮,如下所示:

class MyItemDelegate(QtGui.QItemDelegate):
    def __init__(self, parent=None):
        super(MyItemDelegate, self).__init__(parent)
    def paint(self, painter, option, index):
        text = index.model().data(index, QtCore.Qt.DisplayRole).toString()
        pushButton = QtGui.QPushButton()
        pushButton.setText(text)
        pushButton.setGeometry(option.rect)
 
推荐文章
气势凌人的稀饭  ·  SparkSQL一行转多行 一列变多列 多行转一行-CSDN博客
4 月前
谦虚好学的铁板烧  ·  Indexer errors and warnings - Azure AI Search | Microsoft Learn
11 月前
含蓄的铁板烧  ·  BeanDefinitionOverrideException (Spring Framework 6.1.10 API)
1 年前
留胡子的汤圆  ·  VBA-新建工作簿_新建vba_交小通的博客-CSDN博客
2 年前
文雅的领带  ·  根据Cron表达式获取近几次任务执行时间(Spring + Quartz) - 简书
2 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号