python qt pyside listbox print line by line

2019-03-04 06:06发布

问题:

This piece of code (python3/Qt/PySide) is doing print line by line in ListBox (or something) when some job is done. Problem is lines are not refreshed when print is done. Some piece of wisdom, please.

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_())

回答1:

The functions like sleep() block the GUI loop causing it to not be able to update the elements it manages, in addition to observing that in the load you can not interact with the GUI, such as changing its size. What you should do is look for some equivalent and in the case of Qt you can do a QEventLoop with a QTimer:

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

The following method is equivalent to time.sleep(delay):

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


标签: python qt pyside