python qt pyside listbox逐行打印

python qt pyside listbox print line by line

这段代码(python3/Qt/PySide)在完成某些工作时在列表框(或其他东西)中逐行打印。问题是打印完成后线条没有刷新。请大家多多指教。

import sys
from random import randint
from PySide import QtGui, QtCore
import time

def do_job ():
    time.sleep(randint(1, 8)/10.0)

def work():
    for i in range(14):
        do_job ()
        line = QtGui.QListWidgetItem("did job {}".format(i))
        print (line.text())
        w.lw.addItem(line)

app = QtGui.QApplication(sys.argv)
w = QtGui.QWidget()
w.setGeometry(300, 300, 420, 240)
w.setWindowTitle('Some task')

w.btn1 = QtGui.QPushButton('do job', w)
w.btn1.move(300, 120)
w.btn1.clicked.connect(work)

w.btn2 = QtGui.QPushButton('die', w)
w.btn2.move(300, 180)
w.btn2.clicked.connect(QtCore.QCoreApplication.instance().quit)

w.lw = QtGui.QListWidget(w)
w.lw.move(20, 20)

w.show()
sys.exit(app.exec_())

sleep()这样的函数阻止了GUI循环,导致它无法更新它管理的元素,除了观察到在加载中你不能与GUI交互,比如改变它尺寸。你应该做的是寻找一些等价物,在 Qt 的情况下,你可以用 QTimer:

做一个 QEventLoop
def do_job():
    loop = QtCore.QEventLoop()
    QtCore.QTimer.singleShot(100*randint(1, 8), loop.quit)
    loop.exec_()

下面的方法等同于time.sleep(delay):

def new_sleep(delay):
    loop = QtCore.QEventLoop()
    QtCore.QTimer.singleShot(int(delay*1000), loop.quit)
    loop.exec_()