为什么 QListView 比 QListWidget 慢?

Why is QListView slower than 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_()

我电脑上的输出是:

show1 5.374950885772705
show2 1.3125648498535156

区别在于列表小部件使用 C++ 创建所有项目,而列表视图必须在您的自定义模型中进行数百万次 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

所以在那种情况下,字符串列表模型比列表小部件快四倍以上。但是,如果您的实际需求比这更复杂,您可能应该考虑使用具有 sql-based model.

的数据库