如何提高PyQt4 QListWidget的效率

时间:2012-10-26 15:52:04

标签: python pyqt4 qlistwidget

我有以下代码,我想知道是否有办法提高效率。 setCurrentItem()和scrollToItem()函数似乎可以大大减慢进程。此外,我希望看到列表中的项目在循环完成后立即添加而不是全部添加。任何帮助或讨论都会受到很大的影响。

import sys
from math import *
#from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import (Qt, SIGNAL, QSize)
from PyQt4.QtGui import (QApplication, QDialog, QLabel, QListWidget, QListWidgetItem,     QPushButton, QScrollArea, QTextDocument, QVBoxLayout)
from time import localtime, strftime
import time

class LogDlg(QDialog):

  def __init__(self, parent=None):
    super(LogDlg, self).__init__(parent)
    self.resize(450, 380)

    self.log1 = QListWidget()
    self.log2 = QListWidget()
    lbl = QLabel()
    lbl_2 = QLabel()
    lbl.setText("Communications Log")
    lbl_2.setText("Command/Data Log")
    self.pushButton = QPushButton()
    self.pushButton.setMaximumSize(QSize(110, 24))
    self.pushButton.setObjectName("pushButton")

    self.pushbutton = QPushButton
    self.pushButton.setText("Start Log Loop")
    layout = QVBoxLayout()
    layout.addWidget(self.pushButton)
    layout.addWidget(lbl)
    layout.addWidget(self.log1)
    layout.addWidget(lbl_2)
    layout.addWidget(self.log2)
    self.setLayout(layout)
    self.setWindowTitle("Transaction Logs")
    self.connect(self.pushButton,SIGNAL("clicked()"),self.logLoop) 
    self.time = time.time()

  def logLoop(self):
    for i in range(1000):
        print i
        self.addLog("This is a test","c",True)      

  def timeStamp(self):
    now = time.time()
    localtime = time.localtime(now)
    milliseconds = '%02d' % int((now - int(now)) * 100)
    val = time.strftime('%H:%M:%S.', localtime) + milliseconds
    return val

  def clearUi(self):
    self.log1.clear()
    self.log2.clear()

  def addLog(self, data, type="c", ts=False):
#        pass
    t = self.timeStamp()
    if ts == True:
        data = t + " " + data
    if type == "c":
        self.listItem1 = QListWidgetItem()
        self.listItem1.setText(data)
        self.log1.addItem(self.listItem1)
#        self.log1.scrollToItem(self.listItem1)
        self.log1.setCurrentItem(self.listItem1)


    elif type == "d":
        self.listItem2 = QListWidgetItem()
        self.listItem2.setText(data)
        self.log2.addItem(self.listItem2)
#        self.log2.scrollToItem(self.listItem2)
        self.log2.setCurrentItem(self.listItem2)


app = QApplication(sys.argv)
form = LogDlg()
form.open()
app.exec_()

1 个答案:

答案 0 :(得分:1)

您的问题与.scrollToItem.setCurrentItem没有任何关系。 logLoop方法中的循环不会让Qt事件循环更新任何东西。解决这个问题的一种方法是,让Qt有机会用QApplication.processEvents()更新GUI。因此,如果您修改logLoop如下,您应该看到添加的项目:

  def logLoop(self):
    for i in range(1000):
        print i
        self.addLog("This is a test","c",True)
        QApplication.processEvents()

这在某种程度上是有用的。如果processEvents之间的时间足够小,您将获得响应式用户界面。但是一旦事情变得更复杂并且每个段完成任务的时间增加,您将需要将该段代码委托给单独的线程(QThread),以保持GUI响应。

另一个问题是,一旦QListWidget中有大量项目,事情就会变慢。您可能会注意到添加第25项比第925项更快。这是因为QListWidget(或QTableWidget / QTreeWidget)不能很好地扩展。如果您要拥有大量项目,则应该选择模型/视图框架(QListView / QTableView / QTreeView)。