我在下面的代码中有一个像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
  
  show2 1.3125648498535156

最佳答案

区别在于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-based model的数据库。

关于python - 为什么QListView比QListWidget慢?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57443990/

10-12 19:33