2016-06-04 9 views
0

Ich baue einen einfachen Geschwindigkeitsleser in Python als Übung. Grundsätzlich ein Spritz Klon.Der einfachste Weg, Pyg4 zu unterbrechen?

Was ist der richtige Weg, um die Funktion printword() zu stoppen, sobald ich es ausgeführt habe? Soll ich es in einen Thread stecken? Mit Threading oder QThread? Ich bin ein bisschen verloren.

#!/usr/bin/env python3 

from time import sleep 

import sys 
from PyQt4 import QtGui, QtCore  

class Fastreader(QtGui.QWidget): 

    def __init__(self): 
     super(Fastreader, self).__init__() 
     self.initUI() 

    def initUI(self): 

     self.le = QtGui.QLineEdit(self) 
     self.le.setAlignment(QtCore.Qt.AlignCenter) 
     self.le.move(20, 20) 

     self.btn = QtGui.QPushButton('Play', self) 
     self.btn.move(20, 50) 
     self.btn.clicked.connect(self.printword) 

     self.btn = QtGui.QPushButton('Stop', self) 
     self.btn.move(120, 50) 

     self.setGeometry(300, 300, 225, 80) 
     self.setWindowTitle('fastreader') 
     self.show() 

    def printword(self): 

     cb = QtGui.QApplication.clipboard() 
     text = cb.text() 

     words_per_minute = 200 

     sleeptime = 60.0/words_per_minute 

     for word in text.split(" "): 
       self.le.setText(word) 
       self.le.repaint() 
       sleep(sleeptime) 

def main(): 

    app = QtGui.QApplication(sys.argv) 
    ex = Fastreader() 
    sys.exit(app.exec_()) 

if __name__ == '__main__': 
    main() 

Vielen Dank!

Antwort

0

Ich würde Timer mit einem Rückruf verwenden, um die Verwendung von Threads oder Schlaf in Qt zu vermeiden.

def initUI(self): 
    ... 
    self.btn = QtGui.QPushButton('Play', self) 
    self.btn.move(20, 50) 
    self.btn.clicked.connect(self.play) 

    self.btn = QtGui.QPushButton('Stop', self) 
    self.btn.move(120, 50) 
    self.btn.clicked.connect(self.stop) 
    ... 

def play(self): 
    cb = QtGui.QApplication.clipboard() 
    text = cb.text() 
    self.words = text.split(' ') 
    self.current_word = 0 

    words_per_minute = 200 

    # setInterval apparently takes msecs 
    sleeptime = 60000.0/words_per_minute 

    self.timer = QtCore.QTimer(self) 
    self.timer.setInterval(sleeptime) 
    self.timer.timeout.connect(self.printword) 
    self.timer.start() 

def stop(self): 
    self.timer.stop() 

def printword(self): 
    word = self.words[self.current_word] 
    self.le.setText(word) 

    self.current_word += 1 
    if self.current_word == len(self.words): 
     self.timer.stop() 

Sie haben nicht einmal self.le.repaint zu nennen haben() auf diese Weise: Man könnte so etwas wie dies versuchen.

0

Hier ist meine Lösung von QThread, bitte überprüfen. Und ich benutzte auch den Mechanismus slot und signal, um die Daten zwischen dem Hauptthread und dem Arbeitsthread zu übertragen.

Nun, zunächst dachte ich, es wäre einfach, es so zu ändern. Es stellte sich jedoch heraus, dass einige Änderungen notwendig sind. Aber betrachten Sie es als Beispiel für die Verwendung von QThread.

from time import sleep 

import sys 
from PyQt4.QtCore import * 
from PyQt4.QtGui import * 


class Fastreader(QWidget): 

    def __init__(self): 
     super(Fastreader, self).__init__() 
     self.initUI() 

    def initUI(self): 
     self.le = QLineEdit(self) 
     self.le.setAlignment(Qt.AlignCenter) 
     self.le.move(20, 20) 

     self.btnplay = QPushButton('Play', self) 
     self.btnplay.move(20, 50) 

     self.btnstop = QPushButton('Stop', self) 
     self.btnstop.move(120, 50) 

     self.mthread = QThread() # New thread to run the Measurement Engine 
     self.worker = PrintWord() # Measurement Engine Object 

     # Transfer worker to the new thread. Calls to the worker will execute in mthread. 
     self.worker.moveToThread(self.mthread) 
     self.mthread.finished.connect(self.worker.deleteLater) # Cleanup after thread finished 

     self.btnplay.clicked.connect(self.worker.printword) 
     self.btnstop.clicked.connect(self.worker.kill, Qt.DirectConnection) 

     self.worker.wordshow.connect(self.showword) 
     self.mthread.start() 

     self.setGeometry(300, 300, 225, 80) 
     self.setWindowTitle('fastreader') 
     self.show() 

    @pyqtSlot(str) 
    def showword(self, word): 
     self.le.setText(word) 
#  self.le.repaint() 

    def closeEvent(self, event): 
     """ Example how to capture all window close events and perform an action before closing. It reimplements the default closeEvent""" 
     print("Close Event Received") 

     # Cleanup mthread. 
     self.mthread.quit() 
     self.mthread.wait() 

     # Accept the event, so that the window really closed. 
     # ignore() wold leave the window alive, for example if there is unsaved data. 
#  event.accept() 

class PrintWord(QObject): 
    wordshow = pyqtSignal(str)    # started measurement loop 

    def __init__(self): 
     self.dokill = False # Flag to interrupt the loop if needed 
     QObject.__init__(self) # Don't forget to call base class constructor 
     self.printword() 

    def printword(self): 

     cb = QApplication.clipboard() 
     text = cb.text() 

     words_per_minute = 200 

     sleeptime = 60.0/words_per_minute 
     self.dokill = False 
     for word in text.split(" "): 
       if self.dokill: 
        break 
       self.wordshow.emit(word) 
       sleep(sleeptime) 
#    print word 

    @pyqtSlot() 
    def kill(self): 
     """ Set loop interruption flag to exit the measurment loop """ 
     self.dokill = True 

def main(): 
    app = QApplication(sys.argv) 
    ex = Fastreader() 
    sys.exit(app.exec_()) 

if __name__ == '__main__': 
    main() 
+0

Vielen Dank für Ihre Zeit! Selbst nach ausgiebigen Tests konnte ich Ihren Vorschlag nicht zur Arbeit bringen. Aber ich werde in Zukunft mehr auf QThread schauen. –

+0

@MarkusPreislinger, darf ich den Fehler wissen? Ich konnte den Code erfolgreich auf meiner Seite laufen lassen. Ich benutze Python 3.3 und pyqt 4 – MaThMaX

+0

Beim Start passiert nichts - kein Fenster kommt auf. Manchmal taucht es plötzlich auf, aber wenn ich etwas drücke "Segmentierungsfehler (Core Dumped)". Ich habe versucht, es [mit diesem] (http://stackoverflow.com/questions/1736015/debugging-a-pyqt4-app) zu debuggen, gab aber nach einiger Zeit auf. Python 3.4.3+, PyQt 4.8.6, 4.2.0-36-generisch –

Verwandte Themen