首页 > 解决方案 > 为什么 QListView 比 QListWidget 慢?

问题描述

a在下面的代码中有一个变量,它有很多数据。我想在 QListWidget 或 QListView 中显示这些数据。我一直在使用QListWidget,但是它比QListView消耗更多的内存,所以我选择了QListView。

但是在下面的代码中,显示QListView的速度比QListWidget慢。有没有办法解决这个问题?

from PyQt5 import QtCore, QtGui, QtWidgets

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import time
app=QApplication([])
n=1000000

a=[]
for i in range(n):
     a.append('asfghjkg'+str(i))
class TodoModel(QtCore.QAbstractListModel):
    def __init__(self, todos=None):
        super(TodoModel, self).__init__()
        self.todos = todos or []

    def data(self, index, role):
        if role == Qt.DisplayRole:
            # See below for the data structure.
            return self.todos[index.row()]
            # Return the todo text only.

    def rowCount(self, index): 
        return len(self.todos)    


todos = a
model = TodoModel(todos)

t=time.time()
win1=QListView()
win1.setUniformItemSizes(True)
win1.setViewMode(1)
win1.setWrapping(False)
win1.setFlow(QListWidget.TopToBottom)
win1.setModel(model)
win1.show()
print('show1',time.time()-t)
t=time.time()
win2=QListWidget()
win2.setUniformItemSizes(True)
win2.addItems(a)
win2.show()
print('show2',time.time()-t)
app.exec_()

我的电脑上的输出是:

显示1 5.374950885772705
显示2 1.3125648498535156

标签: pythonperformancepyqt5qlistwidgetqlistview

解决方案


不同之处在于 list-widget 在 C++ 中创建所有项目,而 list-view 必须在您的自定义模型中进行数百万次 Python 方法调用。扁平的单列树形视图的速度大约是列表视图的两倍——但这仍然比列表小部件慢得多。为了获得更好的性能,您可以尝试实现fetchmore。但这具有滚动速度非常慢的缺点,并且您不能轻松地在列表中导航(例如,直接转到最后一项)。它还使排序和过滤更难实现。

如果您的数据集真的只是一个简单的字符串列表,您可以使用QStringListModel获得更好的性能。这是因为它比 list-widget 使用的基于项目的模型要简单得多(当然,它是用 C++ 实现的,与您的自定义模型不同)。如果我将以下代码添加到您的测试脚本中:

model2 = QStringListModel(todos)
t=time.time()
win3=QListView()
win3.setUniformItemSizes(True)
win3.setViewMode(1)
win3.setWrapping(False)
win3.setFlow(QListWidget.TopToBottom)
win3.setModel(model2)
win3.show()
print('show3',time.time()-t)

我在我的系统上得到这个输出:

show1 2.2652294635772705
show2 0.4205465316772461
show3 0.10054779052734375

因此,在这种情况下,stringlist-model 比 list-widget 快四倍以上。但是,如果您的实际需求比这更复杂,您可能应该考虑使用基于 sql 模型的数据库。


推荐阅读