【问题标题】:Python PyQt5 signals & slotsPython PyQt5 信号和插槽
【发布时间】:2013-10-17 13:23:28
【问题描述】:

我在将新的 pyqt5 signals and slots 应用到脚本中时遇到了一些问题,该脚本的目的是测试/调用我一直试图解决的另一个问题,GUI 冻结/崩溃......目的是一旦这些信号并且插槽正常运行,GUI 在运行时 +/- 30 秒后不会崩溃,并且会继续计数直到时间结束。我提供了一个 pyqt4 示例,尽管有一个 pyqt5 解决方案会很棒。谢谢:)

from time import sleep
import os
from PyQt4 import QtCore, QtGui, uic
from PyQt4.QtGui import * 
import random
import os
import time


class Cr(QtCore.QThread):
    def __init__(self):
        QtCore.QThread.__init__(self)
    def run(self):

        while True:
            rndInt = random.randint(1, 100000)
            timesleep = random.random()
            time.sleep(timesleep)
            for i in range(120):
                self.emit(QtCore.SIGNAL('host_UP'), 'foo' + str(rndInt), i)
                QtGui.QApplication.processEvents()


class Main_Window(QWidget):

    def __init__(self, *args): 
        QWidget.__init__(self, *args)
        self.relativePath = os.path.dirname(sys.argv[0])

        self.Main_Window = uic.loadUi("Main_Window.ui", self)
        self.Main_Window.show()
        self.Main_Window.move(790, 300)

        self.GU = []
        ProgressThreads = self.printThreads
        self.details_label = []
        for i in range(120):
            self.details_label.insert(i, 0)
            self.details_label[i] = QLabel(" ")
            ProgressThreads.addWidget(self.details_label[i])
            ProgressThreads.addSpacing(6)
            self.details_label[i].setText(Tools.Trim.Short('Idle', 7))
            self.GU.insert(i, Cr())
            self.GU[i].start()

        self.connect(self.GU, QtCore.SIGNAL("host_UP"), self.UpdateHost)


    def UpdateHost(self, str1, pos1):
        self.details_label[pos1].setText(str1)


class guiUpdate():
    def GUI_main(self):
        self.GUI = GUI



if __name__ == "__main__": 
    app = QApplication(sys.argv)
    guiUpdate.GUI_main.GUI = Main_Window()
    sys.exit(app.exec_())

感谢您的帮助:)

更新 下面的脚本是上面脚本的一个希望正确的 PyQt5 版本。但是,崩溃和“无响应”消息的问题仍未解决

from time import sleep
import os
from PyQt5 import QtCore, QtGui, uic
from PyQt5.QtWidgets import *
from PyQt5.QtCore import QObject, pyqtSignal
import random
import os
import time
import Tools
import sys


class Cr(QtCore.QThread):
    def __init__(self, sam):
        QtCore.QThread.__init__(self)
        self.sam = sam

    def run(self):

        while True:
            rndInt = random.randint(1, 100000)
            timesleep = random.random()
            time.sleep(timesleep)
            for i in range(5):
                #time.sleep(1)

                self.sam.connect_and_emit_trigger('foo' + str(rndInt), i)
                #self.emit(QtCore.SIGNAL('host_UP'), 'foo' + str(rndInt), i)
                #QtGui.QApplication.processEvents()


class Main_Window(QWidget):

    def __init__(self, *args): 
        QWidget.__init__(self, *args)
        self.relativePath = os.path.dirname(sys.argv[0])

        self.Main_Window = uic.loadUi("Main_Window.ui", self)
        self.Main_Window.show()
        self.Main_Window.move(790, 300)

        sam = Foo()


        self.GU = []
        ProgressThreads = self.ProgressThreads
        self.details_label = []
        for i in range(5):
            self.details_label.insert(i, 0)
            self.details_label[i] = QLabel(" ")
            ProgressThreads.addWidget(self.details_label[i])
            ProgressThreads.addSpacing(6)
            self.details_label[i].setText(Tools.Trim.Short('Idle', 7))
            self.GU.insert(i, Cr(sam))
            self.GU[i].start()


class Foo(QObject):
    # Define a new signal called 'trigger' that has no arguments.
    trigger = pyqtSignal()
    def connect_and_emit_trigger(self, str, i):
        self.str = str
        self.i = i

        self.trigger.connect(self.handle_trigger)
        self.trigger.emit()

    def handle_trigger(self):
        guiUpdate.GUI_main.GUI.details_label[self.i].setText(self.str)




class guiUpdate():
    def GUI_main(self):
        self.GUI = GUI



if __name__ == "__main__": 
    app = QApplication(sys.argv)
    guiUpdate.GUI_main.GUI = Main_Window()
    sys.exit(app.exec_())

【问题讨论】:

  • 可以附上Main_Window.ui文件吗?

标签: python python-3.x signals pyqt4 pyqt5


【解决方案1】:

使用线程的新推荐方法(也是我得到最好结果的方法)是使用moveToThread(),而不是直接继承 QThread。简而言之:

  1. 编写一个 QObject 子类来完成实际工作(我们称之为 QMyWorker)。这可能看起来有点像您现有的 qthread 子类,带有 start()run() 方法等。

  2. 创建 QMyWorker 的无父实例

  3. 创建 QThread 的无父实例

  4. 使用QMyWorker.moveToThread(your_thread_instance)(我记着,仔细检查文档中的API)。

  5. 致电您的QMyWorker.start()

这种方法对我来说适用于很长的工作(4GB 文件等)。

【讨论】:

    【解决方案2】:

    我使用了 QThreadPool,QRunnable 与 worker 一起使用,可以让每个线程的 worker 更多。 很好的例子,这里有解释 https://martinfitzpatrick.name/article/multithreading-pyqt-applications-with-qthreadpool/

    我的 PYQT5 也冻结了,现在我通过打印时间戳对其进行微调

    【讨论】:

      猜你喜欢
      • 2013-10-08
      • 2019-04-20
      • 2019-04-15
      • 1970-01-01
      • 1970-01-01
      • 2013-07-08
      • 2016-07-17
      • 1970-01-01
      相关资源
      最近更新 更多