【问题标题】:PyQt update guiPyQt 更新界面
【发布时间】:2012-05-22 11:20:53
【问题描述】:

我正在尝试通过 PyQt 中的 QThread 更新 Qt GUI 对象中的文本,但我只收到错误 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()

【问题讨论】:

    标签: python pyqt


    【解决方案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_())
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-17
      • 1970-01-01
      • 2014-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多