Seite 1 von 3

QPlainTextEdit hängt

Verfasst: Freitag 17. Dezember 2010, 13:17
von JonasR
Hi Leute,

ich bastel gerade an einem tool zum neu bespielen eines Minicomputers. Dazu habe ich ein GUI mit Qt geschrieben über welches man den Vorgang starten kann und ein Log ausgegeben wird.
Wenn ich nun das Log in ein QPlainTextEdit ausgebe erscheinen einzelne Textblöcke erst nach einiger Zeit bzw erst wenn der gestartete Vorgang fertig gestellt ist. Das GUI und der Vorgang in dem ich den Minicomputer neu bespiele laufen in unterschiedlichen Threads. Die CPU Auslastung liegt bei ca 5% also kann es nicht durch eine Sperrung seitens der CPU bzw Parallelität kommen.

Nun wieso erscheinen die Blöcke erst nach einiger Zeit? Gibt es dafür eine Lösung?

€dit: Achja ich benutze PySide 1.0 Qt 4.7 und Python 2.7

Re: QPlainTextEdit hängt

Verfasst: Freitag 17. Dezember 2010, 13:30
von Hyperion
Wie hast Du das mit den Threads denn gelöst? Bist Du den von (Py)Qt empfohlenen Weg gegangen?

Re: QPlainTextEdit hängt

Verfasst: Freitag 17. Dezember 2010, 13:34
von JonasR
Wenn du damit meinst dass ich die QThreads benutze dann nein :D Ich benutze das threading Modul

Code: Alles auswählen

class WORKER(threading.Thread):
    def __init__(self):
        # Initialize threading
        threading.Thread.__init__(self)
Wenn ich QThreads benutze schmiert mir aus welchem Grund auch immer ab -.-'

btw ich habe oben meine Angaben aktualisiert:
€dit: Achja ich benutze PySide 1.0 Qt 4.7 und Python 2.7

Re: QPlainTextEdit hängt

Verfasst: Freitag 17. Dezember 2010, 13:38
von Hyperion
Es mag bei PySide anders sein, aber bei PyQt würde ich sagen, dass darin der Fehler begraben liegt. Da das aber vor allem aber Qt spezifisch sein sollte vermute ich mal extrem stark, dass eben genau das auch das Problem bei PySide sein dürfte. Du solltest mal in der dortigen Doku nach einem "Threading"-HowTo gucken! Dort sollte beschrieben sein, wie man so etwas idiomatisch löst.

lunar hatte mal nach einer Anregung von mir ein gutes Beispiel für PyQt implementiert: http://www.python-forum.de/viewtopic.php?f=11&t=24036

Wie gesagt, Du solltest Dich wegen PySide absichern, ob das dort so oder so ähnlich funzt.

Re: QPlainTextEdit hängt

Verfasst: Freitag 17. Dezember 2010, 13:41
von JonasR
Hehe okay dann werde ich mich da noch einmal einlesen und mich danach melden ;)
Danke schon mal

Re: QPlainTextEdit hängt

Verfasst: Freitag 17. Dezember 2010, 14:20
von JonasR
Sooo ich habe mich jetzt mal an Lunar's Beispielt gehalten. So stürzt mein Gui nicht ab, aber das Problem mit den verschwindenden Blöcken ist damit nicht gelöst :(

Das Ganze funktioniert übrigens in PySide genauso wie in PyQt ^^

Re: QPlainTextEdit hängt

Verfasst: Freitag 17. Dezember 2010, 14:34
von Hyperion
Kann es sein, dass einfach das Log nur in bestimmten Abschnitten aktualisiert wird? Ohne Code kann man dazu jetzt nichts genaueres sagen. Bastel doch mal ein Minimalbeispiel, ohne Schnickschnack, das nur den kern lauffähig widergibt.

Re: QPlainTextEdit hängt

