2015-02-24 183 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