Seite 1 von 1
QTextEdit auf QLabel abbilden
Verfasst: Donnerstag 13. Januar 2011, 16:55
von Friedericus
Hi Leuts,
Ich komm hier grad nicht weiter:
Ich möchte den inhalt von TextEdit auf label abbilden lassen, sobald Enter gedrückt wird, aber alles was ich ausprobiert hab, führt nur zu Fehlermeldungen. Hat jemand ne Idee wie das geht?
Code: Alles auswählen
def groupTextEdit(self, title, text):
group = QtGui.QGroupBox(title) #title der Box
layout = QtGui.QVBoxLayout() #layout der Box
textEdit = QtGui.QLineEdit(text) #Line-Edit Feld
label = QtGui.QLabel()
textEdit.resize(10, 50) #Groesse des LineEdit festlegen
label.resize(10, 50)
layout.addWidget(textEdit) #LineEdit dem Layout hinzufuegen
layout.addWidget(label)
group.setLayout(layout) #die GroupBox mit dem Layout versehen
group.connect(textEdit, QtCore.SIGNAL('returnPressed()'),'Hier sollte die Funktion hin')
return group
Re: QTextEdit auf QLabel abbilden
Verfasst: Donnerstag 13. Januar 2011, 17:12
von lunar
Wieso nicht einfach "textedit.returnPressed.connect(label.setText)"? Was ist daran so schwer?
Im Übrigen wäre es zukünftig ganz nett, wenn Du die Fehlermeldungen selbst auch zeigst

Dann müssen wir weniger raten.
Re: QTextEdit auf QLabel abbilden
Verfasst: Montag 17. Januar 2011, 10:57
von Friedericus
hmm mach ich das spuckt er mich sobald ich enter drück
Code: Alles auswählen
TypeError: QLabel.setText(QString): not enough arguments
aus.
wenn ich das so
umbau, kommt mir folgende Fehlermeldung:
Code: Alles auswählen
TypeError: connect() slot argument should be a callable or a signal, not 'NoneType'
Re: QTextEdit auf QLabel abbilden
Verfasst: Montag 17. Januar 2011, 11:07
von Hyperion
Friedericus hat geschrieben:hmm mach ich das spuckt er mich sobald ich enter drück
Code: Alles auswählen
TypeError: QLabel.setText(QString): not enough arguments
aus.
returnPressed() hat ja auch keinen Rückgabewert. Insofern kann man imho dieses Signal nicht direkt mit einem Slot verbinden, welcher einen Parameter benötigt. Da hat lunar wohl nicht ganz aufgepasst oder er weiß mal wieder mehr als wir anderen
Friedericus hat geschrieben:
wenn ich das so
umbau, kommt mir folgende Fehlermeldung:
Code: Alles auswählen
TypeError: connect() slot argument should be a callable or a signal, not 'NoneType'
Na das ist ja auch logisch, da Du hier nicht die Funktion übergibst, sondern den Rückgabewert von "label.setText()"; und der ist eben None
Ich würde eben eine Funktion definieren, welche Du mit dem returnPressed-Signal verbindest und in der dann separat die setText()-Methode des Labels aufgerufen wird.
Im übrigen ist die Frage irreführend, da es sich hier ja nicht um ein QTextEdit handelt, sondern um ein QLineEdit-Element!
Re: QTextEdit auf QLabel abbilden
Verfasst: Montag 17. Januar 2011, 11:10
von lunar
Verzeih mir, ich hatte nicht daran gedacht, dass "returnPressed()" kein Argument erhält. Du kannst stattdessen "textEdited()" verwenden: "lineedit.textEdited.connect(label.setText)". Oder Du musst eben eine eigene Funktion oder Methode schreiben, um den Text des Eingabefelds abzufragen, und dem Beschriftungsfeld zuzuweisen, welche Du dann mit dem "returnPressed()"-Signal verbinden kannst.
Re: QTextEdit auf QLabel abbilden
Verfasst: Montag 17. Januar 2011, 11:23
von Hyperion
@lunar: Wäre es in so einer Situation eigentlich opportun, eine lambda-Funktion zu nutzen? Also etwa so:
Code: Alles auswählen
textedit.returnPressed.connect(lambda: label.setText(textedit.text))
Re: QTextEdit auf QLabel abbilden
Verfasst: Montag 17. Januar 2011, 11:31
von Friedericus
kk, und warum genau funktioniert die Funktion jetzt mit 'textEdited()' aber nicht mit 'returnPressed' ?
Re: QTextEdit auf QLabel abbilden
Verfasst: Montag 17. Januar 2011, 11:33
von Hyperion
Friedericus hat geschrieben:kk, und warum genau funktioniert die Funktion jetzt mit 'textEdited()' aber nicht mit 'returnPressed' ?
Weil ersteres Signal einen QString (eben den Text des LineEdits) emittiert, den wiederum setText als Parameter benötigt. returnPressed() emittiert eben nichts und deswegen kann man es nicht direkt mit einem Slot verbinden, der einen Parameter benötigt!
Re: QTextEdit auf QLabel abbilden
Verfasst: Montag 17. Januar 2011, 11:50
von lunar
@Hyperion: Wieso sollte man keine "lambda"-Funktion nutzen? Es fehlen nur die Klammern in "textedit.text
()"

