【问题标题】:QThread Mystery ErrorQThread 神秘错误
【发布时间】:2015-02-24 08:44:22
【问题描述】:

我目前正在尝试使用 PyQt 创建一个线程计时器应用程序。很简单,对吧?我也是那么想的。然而,在花了一整天试图弄清楚出了什么问题之后,我仍然完全不知道。尽管我非常固执,但我拒绝放弃本应是 15 分钟的项目。

这里是麻麻编码:

__author__ = 'Darth Vader'

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QMessageBox, QApplication, QDialog
from PyQt5.QtCore import QThread
from timerui import Ui_Form
import sys
import ctypes
import time
import threading

class Timer(QThread):
    def makeNoise(self):
        pass

    def run(self):

        self.ui.startButton.setStyleSheet('''QPushButton {color: red;font: bold 15px;}''')

        self.ui.startButton.setEnabled(False)

        self.hour = int(self.ui.spinBoxHrs.value())
        self.min = int(self.ui.spinBoxMin.value())
        self.sec = int(self.ui.spinBoxSec.value())

        if self.sec:
            self.countSec = self.sec
        elif self.min and not self.sec:
            self.countSec = 60
            self.min -= 1
        elif self.hour and not self.min and not self.sec:
            self.min = 59
            self.countSec = 60
        print(self.countSec)
        while self.countSec or self.hour or self.min:
            if not self.countSec and self.min:
                self.min -= 1
                self.countSec = 60
            elif not self.countSec and not self.min and self.hour:
                self.hour -= 1
                self.min = 59
                self.sec = 60
            elif not self.countSec and not self.min and not self.hour:
                self.makeNoise()
                break

            time.sleep(1)
            self.countSec -= 1
            self.ui.startButton.setText("%dh %dm %ds" % (self.hour, self.min, self.sec))

        self.ui.startButton.setEnabled(True)
        self.ui.startButton.setText("Start")
        self.ui.startButton.setStyleSheet('QPushButton{}')

    def setup(self, gui):
        self.ui = gui

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


def start():
    t = Timer()
    t.start()




if __name__ == '__main__':
    myappid = u'org.ayoung.timer'
    ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)

    app = QApplication(sys.argv)
    app.setWindowIcon(QtGui.QIcon('res/favicon.png'))

    window = QDialog()

    ui = Ui_Form()
    ui.setupUi(window)
    ui.startButton.clicked.connect(start)

    window.show()
    sys.exit(app.exec_())

还有错误:

QThread: Destroyed while thread is still running
QMutex: destroying locked mutex

根据我的阅读,这两个错误与垃圾收集有关,但我完全不知道如何修复它们。

谢谢!

【问题讨论】:

    标签: python multithreading python-3.x pyqt pyqt5


    【解决方案1】:

    您的代码存在三个问题。您需要先解决第一个问题,然后才能解决第三个问题(解决第一个问题后,第二个问题应该会消失)

    1. 您混淆了函数和方法。我可以这么说是因为您有一个名为start 的函数,但函数签名中的第一个参数称为self 的事实表明您希望它是一个对象的方法。您可能想阅读 this 以获得对函数和方法之间区别的一个很好的解释。

    2. 1234563到一个类的实例(也称为对象)——这就是start是一个方法而不是一个函数)
    3. self.t = Timer().start() 行执行以下操作:

      • Timer() 创建 Timer 类的实例
      • 调用此实例的start方法
      • start() 方法的返回值存储在self.t 中(这里我们忽略了self 不是对对象的引用的问题)。

      您要做的是创建Timer 的实例并将其分配给self.t。然后在self.t 上致电start()。例如:

      self.t = Timer()
      self.t.start()
      

      这可确保Timer 对象保存在某处并且不会被垃圾回收。

    【讨论】:

    • 我将 start 方法封装在一个容器类中,希望有一个存储变量的类实例可以防止它被垃圾收集。它没有,所以我删除了课程,但忘记删除 self.我已经编辑了操作以反映我的代码现在的样子,以及随之而来的错误。
    • @DarthVader 您能否尝试通过将start 方法放回类中,创建该类的实例并将按钮的clicked 信号连接到属于实例的start 方法。如果您仍然看到在这种情况下线程正在被垃圾收集,那么您的容器对象可能正在被垃圾收集。无论哪种方式,这都是问题的症结所在,我需要看看你用类尝试了什么来诊断/解释它为什么不起作用。
    【解决方案2】:
    def start(self):
        self.t = Timer().start()
    
    
    ...    
        ui.startButton.clicked.connect(start)
    

    在这里,您将信号连接到插槽。传递给槽的参数是button state,也就是bool。所以self 在你的情况下是True

    【讨论】:

    • 除此之外,QThread.start() 返回 None,并且线程没有被分配给变量,这就是它被破坏的原因。老实说,这段代码有很多问题,很难知道从哪里开始。
    • 休息一下,这是我第一次使用 PyQT。此外,当我有两个单独的陈述时,也发生了同样的事情。 @warvariuc 试过了,现在我只得到“QThread:在线程仍在运行时被销毁”错误。
    • @DarthVader 我知道您对此代码还有其他问题,但我回答了您的主要问题。 Stackoverflow 尝试一次回答一个问题,否则您最终会讨论代码而不是回答小而明确的问题。你可以讨论你的代码here
    猜你喜欢
    • 2015-03-13
    • 2017-04-20
    • 2014-06-07
    • 1970-01-01
    • 1970-01-01
    • 2011-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多