2015-02-24 3 views
0

Je suis actuellement en train de tenter de créer une application de minuteur fileté en utilisant PyQt. Simple, non? Je le pensais aussi. Cependant, après avoir passé toute la journée à essayer de comprendre ce qui ne va pas, je n'en ai absolument aucune idée. Dans mon immense entêtement, j'ai refusé d'abandonner ce qui devait être un projet de 15 minutes.QThread Mystère Erreur

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_()) 

Et l'erreur:

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

D'après ce que j'ai lu, ces deux erreurs ont quelque chose à voir avec la collecte des ordures, mais je n'ai absolument aucune idée comment les réparer.

Merci!

Répondre

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


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

Ici, vous connectez un signal à un emplacement. Le paramètre transmis à l'emplacement est le button state, qui correspond à bool. Donc self est True dans votre cas.

+0

En outre, QThread.start() renvoie None et le thread n'est pas affecté à une variable, ce qui explique pourquoi il est détruit. Honnêtement, il y a tellement de problèmes avec ce code qu'il est difficile de savoir par où commencer. –

+0

Donne-moi une pause, c'est la première fois que j'utilise PyQT. D'ailleurs, la même chose s'est produite quand j'ai eu deux déclarations séparées. @warvariuc J'ai essayé cela, maintenant je viens d'obtenir l'erreur "QThread: Détruit pendant que le fil est encore en cours". –

+0

@DarthVader Je sais que vous avez d'autres problèmes avec ce code, mais j'ai répondu à votre question principale. Stackoverflow essaie de répondre à une question à la fois, sinon vous finissez par discuter de code au lieu de répondre à des questions petites et bien définies. Vous pouvez discuter de votre code [ici] (http://chat.stackoverflow.com/rooms/6/python) – warvariuc

1

Votre code comporte trois problèmes. Vous devez résoudre le premier avant de pouvoir résoudre le troisième (la deuxième question devrait disparaître une fois que vous résolvez le premier numéro)

  1. Vous êtes fonctions et méthodes confuses. Je peux le dire parce que vous avez une fonction appelée start, mais le fait que le premier argument dans la signature de la fonction est appelé self indique que vous voulez que ce soit une méthode d'un objet. Vous pourriez vouloir lire this pour une bonne explication de la différence entre une fonction et une méthode.

  2. En conséquence du point précédent, et du fait que le signal QPushButton.clicked émet un booléen, signifie que lorsque start est appelé, la variable self contient True (au lieu d'une référence à l'instance d'une classe (autrement connu comme un objet) - qui est ce qui se passerait est start était une méthode plutôt qu'une fonction)

  3. la ligne self.t = Timer().start() effectue les opérations suivantes:

    • Timer() crée un en position de la classe Timer
    • La méthode start de cette instance est appelée
    • La valeur de retour de la méthode start() est stockée dans self.t (nous ignorons ici le problème self n'est pas une référence à un objet).

    Ce que vous voulez faire est de créer à la place de l'instance Timer et l'affecter à self.t. Puis appelez start() sur self.t. Par exemple:

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

    Cela garantit que l'objet Timer est enregistré quelque part et ne reçoit pas les déchets collectés.

+0

J'ai eu la méthode start enfermé dans une classe de conteneur, en espérant qu'une instance de classe stockant la variable pourrait l'empêcher de être ramassé des ordures. Ce n'est pas le cas, alors j'ai supprimé la classe, mais j'ai oublié de m'enlever. J'ai modifié l'op pour refléter ce que mon code ressemble maintenant, et l'erreur conséquente. –

+0

@DarthVader Pouvez-vous tenter d'adresser le point 1 de mon post en replaçant la méthode 'start' dans une classe, en créant une instance de cette classe et en connectant le signal' clicked' du bouton à la méthode 'start' qui appartient à l'instance. Si vous voyez toujours le thread étant collecté dans cette situation, votre objet conteneur est peut-être en train d'être récupéré. De toute façon, c'est le noeud du problème et j'ai besoin de voir ce que vous avez essayé avec les classes pour diagnostiquer/expliquer pourquoi cela ne fonctionne pas. –