QThread神秘错误

时间:2015-02-24 08:44:22

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

我目前正在尝试使用PyQt创建一个线程计时器应用程序。简单吧?我也是这么想的。然而,在花了一整天试图弄清楚出了什么问题之后,我仍然完全不知道。在我所有的巨大顽固中,我拒绝放弃应该是15分钟的项目。

Heres mah codez:

__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

从我读过的内容来看,这两个错误与垃圾收集有关,但我完全不知道如何修复它们。

谢谢!

2 个答案:

答案 0 :(得分:1)

您的代码有三个问题。在解决第三个问题之前,你需要解决第一个问题(第二个问题应该在解决第一个问题后消失)

  1. 您的功能和方法令人困惑。我可以告诉你,因为你有一个名为start的函数,但是函数签名中的第一个参数被称为self这一事实表明你希望它是一个对象的方法。您可能需要阅读this以获得有关函数和方法之间差异的详细说明。

  2. 由于前一点以及QPushButton.clicked信号发出布尔值这一事实,意味着当调用start时,self变量包含{{ 1}}(而不是对类实例的引用(也称为对象) - 会发生的是True是方法而不是函数)

  3. start行执行以下操作:

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

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

    self.t

    这可确保self.t = Timer() self.t.start() 对象保存在某处,并且不会收集垃圾。

答案 1 :(得分:0)

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


...    
    ui.startButton.clicked.connect(start)

这里是将信号连接到插槽。传递给广告位的参数是button state,即bool。因此,self在您的案例中为True