PyQt 更新界面 [英] PyQt update gui

查看:54
本文介绍了PyQt 更新界面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

这条线有问题.您正在线程中实例化一个看起来像小部件的类.这是错误的.您不应该在不同的线程中使用 GUI 元素.所有与 GUI 相关的代码都应该与事件循环在同一线程中运行.

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. All GUI related code should run in the same thread with the event loop.

上面这行在设计上也是错误的.您从线程发出自定义信号,这是一个好方法.但是处理这个信号的对象应该是拥有/创建线程的对象,即你的MainWindow

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

您也不保留对线程实例的引用.您在方法中创建它,但它是本地的.所以它会被垃圾收集,你可能会看到一个警告,它在完成之前被删除了.

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

这篇关于PyQt 更新界面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