2013-03-29 22 views
11

Mam problem z QThreads w python. Chcę zmienić kolor tła etykiety. Ale Moja awaria aplikacji podczas uruchamiania. „QThread: Zniszczony podczas gdy wątek jest nadal działa”QThread: Destroyed while thread nadal działa

class MainWindow(QMainWindow): 
     def __init__(self): 
      QMainWindow.__init__(self) 
      self.ui = Ui_MainWindow() 
      self.ui.setupUi(self) 

      statusTh = statusThread(self) 
      self.connect(statusTh, SIGNAL('setStatus'), self.st, Qt.QueuedConnection) 
      statusTh.start() 

     def st(self): 
      if self.status == 'ON': 
       self.ui.label.setStyleSheet('background-color:green') 
      else: 
       self.ui.label.setStyleSheet('background-color:red') 

    class statusThread(QThread): 
     def __init__(self, mw): 
      super(statusThread, self).__init__() 

     def run(self): 
      while True: 
       time.sleep(1) 
       self.emit(SIGNAL('setStatus')) 

    if __name__ == "__main__": 
     app = QApplication(sys.argv) 
     main_window = MainWindow() 
     main_window.show() 
     sys.exit(app.exec_()) 
+0

Rozwiązanie Qt stylu, przypisać okna głównego jako 'rodzica statusTh', a mianowicie,' super (statusThread, self) .__ init __ (mw) '. – nymk

+0

Bardzo dużo. Działa teraz –

+0

Tylko dla informacji, jest to w zasadzie to samo: w tym przypadku rodzic zachowa odwołanie do instancji wątku i dlatego nie będzie zbierane śmieci. – rainer

Odpowiedz

20

Nie jesteś przechowywania odniesienie do wątku po to został stworzony, co oznacza, że ​​będzie to śmieci zebrane (tj zniszczone.) Jakiś czas po program pozostawia MainWindow s __init__. Trzeba przechowywać co najmniej tak długo, jak wątek jest uruchomiony, na przykład użyć self.statusTh:

self.statusTh = statusThread(self) 
self.connect(self.statusTh, SIGNAL('setStatus'), self.st, Qt.QueuedConnection) 
self.statusTh.start() 
+0

Przepraszam, jestem nowicjuszem w Pythonie. Nie mogę zrozumieć. Jak mogę zapisać referencję? –

+5

Tak jak napisałem w mojej odpowiedzi. Przez przypisanie instancji 'statusThread (self) do zmiennej lokalnej (tj. Bez' self' przed nią), będzie ona zbiorem śmieci, gdy zmienna lokalna wyjdzie poza zakres (co robi gdy '__init__' z 'MainWindow' jest zakończony). Jeśli przechowujesz referencję w zmiennej członkowskiej klasy 'MainWindow' (tj. Z' self 'przed nią), to nie wyjdzie poza zakres, gdy zrobi się' __init__', co spowoduje, że obiekt wątku nie będzie śmieci zebrane. – rainer

+0

Dałbym 10 przegranych! Dobra odpowiedź - zaoszczędziło mi wiele czasu i żałoby! Myślę, że powinieneś przenieść tekst komentarza również do odpowiedzi. –