QThread, der/die niemals schläft

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Hey Leute,

irgendwie sehe ich den Wald vor lauter Bäumen nicht. Im nachfolgenden, ausführbaren Quelltext möchte ich eine While-Schleife (hier soll die lange Arbeit simuliert werden) unterbrechen. Ich bekomme keinerlei Fehlermeldungen. Aber die While-Schleife lässt sich nicht unterbrechen, obwohl die Stop-Schaltfläche über pyqtSignal ordnungsgemäß emittiert. Ich bin mir ziemlich sicher, dass ich eine Kleinigkeit übersehe.

Code: Alles auswählen

from sys import argv

from PyQt4.QtCore import QObject, pyqtSignal, QThread, Qt
 
from PyQt4.QtGui import QDialog, QApplication, QPushButton, \
     QLineEdit, QFormLayout, QTextEdit

class TestTask(QObject):

    def __init__(self, parent=None):
        QObject.__init__(self, parent)

        self._end_loop = True

    def init_object(self):
        while self._end_loop:
            print "Sratus", self._end_loop

    def stop(self):
        self._end_loop = False

class Form(QDialog):
    stop_loop = pyqtSignal()
    
    def __init__(self, parent=None):
        QDialog.__init__(self, parent)
        
        self.init_ui()

    def init_ui(self):

       
        self.pushButton_start_loop = QPushButton()
        self.pushButton_start_loop.setText("Start Loop") 

        self.pushButton_stop_loop = QPushButton()
        self.pushButton_stop_loop.setText("Stop Loop")       

        self.pushButton_close = QPushButton()
        self.pushButton_close.setText("Close")
        
        layout = QFormLayout()
        
        layout.addWidget(self.pushButton_start_loop)
        layout.addWidget(self.pushButton_stop_loop)
        layout.addWidget(self.pushButton_close)
        
        self.setLayout(layout)
        self.setWindowTitle("Tes Window")

        self.init_signal_slot_pushButton()

    def start_task(self):
        
         self.task_thread = QThread(self)
         self.task_thread.work = TestTask()
         self.task_thread.work.moveToThread(self.task_thread)
         self.task_thread.started.connect(self.task_thread.work.init_object)
         
         self.stop_loop.connect(self.task_thread.work.stop)

         self.task_thread.finished.connect(self.task_thread.deleteLater)
         
         self.task_thread.start()

    def stop_looping(self):
        self.stop_loop.emit()
                 
    def init_signal_slot_pushButton(self):

        self.pushButton_start_loop.clicked.connect(self.start_task)
        
        self.pushButton_stop_loop.clicked.connect(self.stop_looping)
        
        self.pushButton_close.clicked.connect(self.close)



app = QApplication(argv)
form = Form()
form.show()
app.exec_()
BlackJack

@Sophus: Ich sehe in dem QThread der da läuft keine Hauptschleife (`exec_()`-Aufruf) damit die eingehenden Signale auch verarbeitet werden.

Edit:

Code: Alles auswählen

from sys import argv

from PyQt4.QtCore import QObject, QThread, QTimer, pyqtSignal
from PyQt4.QtGui import qApp, QApplication, QDialog, QPushButton, QVBoxLayout

 
class TestTask(QThread):
 
    def __init__(self, parent=None):
        QThread.__init__(self, parent)
        self.timer = None
 
    def run(self):
        self.timer = QTimer()
        self.timer.timeout.connect(self.on_timeout)
        self.timer.start()
        self.exec_()
 
    def stop(self):
        self.timer.stop()
        self.quit()

    @staticmethod
    def on_timeout():
        print 'Status'
 

class Form(QDialog):
    stop_loop = pyqtSignal()
   
    def __init__(self, parent=None):
        QDialog.__init__(self, parent)
        self.task_thread = None

        self.start_loop_button = QPushButton()
        self.start_loop_button.setText('Start Loop')
 
        self.stop_loop_button = QPushButton()
        self.stop_loop_button.setText('Stop Loop')      
 
        self.close_button = QPushButton()
        self.close_button.setText('Close')
       
        layout = QVBoxLayout()
       
        layout.addWidget(self.start_loop_button)
        layout.addWidget(self.stop_loop_button)
        layout.addWidget(self.close_button)
       
        self.setLayout(layout)
        self.setWindowTitle('Test Window')
 
        self.start_loop_button.clicked.connect(self.start_task)
        self.stop_loop_button.clicked.connect(self.stop_loop.emit)
        self.close_button.clicked.connect(self.close)
 
    def start_task(self):
        self.task_thread = TestTask(self)
        self.stop_loop.connect(self.task_thread.stop)
        self.task_thread.finished.connect(self.task_thread.deleteLater)
        self.task_thread.start()
 

def main():
    app = QApplication(argv)
    form = Form()
    form.show()
    app.exec_()


if __name__ == '__main__':
    main()
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

@BlackJack: Besten dank.
Antworten