Seite 2 von 3
Re: QPlainTextEdit hängt
Verfasst: Donnerstag 23. Dezember 2010, 10:34
von JonasR
Hier mal der fertige Code
Klick
Bin für Verbesserungsvorschläge offen

Danke an alle die geholfen haben =)
Re: QPlainTextEdit hängt
Verfasst: Donnerstag 23. Dezember 2010, 11:39
von lunar
"ReadTXT.run" implementierst Du besser so:
Code: Alles auswählen
def run(self):
with open("log.log", "r") as stream:
for line in log:
self.newLineRead.emit(line.strip())
Und da Du die neue Signal-Slot-API bereits zur Deklaration des Signals nutzt, spricht nichts dagegen, sie auch beim Verbinden zu nutzen, so dass Zeile 31ff. als "pushButton.clicked.connect(read.start)" formuliert werden kann.
Zum Schluss noch der obligatorische Hinweis auf PEP 8 (e.g. "MAINGUI" umbenennen), und darauf, dass "pushButton" und "textEdit" keine sonderlich aussagekräftigen Bezeichner sind.

Re: QPlainTextEdit hängt
Verfasst: Donnerstag 23. Dezember 2010, 11:51
von DaMutz
mir gefällt die Abhängigkeit der 2 Klassen untereinander nicht!
Erzeuge das 'ReadTXT' in der 'main()' und übergib das Objekt dem 'MainGUI' bei der Erzeugung. Die umgekehrt Kopplung ist meiner Meinung nach nicht nötig. 'ReadTXT' muss nichts von einer GUI wissen. Die '__init__'-Methode der 'ReadTXT' Klassen kannst du dann komplett löschen.
Durch diese Trennung wären die 2 Klassen auch besser einzeln testbar.
Re: QPlainTextEdit hängt
Verfasst: Donnerstag 23. Dezember 2010, 12:16
von lunar
"ReadTXT.__init__()" kann man auch so gleich löschen, der Konstruktor tut ja nichts sinnvolles. Aber ich denke, dass ist nur speziell in diesem Beispiel der Fall, tatsächlich wird da wohl irgendeine Art der Initialisierung stehen (e.g. Übergabe des Dateinamens der Logdatei oder so).
Auch sehe ich kein großes Problem in der „Abhängigkeit der Klassen“. Die gibt es gar nicht, denn "ReadTXT" ist auch jetzt schon vollkommen unabhängig von der GUI-Klasse. Allenfalls hängt die GUI-Klasse von ReadTXT ab, aber das ist mit einem einfachen Refactoring zu lösen, und daher meines Erachtens nicht so tragisch. Zumal das im tatsächlichen Quelltext möglicherweise auch so aussehen muss, nämlich wenn ReadTXT erst in Abhängigkeit von gewissen Eingaben in der GUI (e.g. Dateiname der Logdatei aus einem Dateidialog) erzeugt werden kann.
Re: QPlainTextEdit hängt
Verfasst: Montag 3. Januar 2011, 14:14
von JonasR
Bin mir nicht ganz sicher ob "startButton" und "logEdit" sinnvollere Namen sind ^^ aber ich habe die "__init__" Funktion der "ReadTXT" Klasse gelöscht und das "read" Objekt wird nun von der "main" Funktion vererbt.
Habe noch eine Frage bezüglich der Signale.
Wie stelle ich es am besten an das ich die gleichen Signal von mehreren Klassen aus nutzen kann? Wenn ich z.B das Signal "newLineRead" in einer anderen Klasse noch einmal definieren würde müsste ich auch den Slot in der GUI Klasse neu definieren. Würde aber lieber von Zwei Klassen auf einen Slot zugreifen.
Nun habe ich noch eine Frage die sich eher weniger auf diesen Thread richtet:
Wie bringe ich folgenden Beispiel Code auf 80 Zeichen pro Zeile?
Code: Alles auswählen
self.newLineRead.emit("Hallo, ich bin ein mehr als achtzig Zeichen langer Befehl und möchte ohne Zeilenumbruch ausgegeben werden")
Anbei noch der, wie oben beschrieben, veränderte Code.
Code: Alles auswählen
from PySide import QtCore, QtGui
import sys, time
class MainGui(QtGui.QMainWindow):
def __init__(self, read):
QtGui.QMainWindow.__init__(self)
widget = QtGui.QWidget(self)
widget.setLayout(QtGui.QVBoxLayout(widget))
self.setCentralWidget(widget)
logEdit = QtGui.QPlainTextEdit(widget)
logEdit.setObjectName("textEdit")
widget.layout().addWidget(logEdit)
startButton = QtGui.QPushButton(widget)
startButton.setObjectName("pushButton")
widget.layout().addWidget(startButton)
startButton.setText(
QtGui.QApplication.translate("Form",
"Start",
None,
QtGui.QApplication.UnicodeUTF8
)
)
startButton.clicked.connect(read.start)
read.newLineRead.connect(logEdit.appendPlainText)
class ReadTXT(QtCore.QThread):
newLineRead = QtCore.Signal(unicode)
def run(self):
file = open("log.log", "r")
lines = file.readlines()
file.close()
for line in lines:
self.newLineRead.emit(line.strip())
time.sleep(0.01)
def main():
app = QtGui.QApplication(sys.argv)
read = ReadTXT()
widget = MainGui(read)
widget.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
Re: QPlainTextEdit hängt
Verfasst: Montag 3. Januar 2011, 20:19
von lunar
Bitte gewöhne Dir die korrekte Terminologie an. In Deinem Beispiel wird das an "read" gebundene Objekt von "main()" an "MainGUI.__init__()" übergeben, mit Vererbung hat das nicht das Geringste zu tun. Vererbung ist eine Beziehung zwischen Klassen.
Deine Frage bezüglich der Signale verstehe ich nicht, oder anders gesagt, ich kann das beschriebene Problem nicht nachvollziehen. Du kannst doch ganz einfach mehrere, identische oder auch ganz verschiedene Funktionen oder Methoden mit einem Signal verbinden. Wenn Du Methoden zwischen Klassen "teilen" möchtest, in den Sinne, dass beide Klassen diese Methode in identischer Implementierung besitzen, dann hat das nichts mit Signalen und Slots, sondern nur mit den absoluten Grundlagen der Objektorientierung zu tun, die Lösung nämlich heißt Vererbung (und zwar im eigentlichen objektorientierten Sinne, und nicht in dem Sinne, welchem Du diesem Terminus in Deinem Beitrag verpasst hast).
Re: QPlainTextEdit hängt
Verfasst: Dienstag 4. Januar 2011, 09:58
von JonasR
Sorry wegen der falschen Terminologie.. Werde in Zukunft besser nachdenken bevor ich schreibe
Also ich mochte von Zwei Klassen auf das selbe Signal zugreifen. Ich habe in meinem echten Programm 8 Signale die ich in zwei klassen brauche, das heißt ich muss in der GUI Klasse 16 connect's machen. Ich habe mich nun mal an einem Beispiel mit Vererbung versucht... Das ganze läuft aber nicht wirklich...
Klick
Ich habe also eine Talker Klasse erstellt welche das Signal beinhaltet und diese an drei Klassen Vererbt,(Dieses mal ist es sogar richtig

) an meine GUI Klasse und an zwei Klassen die etwas in das Textfeld einfügen sollen. Nun mault der Interpreter aber rum:
Traceback (most recent call last):
File "C:\scripts\mainExample.py", line 61, in <module>
main()
File "C:\scripts\mainExample.py", line 56, in main
widget = MainGui(read)
File "C:\scripts\mainExample.py", line 34, in __init__
Talker.writeNewLine.connect(logEdit.appendPlainText)
AttributeError: 'PySide.QtCore.Signal' object has no attribute 'connect'
Denke mal die Talker Klasse wird nicht richtig initialisiert sodass das Signal nicht richtig erstellt wird... Wie geht es richtig?
Edit: Habe gerade herausgefunden dass ich das "Talker" in den Klassen durch self ersetzen muss

