PySide QThread и QProgressBar

Я новичок в программировании графического интерфейса с помощью PySide и в графическом интерфейсе Python в целом. Я пытаюсь установить значение индикатора выполнения с помощью потока, но это не работает, и эти ошибки продолжают появляться:

 QPixmap: It is not safe to use pixmaps outside the GUI thread 

or

 QWidget::repaint: Recursive repaint detected 

И программа вылетает внезапно, особенно когда я пытаюсь взаимодействовать с другим виджетом в графическом интерфейсе.


Следующее не является фактическим кодом, это всего лишь симуляция того, что я хотел сделать:

from PySide.QtGui import *
from PySide.QtCore import *​​
import os, time, platform, sys
class main(QDialog):
    def __init__(self, parent = None):
        super(main, self).__init__(parent)
        self.resize(300, 100)
        self.setMinimumSize(QSize(300, 100))
        self.setMaximumSize(QSize(300, 100))
        self.setWindowTitle("Test")
        self.buttonStart = QPushButton("Start")
        self.progressBar = QProgressBar()
        self.gridLayout = QGridLayout(self)
        self.setLayout(self.gridLayout)
        self.gridLayout.addWidget(self.progressBar, 0, 0, 1, 1)
        self.gridLayout.addWidget(self.buttonStart, 0, 1, 1, 1)
        self.connect(self.buttonStart, SIGNAL("clicked()"), self.startProgress)
        self.genericThread = GenericThread(self.test)
    def startProgress(self):
        self.genericThread.start()
    def test(self):
        print "started"
        for i in range(100):
            time.sleep(0.3)
            print i
            self.progressBar.setValue(i)
        print "done"
class GenericThread(QThread):
    def __init__(self, function, *args, **kwargs):
        QThread.__init__(self)
        self.function = function
        self.args = args
        self.kwargs = kwargs
    def run(self):
        self.function(*self.args,**self.kwargs)
        return
app = QApplication(sys.argv)
start = main()
start.show()
app.exec_()

Итак, GenericThread должен запускать любую функцию, переданную ему в потоке, вместо того, чтобы создавать поток для каждой функции. Я знаю, что мне следует использовать сигналы, чтобы поток изменял виджет в потоке графического интерфейса пользователя, но на самом деле мне не удалось применить это с этим классом потока. Я попытался добавить сигнал в тестовую функцию и подключить его к основному классу, но ничего не вышло.

И что я должен делать? Я не хочу изменять класс потока GenericThread, так как в фактическом коде есть много функций, которые необходимо запускать в отдельных потоках, и в то же время мне нужно показать пользователю прогресс потока.


person Dee Taha    schedule 24.06.2013    source источник


Ответы (1)


Используйте сигнал для потока графического интерфейса, чтобы он обновил индикатор выполнения и / или нарисовал Pixmap.

И когда вы подключаете этот сигнал, убедитесь, что вы указали ему использовать Qt::QueuedConnection вместо Qt::AutoConnection.

http://doc.qt.io/qt-4.8/qt.html#ConnectionType-enum

http://doc.qt.io/qt-4.8/qobject.html#connect

http://doc.qt.io/qt-4.8/qcoreapplication.html#processEvents

Надеюсь, это поможет.

person phyatt    schedule 24.06.2013