Re: QTextEdit auf QLabel abbilden
Verfasst: Montag 17. Januar 2011, 11:54
von Hyperion
lunar hat geschrieben:@Hyperion: Wieso sollte man keine "lambda"-Funktion nutzen? Es fehlen nur die Klammern in "textedit.text
()"

Oops, ja klar
Naja, mit lambda sollte man ja schon eher vorsichtig umgehen; in diesem Falle würde ich es eben so sehen, dass die "Relais"-Funktion im Grunde genommen keine Funktionalität kapselt, die man modular außerhalb dieses Problems noch mal brauchen würde. Ich wollte das nur mal von Dir bestätigt wissen

Re: QTextEdit auf QLabel abbilden
Verfasst: Dienstag 18. Januar 2011, 09:55
von Friedericus
So, jetzt funktioniert alles soweit. Der Inhalt der Line-Edit wird auf dem Label abgebildet, allerdings hab ich keine Returnwerte, d.h.:
Code: Alles auswählen
textEdit.returnPressed.connect(lambda: label.setText(textEdit.text()))
print 'mit Klammer:', label.text()
print 'Ohne Klammer:', label.text
bekomm ich folgendes zurück:
Code: Alles auswählen
mit Klammer:
Ohne Klammer: <built-in method text of QLabel object at 0x01564588>
das ohne klammer ist klar, aber warum ist label.text() leer obwohl ich mit der lambdafunktion den Wert gerade gesetzt hab?
Re: QTextEdit auf QLabel abbilden
Verfasst: Dienstag 18. Januar 2011, 17:13
von lunar
Der Text des Beschriftungsfeld wird nicht sofort gesetzt, sondern nur und ausschließlich dann, wenn Du im Eingabefeld die Eingabetaste drückst. Die erste Zeile Deines Beispiels beschreibt nur diese Verbindung, führt aber nicht dazu, dass der Text sofort aktualisiert wird. Das ist ja gerade der immanente Unterschied zwischen Signal-Slot-Verbindungen und normalen Methodenaufrufen, letztere werden ja sofort ausgeführt. Insofern ist dieses Ergebnis genau das, was gemäß des Quelltexts zu erwarten ist.
Das alles muss Dir klar sein, wenn Du Benutzeroberflächen mit Qt entwickeln möchtest.
Re: QTextEdit auf QLabel abbilden
Verfasst: Mittwoch 19. Januar 2011, 10:03
von Friedericus
lunar hat geschrieben:Der Text des Beschriftungsfeld wird nicht sofort gesetzt, sondern nur und ausschließlich dann, wenn Du im Eingabefeld die Eingabetaste drückst.
ja, das hab ich gemacht. Etwas ins LineEdit eingegeben, danach die Entertaste gedrückt.
Der text wird auch so wie er soll auf dem Label abgebildet, jedoch wird Label.text() eben nicht mit dem String gesetzt.
Aber ich weiß nicht warum. :K
lunar hat geschrieben:... und normalen Methodenaufrufen, letztere werden ja sofort ausgeführt. Insofern ist dieses Ergebnis genau das, was gemäß des Quelltexts zu erwarten ist.
ja es ist ja genau so beabsichtigt. Dass eben die Funktion nicht sofort ausgeführt werden soll, sondern eben nur wenn ich Enter betätige.
Re: QTextEdit auf QLabel abbilden
Verfasst: Mittwoch 19. Januar 2011, 12:20
von lunar
@Friedericus: Nun, aus dem Quelltext, den Du in Deinem Beitrag gezeigt hast, geht das alles nicht hervor. Wenn Du sinnvolle Antworten möchtest, dann musst Du auch den Quelltext zeigen, mit dem dieser Quelltext auftritt, und nicht irgendeinen wahlfreien Zusammenschnitt.
Insofern bleibt es auch jetzt bei allgemeinen Aussagen: "QLabel.text()" gibt immer zurück, was das betreffende Beschriftungsfeld anzeigt. Wenn der Aufruf von ".text()" bei Dir nichts zurückgibt, dann rufst Du ".text()" offenbar auf dem falschen Objekt auf.
Re: QTextEdit auf QLabel abbilden
Verfasst: Mittwoch 19. Januar 2011, 14:41
von Friedericus
ok, dann hier mal der gesamte Code:
Code: Alles auswählen
from PyQt4 import QtGui, QtCore
import TCPIP_server_Auftragsmodul_v11_units
import sys
class ServerGui(QtGui.QMainWindow): #Main Window erstellen
def __init__(self, parent = None):
self.ipAdress = ''
self.distance = '10'
QtGui.QMainWindow.__init__(self, parent)
self.filename = 'H:/iwbDaten/TCPIP_Client/'
self.data = ''
central_widget = QtGui.QWidget()
self.setCentralWidget(central_widget)
grid = QtGui.QGridLayout()
menu = self.menubar()
# zeile = TCPIP_server_Auftragsmodul_v11_units.Server.start().zeile
okButton = QtGui.QPushButton("OK")
cancelButton = QtGui.QPushButton("Beenden")
distance, self.distance = self.groupTextEdit('distance', self.distance)
showData, self.filename = self.groupTextEdit('gewaehlte Datei', self.filename)
progress = self.dateiBearbeiten(self.data)
group = self.unitGroups(showData, distance, 'Datei einlesen')
grid.addWidget(okButton, 60, 49)
grid.addWidget(cancelButton, 60, 48)
grid.addWidget(progress, 20, 10, 20, 40)
grid.addWidget(group, 10, 10, 10, 40)
central_widget.setLayout(grid)
self.setWindowTitle('Server')
self.resize(250, 350)
self.connect(cancelButton, QtCore.SIGNAL('clicked()'), QtCore.SLOT('close()'))
self.connect(okButton, QtCore.SIGNAL('clicked()'), self.startServer)
def startServer(self):
server = TCPIP_server_Auftragsmodul_v11_units.Server(self.filename, self.distance)
start = server.start() #Datei, Distance
return start #H:/iwbDaten/TCPIP_Client/"
def createWidgets(self):
central_widget = QtGui.QWidget()
widget = self.setCentralWidget(central_widget)
return widget
'''
----------MENUBAR-----------
Erstellt die Menuebar
Es wird eine Menubar erstellt,
sowie zwei Funktionen hinzugefuegt:
OPEN: oeffnet ein File und zeigt den Dateipfad an
EXIT: Beendet das Programm
'''
def menubar(self):
exit = QtGui.QAction(QtGui.QIcon('icons/exit.png'), #Erstellt die Exit-Schaltflaeche
'Exit', self)
exit.setShortcut('Ctrl+Q') #weist den Shortcut zu
self.connect(exit, QtCore.SIGNAL('triggered()'), #Verbindet die Schaltflaeche
QtCore.SLOT('close()')) #mit der close-Anweisung
open = QtGui.QAction(QtGui.QIcon('open.png'), #Erstellt die Exit-Schaltflaeche
'Open', self)
open.setShortcut('Ctrl+O') #weist den Shortcut zu
open.setStatusTip('Open new File')
self.connect(open, QtCore.SIGNAL('triggered()'), #Verbindet die Schaltflaeche mit der
self.openFile) #openFile-Anweisung
menubar = self.menuBar() #Erstellt eine Menubar
file = menubar.addMenu('&Datei') #Fuegt ein Menu hinzu
file.addAction(open) #Open-Button hinzufuegen
file.addAction(exit) #Exit-Button hinzufuegen
'''
---------OPENFILE---------
Erstellt den Dialog zum oeffnen des Files
Hier wird der 'FileOpen'-Dialog erzeugt
die Daten werden an self.file uebergeben
Der Dateipfad wird auf dem 'Datei Anzeigen-Label angezeigt
'''
def openFile(self):
filename = QtGui.QFileDialog.getOpenFileName(self,'Ordner wählen', '', "*.cli")#Dialog aufrufen
file = open(filename) #Datei oeffnen
self.data = file.read() #Datei auslesen
self.filename = filename #Filename setzen
self.lab.setText(self.filename) #Dateipfad anzeigen
'''
---------GROUPLABEL-----------
Erstellt einen Gruppenkasten mit Label
Hier wird ein Label erzeugt, welches
in eine Group-Box eingebettet wird
'''
def groupLabel(self, title, label):
group = QtGui.QGroupBox(title) #title der Box
layout = QtGui.QVBoxLayout() #layout der Box
self.lab = QtGui.QLabel(label) #Label ACHTUNG: label ist self, da hier der Pfad abgebildet wird
layout.addWidget(self.lab) #Label dem Layout hinzufuegen
group.setLayout(layout) #die Groupbox mit dem Layout versehen
return group #Gruppe returnen
'''
---------groupTextEdit-----------
Erstellt einen Gruppenkasten mit TextEdit
Hier wird ein Edit-Zeile erzeugt, welches
in einer Group-Box eingebettet wird
'''
def groupTextEdit(self, title, text):
group = QtGui.QGroupBox(title) #title der Box
layout = QtGui.QVBoxLayout() #layout der Box
textEdit = QtGui.QLineEdit(text) #Line-Edit Feld
label = QtGui.QLabel()
textEdit.resize(10, 50) #Groesse des LineEdit festlegen
label.resize(10, 50)
layout.addWidget(textEdit) #LineEdit dem Layout hinzufuegen
layout.addWidget(label)
group.setLayout(layout) #die GroupBox mit dem Layout versehen
textEdit.returnPressed.connect(lambda: label.setText(textEdit.text()))
print 'mit Klammer:', label.text()
print 'Ohne Klammer:', label.text
returnText = label.text()
return group, returnText #Gruppe returnen
#def setText(self):
# label = ''
#text = self.distance
#label.setText(text.text)
'''
----------UNITEGROUPS------------
fasst beide Gruppen zusammen
und fasst sie in eine Horizontales
Layout zusammen
'''
def unitGroups(self, group1, group2, title):
group = QtGui.QGroupBox(title) #Gruppe erstellen
layout = QtGui.QHBoxLayout() #Layout erstellen
layout.addWidget(group1) #Gruppe1 hinzufuegen
layout.addWidget(group2) #Gruppe2 hinzufuegen
#layout.addWidget(group3)
group.setLayout(layout) #Gruppe das Layout hinzufuegen
return group #Gruppe returnen
############
#erstellt Die Gruppe die die Arbeitsschritte darstellt
############
'''
-------DATEIBEARBEITEN---------
Hier wird die Gruppe erstellt
die Informationen ueber den Arbeitsablauf gibt.
Sie beinhaltet:
PBAR: Prozentbalken
PPROGRESS: Information welche Zeile aufgetragen wird
PSHOW: Zeigt den Momentan durgefuehrten Arbeitsablauf
'''
def dateiBearbeiten(self, data):
group = QtGui.QGroupBox('Datei bearbeiten') #Gruppenkasten hinzufuegen
plab = QtGui.QLabel('Fortschritt:') #Label hinzufuegen
pbar = QtGui.QProgressBar(self) #Prozentleiste erstellen
pprogress = QtGui.QLabel('Es wird Zeile %d von %e aufgetragen') #Aktuelle Zeile dartellen
pshow = QtGui.QTextEdit(data) #Anzeige fuer den gegenwaerteigen Arbeitsschritt
plab1 = QtGui.QLabel('Arbeitsschritt:') #Label fuer das Textfeld
progress = QtGui.QVBoxLayout() #Erstellt das Layout
progress.addWidget(plab) #fuegt die Widgets dem Layout hinzu
progress.addWidget(pbar)
progress.addWidget(pprogress)
progress.addWidget(plab1)
progress.addWidget(pshow)
group.setLayout(progress) #der Gruppe das Layout hinzufuegen
return group
app = QtGui.QApplication(sys.argv) #Main-Methode
ex = ServerGui()
ex.show()
sys.exit(app.exec_())
und wie gesagt, Der Text wird auf dem Label abgebildet, label.text() jedoch bleibt leer.
Re: QTextEdit auf QLabel abbilden
Verfasst: Mittwoch 19. Januar 2011, 15:07
von lunar
Für diesen Quelltext gilt das
oben Gesagte.
"label.text()" gibt den Inhalt des Beschriftungsfeld
zum Zeitpunkt des Aufrufs zurück. Dieses Objekt wird nicht "magisch" aktualisiert, wenn sich der Text ändert. Außerdem geschieht dieser Aufruf bei Dir zu einem Zeitpunkt, an dem das Fenster nicht einmal vollständig initialisiert ist, dementsprechend ist der Text
immer leer. Du darfst den Text des Beschriftungsfelds natürlich erst dann abfragen, wenn es einen Inhalt hat, also sprich, nachdem der Benutzer die Eingabetaste betätigt hat.
Im Allgemeinen verstehe ich auch nicht, wieso Du unbedingt den Text des Beschriftungsfelds abfragen möchtest, anstatt direkt den Text des Eingabefelds zu nehmen.
Jedenfalls offenbart die Tatsache, dass Du im gezeigten Quelltext die Ausgabe des Texts erwartest,
grundlegende Verständnisschwierigkeiten im Signal-Slot-Konzept sowie im allgemein asynchronen Ablauf von ereignisorientierten Programmen, wie es jede Benutzeroberfläche ist. Auch andere Probleme im Quelltext wie beispielsweise die Verwendung absoluter Größenangaben, dem Namen "TCPIP_server_Auftragsmodul_v11_units" (?!) sowie manche Kommentare lassen vermuten, dass die für solche Programme nötigen Grundlagen fehlen. Lese also doch bitte die Einführungen und Tutorien in der Qt-Dokumentation.
Re: QTextEdit auf QLabel abbilden
Verfasst: Mittwoch 19. Januar 2011, 15:11
von BlackJack
@Friedericus: Du hast anscheinend grundsätzlich den Programmablauf bei GUIs nicht verstanden. In der vorletzten Zeile von der Funktion ermittelst Du den Inhalt von dem `label` zu dem Zeitpunkt wo diese Zeile ausgeführt wird. Und da steht in dem Label *tatsächlich* nichts drin. Dafür müsstest Du theoretisch zwischen der Abarbeitung der Zeile mit dem `connect()` und der vorletzten Zeile etwas eingetippt und die Eingabetaste gedrückt haben. Selbst das wäre aber nicht genug, denn da die GUI-Hauptschleife diese Ereignisse gar nicht verarbeiten kann, solange Deine Funktion da noch abgearbeitet wird, kann auch das Signal nicht verarbeitet werden.
Deine DocStrings sind übrigens keine -- dafür stehen sie an der falschen Stelle. Literale Zeichenketten sind nur dann DocStrings, wenn sie direkt *nach* einer ``def``- oder ``class``-Anweisung stehen.