Insgesamt wird aber trotzdem nichts in das Textfeld geschrieben. Denke mal dass ich wieder mehrere Signale erstelle und er deswegen nichts empfängt.
Re: QPlainTextEdit hängt
Verfasst: Dienstag 4. Januar 2011, 12:50
von lunar
Wie in der Dokumentation beschrieben ist, müssen Klassen, die Signale verwenden, von "QObject" ableiten. Davon abgesehen ist Vererbung wirklich zu viel des Guten, wenn es wirklich nur darum geht, identische Signale in mehreren Klassen zu deklarieren. Da kannst Du die Deklaration auch einfach in jeder Klasse hinzufügen, Vererbung ist nur sinnvoll, wenn wirklich eine signifikante Menge an Quelltext zwischen Klassen zu teilen ist.
Davon abgesehen verstehe ich Dein Problem noch immer nicht. Im vorherigen Beitrag ging es um Slots, die in Python letztlich nichts weiter als normale Methoden sind, jetzt aber geht es Dir auf einmal um Signale, und die sind eben durchaus besondere Attribute.
Im Übrigen ist es eigentlich Grundwissen über Objektorientierung, dass man auf Exemplarattribute mittels "self" zugreift. Das muss Dir klar sein, bevor Du graphische Oberflächen entwickeln möchtest.
Re: QPlainTextEdit hängt
Verfasst: Dienstag 4. Januar 2011, 13:07
von JonasR
Hmm ich werde jetzt einfach in beiden "worker" Klassen die Signale definieren. Ist denke ich einfacher...
Und wie ich self benutze weiß ich natürlich