Verfasst: Freitag 17. Dezember 2010, 15:06
von JonasR
Das werde ich vielleicht erst am Montag machen :P Habe gleich erstmal Wochenende.
Das Log kommt nach und nach über die Serielle Schnittstelle. Und es wird 100% in das QPlainTextEdit geschrieben. Wenn ich die Textzeilen markiere erscheint urplötzlich der Text.

Nochmals danke das du dich mit meinem Problem beschäftigst =)

Re: QPlainTextEdit hängt

Verfasst: Freitag 17. Dezember 2010, 15:09
von Hyperion
Wie setzt Du denn den Text? Evtl. musst Du da ein spezielles Update-Signal emitten? Durch das "Markieren" könnte das ja gesendet werden und fehlt eben bei deinem Hinzufügen?

Re: QPlainTextEdit hängt

Verfasst: Freitag 17. Dezember 2010, 15:20
von JonasR
Ich hänge es das was aus der Seriellen Schnittstelle kommt einfach hinten ran.

Code: Alles auswählen

QPlainTextEdit.appendPlainText("TEXT")
Und an ein Update habe ich auch schon gedacht. Bewirkt aber vom Gefühl her nichts nach jedem append das Feld zu Updaten.

Re: QPlainTextEdit hängt

Verfasst: Freitag 17. Dezember 2010, 15:26
von Hyperion
Tja, im Zweifel weiß lunar da Rat; sobald er den Thread entdeckt hat, wird es Dir sicherlich einen guten Tipp geben können.

Re: QPlainTextEdit hängt

Verfasst: Freitag 17. Dezember 2010, 16:12
von lunar
Ich warte lieber auf den Quelltext, anstatt jetzt wild herumzuraten.

@Hyperion: Ach ja, war "es" ein Versehen, ein Tippfehler, oder Absicht? Ich weiß nicht, aber irgendwie finde ich es komisch, Personen mit "es" zu bezeichnen ;)

Re: QPlainTextEdit hängt

Verfasst: Montag 20. Dezember 2010, 11:39
von Hyperion
lunar hat geschrieben:Hyperion: Ach ja, war "es" ein Versehen, ein Tippfehler, oder Absicht? Ich weiß nicht, aber irgendwie finde ich es komisch, Personen mit "es" zu bezeichnen ;)
Ooopsi.... großes Sorry!!! Natürlich ein Tippfehler ;-)

Re: QPlainTextEdit hängt

Verfasst: Montag 20. Dezember 2010, 12:00
von JonasR
Code
Log

Ist ein wenig unsauber der Code aber ich denke er zeigt das die Blöcke erst spät angezeigt werden. Wenn man das .strip() aus line 49 nimmt funktioniert es recht flüssig. Mir ist als würde er erst alles anzeigen wenn man eine Leere Zeile einfügt.

In meinem Original Code wird übrigens aus der Seriellen Schnittstelle ausgelesen nicht aus einer txt.
Und bitte keine Haue wegen dem global :D

Re: QPlainTextEdit hängt

Verfasst: Montag 20. Dezember 2010, 13:57
von DaMutz
dein Hauptproblem ist, dass du von einem anderen Thread aus auf den 'textEdit' zugreifst. Dies haben GUIs nicht gerne und reagieren darum auch nicht sauber. PyQt beschwert sich mit folgenden Fehlermeldungen:

Code: Alles auswählen

QObject::connect: Cannot queue arguments of type 'QTextBlock'
(Make sure 'QTextBlock' is registered using qRegisterMetaType().)
QObject::connect: Cannot queue arguments of type 'QTextCursor'
(Make sure 'QTextCursor' is registered using qRegisterMetaType().)
Deine READTXT-Klasse (nicht PEP8 konform) muss ein Signal senden sobald eine Linie gelesen wurde. Dies macht man mit PyQt so:

Code: Alles auswählen

class ReadTXT(QtCore.QThread):
    new_line_read = QtCore.pyqtSignal(unicode)

    def run(self):
        file = open("log.log", "r")
        lines = file.readlines()
        file.close()

        for line in lines:
            time.sleep(0.1)
            self.new_line_read.emit(line.strip())
