PyQt обновление графического интерфейса

Я пытаюсь обновить текст в объекте Qt GUI черезQThread в PyQt, но я просто получаю ошибкуQPixmap: It is not safe to use pixmaps outside the GUI thread, то это вылетает. Я был бы очень признателен за любую помощь, спасибо.

class MainWindow(QMainWindow, Ui_MainWindow):

    def __init__(self, parent = None):
        QMainWindow.__init__(self, parent)
        self.setupUi(self)
        self.output = Output()

    def __del__ (self):
        self.ui = None

    @pyqtSignature("")
    def on_goBtn_released(self):
        threadnum = 1
        #start threads
        for x in xrange(threadnum):
            thread = TheThread() 
            thread.start()


class Output(QWidget, Ui_Output):

    def __init__(self, parent = None):
        QWidget.__init__(self, parent)
        self.setupUi(self)
        self.ui = Ui_Output
        self.show()

    def main(self):
        self.textBrowser.append("sdgsdgsgsg dsgdsg dsgds gsdf")



class TheThread(QtCore.QThread):

    trigger = pyqtSignal()

    def __init__(self):
        QtCore.QThread.__init__(self)

    def __del__(self):
        self.wait()

    def run(self):
        self.trigger.connect(Output().main())
        self.trigger.emit()

Ответы на вопрос(1)

Решение Вопроса
self.trigger.connect(Output().main())

Эта линия проблематична. Вы создаете экземпляр класса в потоке, который выглядит как виджет. Это не верно. Вы не должны использовать элементы GUI в другом потоке. Весь код, связанный с GUI, должен выполняться в одном потоке с циклом событий.

Вышеприведенная линия также неверна с точки зрения дизайна. Вы излучаете пользовательский сигнал из вашей темы, и это хороший способ. Но объект для обработки этого сигнала должен быть тем, кто владеет / создает поток, а именно вашMainWindow

Вы также не сохраняете ссылку на свой экземпляр потока. Вы создаете это в методе, но это локально. Так что это будет сборка мусора, вы, вероятно, увидите предупреждение о том, что он удален до его завершения.

Вот минимальный рабочий пример:

import sys
from PyQt4 import QtGui, QtCore
import time
import random


class MyThread(QtCore.QThread):
    trigger = QtCore.pyqtSignal(int)

    def __init__(self, parent=None):
        super(MyThread, self).__init__(parent)

    def setup(self, thread_no):
        self.thread_no = thread_no

    def run(self):
        time.sleep(random.random()*5)  # random sleep to imitate working
        self.trigger.emit(self.thread_no)


class Main(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(Main, self).__init__(parent)
        self.text_area = QtGui.QTextBrowser()
        self.thread_button = QtGui.QPushButton('Start threads')
        self.thread_button.clicked.connect(self.start_threads)

        central_widget = QtGui.QWidget()
        central_layout = QtGui.QHBoxLayout()
        central_layout.addWidget(self.text_area)
        central_layout.addWidget(self.thread_button)
        central_widget.setLayout(central_layout)
        self.setCentralWidget(central_widget)

    def start_threads(self):
        self.threads = []              # this will keep a reference to threads
        for i in range(10):
            thread = MyThread(self)    # create a thread
            thread.trigger.connect(self.update_text)  # connect to it's signal
            thread.setup(i)            # just setting up a parameter
            thread.start()             # start the thread
            self.threads.append(thread) # keep a reference

    def update_text(self, thread_no):
        self.text_area.append('thread # %d finished' % thread_no)

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)

    mainwindow = Main()
    mainwindow.show()

    sys.exit(app.exec_())
 amba8822 мая 2012 г., 23:50
Это сработало отлично, большое спасибо!

Ваш ответ на вопрос