Mir war nur nicht ganz das Ausmaß der Vererbung bewusst. Also was dort geschieht.
Denn mal Danke für die Hilfe =)
Re: QPlainTextEdit hängt
Verfasst: Dienstag 4. Januar 2011, 14:28
von JonasR
Ich bin gerade auf noch ein Problem gestoßen. Ich brauche zum Beispiel in einer worker Klasse den Text aus einem QLineEdit. Wie stelle ich das ganze an?
Re: QPlainTextEdit hängt
Verfasst: Dienstag 4. Januar 2011, 14:40
von lunar
@JonasR: Du musst eben den Text des Steuerelements irgendwie an das "Worker"-Exemplar übergeben.
Re: QPlainTextEdit hängt
Verfasst: Dienstag 4. Januar 2011, 14:47
von JonasR
Naja das war mir klar nur blieb ich auch an dem "irgendwie" hängen ^^
Soll ich in dem worker ein Signal senden welches der GUI Klasse sagen soll dass sie das QLineEdit ausliest und in eine var der worker Klasse schreiben soll?
Weiß halt nicht ob es dafür eine gute Lösung gibt...
Re: QPlainTextEdit hängt
Verfasst: Dienstag 4. Januar 2011, 15:05
von lunar
Wieso übergibst Du den Text nicht einfach bei der Erzeugung des "Worker"-Exemplars?
Re: QPlainTextEdit hängt
Verfasst: Dienstag 4. Januar 2011, 15:07
von JonasR
Weil sich das Ganze während der Laufzeit noch ändern kann.
Re: QPlainTextEdit hängt
Verfasst: Dienstag 4. Januar 2011, 15:14
von lunar
@JonasR: Dann sende doch einfach ein Signal an den Thread, welchem Du den Text des Steuerelements als Parameter mitgibst.
Re: QPlainTextEdit hängt
Verfasst: Dienstag 4. Januar 2011, 15:20
von JonasR
Müsste mein worker dann aber nicht die GUI Klasse kennen um connecten zu können?
Re: QPlainTextEdit hängt
Verfasst: Dienstag 4. Januar 2011, 15:46
von lunar
Nein, muss er nicht. Es ist gerade der Sinn des Signal-Systems, dass verschiedene Komponenten nichts voneinander wissen müssen, und trotzdem kommunizieren können. Du kannst beliebige Signale an beliebiger Stelle mit beliebigen Methoden oder Funktionen verbinden.
Im konkreten Fall verbindest Du einfach nach der Erzeugung des "Worker"-Exemplars das entsprechende Signal Deiner GUI-Klasse mit dem entsprechenden Slot des "Worker"-Exemplars. So schwer ist das doch nicht ...
Re: QPlainTextEdit hängt
Verfasst: Dienstag 4. Januar 2011, 16:06
von JonasR
Sorry arbeite noch nicht so lange und intensiv mit Signalen und Slots
Kannst du mir das vielleicht ein Beispiel geben? Muss nichts großes sein.. Nur ein Denkanstoß ^^Stehe gerade ein bisschen auf dem Schlauch
Re: QPlainTextEdit hängt
Verfasst: Dienstag 4. Januar 2011, 16:30
von lunar
Mit Verlaub, es finden sich bereits genügend Beispiele für die Verwendung von Signalen und Slots in der Dokumentation von Qt, und es wurde in diesem Thread auch bereits eines meiner PyQt-Beispiele verlinkt, in welchem naturgemäß ebenfalls ausgiebig Gebrauch von Signalen und Slots gemacht wird.
Re: QPlainTextEdit hängt
Verfasst: Dienstag 4. Januar 2011, 16:40
von JonasR
lunar mir sind die Grundlagen von Signalen und Slots, wie du an meinen Codefetzen siehst, schon läufig. Nur weiß ich nicht wie ich einen Slot im worker definieren soll der das GUI nicht kennt...
Vielleicht habe ich auch mal wieder was vollkommen falsches im Kopf aber ich erkläre mal was ich denke:
Signal, würde in der GUI Klasse stehen:
Slot, würde im worker stehen:
Also was soll anstelle der drei Fragezeichen hin wenn ich das GUI nicht kenne?