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
QPlainTextEdit hängt
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Wie hast Du das mit den Threads denn gelöst? Bist Du den von (Py)Qt empfohlenen Weg gegangen?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
Wenn du damit meinst dass ich die QThreads benutze dann nein Ich benutze das threading Modul
Wenn ich QThreads benutze schmiert mir aus welchem Grund auch immer ab -.-'
btw ich habe oben meine Angaben aktualisiert:
Code: Alles auswählen
class WORKER(threading.Thread):
def __init__(self):
# Initialize threading
threading.Thread.__init__(self)
btw ich habe oben meine Angaben aktualisiert:
€dit: Achja ich benutze PySide 1.0 Qt 4.7 und Python 2.7
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
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.
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.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
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 ^^
Das Ganze funktioniert übrigens in PySide genauso wie in PyQt ^^
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
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.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
Das werde ich vielleicht erst am Montag machen 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 =)
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 =)
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
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?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
Ich hänge es das was aus der Seriellen Schnittstelle kommt einfach hinten ran.
Und an ein Update habe ich auch schon gedacht. Bewirkt aber vom Gefühl her nichts nach jedem append das Feld zu Updaten.
Code: Alles auswählen
QPlainTextEdit.appendPlainText("TEXT")
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Tja, im Zweifel weiß lunar da Rat; sobald er den Thread entdeckt hat, wird es Dir sicherlich einen guten Tipp geben können.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
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
@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
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Ooopsi.... großes Sorry!!! Natürlich ein Tippfehlerlunar 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
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
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
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
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:
Deine READTXT-Klasse (nicht PEP8 konform) muss ein Signal senden sobald eine Linie gelesen wurde. Dies macht man mit PyQt so:
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.
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().)
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())
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.
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Genau das wurde ja auch so bei den von mir verlinkten Beispielen demonstriertDaMutz hat geschrieben: Deine READTXT-Klasse (nicht PEP8 konform) muss ein Signal senden sobald eine Linie gelesen wurde.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
@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 Habe mir soeben die PEP8 Richtlinien durchgelesen und versuche mich beim nächsten mal dran zuhalten
@DaMutz und Hyperion Habe mir soeben die PEP8 Richtlinien durchgelesen und versuche mich beim nächsten mal dran zuhalten
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:
durch
ersetze wird dann der text von Zeile 50 automatisch als Eingabevariable gesetzt?
Btw wie bekomme ich Zeile 19 bis 22 auf 80 Zeichen getrimmt? ^^
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)
Code: Alles auswählen
read.newLineRead.connect(textEdit.appendPlainText)
Btw wie bekomme ich Zeile 19 bis 22 auf 80 Zeichen getrimmt? ^^
Sieht schon viel besser aus
keine Ahnung ob dies so gut ist.
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:Wieso wird das Signal anscheinend nicht gesendet?
ja. Deine Testfunktion benötigt noch einen zusätzlichen Parameter für den Text.JonasR hat geschrieben: Und wenn ich Zeile 29:durchCode: Alles auswählen
read.newLineRead.connect(self.test)
ersetze wird dann der text von Zeile 50 automatisch als Eingabevariable gesetzt?Code: Alles auswählen
read.newLineRead.connect(textEdit.appendPlainText)
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:JonasR hat geschrieben: Btw wie bekomme ich Zeile 19 bis 22 auf 80 Zeichen getrimmt? ^^
Code: Alles auswählen
self.pushButton.setText(
QtGui.QApplication.translate(
"Form",
"Start",
None,
QtGui.QApplication.UnicodeUTF8
)
)