Die Datei könnte man mit dem 'with'-Konstrukt auslesen, dann müsste man auch nicht die ganze Datei im speicher halten. Aber da du eh von der seriellen Schnittstelle liest, ist dies hier ja nicht relevant.

Ich habe den connect aufruf in die MainGUI-Klasse verschoben, da gehört er eher hin. Ausserdem sind die globalen Variablen nicht wirklich nötig und stören nur.
Die WORKER-Klasse kannst du auch weglassen.

#edit: ich habe alles mit PyQt gemacht.

Re: QPlainTextEdit hängt

Verfasst: Montag 20. Dezember 2010, 14:06
von Hyperion
DaMutz hat geschrieben: Deine READTXT-Klasse (nicht PEP8 konform) muss ein Signal senden sobald eine Linie gelesen wurde.
Genau das wurde ja auch so bei den von mir verlinkten Beispielen demonstriert :!:

Re: QPlainTextEdit hängt

Verfasst: Montag 20. Dezember 2010, 15:02
von JonasR
@DaMutz danke erstmal für deine Mühe, ich glaube ich muss mir mal ein ordentliches Tutorial fürs arbeiten mit Qt suchen. Hast du da was zur Hand? Ansich verstehe ich was du meinst bin mir aber mit den Signalen und Slots ein wenig unsicher...

@DaMutz und Hyperion :oops: Habe mir soeben die PEP8 Richtlinien durchgelesen und versuche mich beim nächsten mal dran zuhalten ;)

Re: QPlainTextEdit hängt

Verfasst: Dienstag 21. Dezember 2010, 10:53
von JonasR
CODE

So ich habe mal ein wenig auf und umgeräumt... Leider habe ich es nicht zum laufen gebracht.

Wieso wird das Signal anscheinend nicht gesendet?
Und wenn ich Zeile 29:

Code: Alles auswählen

read.newLineRead.connect(self.test)
durch

Code: Alles auswählen

read.newLineRead.connect(textEdit.appendPlainText)
ersetze wird dann der text von Zeile 50 automatisch als Eingabevariable gesetzt?


Btw wie bekomme ich Zeile 19 bis 22 auf 80 Zeichen getrimmt? ^^

Re: QPlainTextEdit hängt

Verfasst: Dienstag 21. Dezember 2010, 11:27
von DaMutz
Sieht schon viel besser aus :-)
JonasR hat geschrieben:Wieso wird das Signal anscheinend nicht gesendet?
Das Signal wird schon gesendet, nur machst du kein connect, bzw. erzeugst ein neues ReadTXT Objekt bei dem du das Signal nicht abfängst, und das korrekt verbundene startest du nicht. Binde doch den 'clicked' Event direkt an 'read.start', dann benötigst du auch die 'startWork' Methode nicht...
JonasR hat geschrieben: Und wenn ich Zeile 29:

Code: Alles auswählen

read.newLineRead.connect(self.test)
durch

Code: Alles auswählen

read.newLineRead.connect(textEdit.appendPlainText)
ersetze wird dann der text von Zeile 50 automatisch als Eingabevariable gesetzt?
ja. Deine Testfunktion benötigt noch einen zusätzlichen Parameter für den Text.
JonasR hat geschrieben: Btw wie bekomme ich Zeile 19 bis 22 auf 80 Zeichen getrimmt? ^^
das weiss ich auch nicht. Ich denke es gibt 2 Möglichkeiten. Entweder du benutzt eine Hilfsvariable für den setText Teil oder du formatierst es so:

Code: Alles auswählen

self.pushButton.setText(
            QtGui.QApplication.translate(
                "Form",
                "Start",
                None,
                QtGui.QApplication.UnicodeUTF8
            )
        )
keine Ahnung ob dies so gut ist.

Re: QPlainTextEdit hängt

Verfasst: Mittwoch 22. Dezember 2010, 08:33
von JonasR
Was für ein dummer Fehler :D Denn erstmal danke. Ich werde das ganze bei Zeiten mal umbauen und nochmal bescheid geben ob es klappt ;)