2015-02-24 133 views
0

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

继承人麻将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 

从我读过,这两个错误是与垃圾收集,但我完全不知道如何解决它们。

谢谢!

回答

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


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

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

+0

除此之外,QThread.start()返回无,并且线程没有被分配给变量,这就是为什么它被销毁。老实说,这个代码有很多错误,很难知道从哪里开始。 – 2015-02-24 09:02:42

+0

给我一个休息时间,这是我第一次使用PyQT。此外,当我有两个单独的陈述时,也发生了同样的事情。 @warvariuc试过了,现在我刚刚得到“QThread:线程仍在运行时被销毁”的错误。 – 2015-02-24 09:25:07

+0

@DarthVader我知道你有这个代码的其他问题,但我回答你的主要问题。 Stackoverflow试图回答一个问题,否则你最终会讨论代码而不是回答小而明确的问题。你可以讨论你的代码[这里](http://chat.stackoverflow.com/rooms/6/python) – warvariuc 2015-02-24 10:10:44

1

您的代码有三个问题。您需要解决的第一个,然后才能解决第三个(一旦你解决了第一个问题的第二个问题应该消失)

  1. 你是混乱的函数和方法。我可以这样说,因为你有一个名为start的函数,但函数签名中的第一个参数叫做self的事实表明你希望它是一个对象的方法。您可能想要阅读this以获得有关函数和方法之间差异的很好解释。

  2. 如前面的点的结果,并且该QPushButton.clicked信号发出一个布尔,事实意味着,当start被调用时,self变量包含True(而不是一类的实例的引用(或称为作为一个对象) - 这是会发生什么事是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对象的地方保存,并没有得到垃圾收集。

+0

我有一个容器类中的启动方法,希望有一个类实例存储变量可能会阻止它被垃圾收集。它没有,所以我删除了班级,但忘了删除自己。我编辑了操作以反映我的代码现在的样子,以及随之而来的错误。 – 2015-02-24 20:28:55

+0

@DarthVader你可以尝试通过将'start'方法放回到类中,创建该类的一个实例,并将该按钮的'clicked'信号连接到属于'start'方法到实例。如果你仍然看到线程在这种情况下被垃圾收集,那么也许你的容器对象被垃圾收集。无论哪种方式,这是问题的关键,我需要看看你用类尝试诊断/解释为什么它不工作。 – 2015-02-25 10:37:37