简体   繁体   English

PyQt更新gui

[英]PyQt update gui

I'm trying to update the text in a Qt GUI object via a QThread in PyQt but I just get the error QPixmap: It is not safe to use pixmaps outside the GUI thread , then it crashes. 我正在尝试通过PyQt中的QThread更新Qt GUI对象中的文本,但我只是得到错误QPixmap: It is not safe to use pixmaps outside the GUI thread ,然后它崩溃了。 I would really appreciate any help, thanks. 我真的很感激任何帮助,谢谢。

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()
self.trigger.connect(Output().main())

This line is problematic. 这条线存在问题。 You are instantiating a class in the thread which looks like a widget. 您正在线程中实例化一个类似于小部件的类。 This is wrong. 这是错的。 You shouldn't use GUI elements in a different thread. 您不应该在不同的线程中使用GUI元素。 All GUI related code should run in the same thread with the event loop. 所有与GUI相关的代码都应该与事件循环在同一个线程中运行。

The above line is also wrong in terms of design. 以上这条线在设计上也是错误的。 You emit a custom signal from your thread and this is a good way. 您从线程发出自定义信号,这是一个好方法。 But the object to process this signal should be the one that owns/creates the thread, namely your MainWindow 但处理此信号的对象应该是拥有/创建线程的对象,即您的MainWindow

You also don't keep a reference to your thread instance. 您也不会保留对线程实例的引用。 You create it in a method, but it is local. 您可以在方法中创建它,但它是本地的。 So it'll be garbage collected, you probably would see a warning that it is deleted before it is finished. 所以它将被垃圾收集,你可能会看到它在完成之前被删除的警告。

Here is a minimal working example: 这是一个最小的工作示例:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM