Hallo,
ich habe lange mit mir gehadert, ob ich mein Problem hier einstellen soll oder nicht. Aber jetzt will ich es doch tun, da meine Suche mit Google und Co. keinen Erfolg brachte.
Folgende Umgebung, mit Qt Designer erstellt und ins Programm eingebunden:
Ein Formular mit ca. 30 LineEdit (Text) Feldern, ein paar Checkbox und einem TableWidget.
Das Formular füttert mit seinen Eingabeobjekten dieses Tablewidget, welches wiederum eine Datenbank füllt und eine Art Adressdatenbank darstellt.
Das Anzeigen der Daten aus der Datenbank in das Tablewidget und Abspeichern von neuen Datensätzen aus dem Formular funktioniert bereits.
Wenn ich aber durch "Doppelklick" auf eine Zeile im Widget die Daten in das Formular übernehmen will, bleibt das Programm spätestens an der ersten ComboBox stehen.
Die ComboBox unterstützt nicht das Attribut .setText() Soweit klar.
Wie kann ich den Typ des Feldes herausfinden um damit das richtige Attribut zu nehmen?
Ich fülle im Moment die Felder des Formulars mit Hilfe eines Arrays, in dem alle Feldnamen stehen.
In meiner Unwissenheit könnte ich mir sowas vorstellen wie: Ist es eine ComboBox, dann rufe def combobox auf, ermittle den aktuellen Index vom einzutragenden Wert und zeige ihn an.
Ähnliches würde ich dann mit den Checkboxen machen.
Gibt es so einen Befehl der mit im Klartext sagt, es handelt sich hier um eine Combobox, eine Checkbox, ein Lineedit?
Für eine kleine Hilfestellung wäre ich dankbar. Mein Wissensstand zu Python würde ich mit "geht schon" bezeichnen. Wenn's geht bitte einfach.
Danke
Matthias
Formularfeld Typ feststellen
Es gibt verschiedene Ansaetze. Zum einen gibt es die Moeglichkeit, den Typ eines Objektes mit isinstance rauszufinden, und basierend darauf zu verzweigen. Das funktioniert fuer den von dir soweit geschilderten Fall, aber setzt dann voraus, dass wirklich immer fuer jede ComboBox etc das genau gleiche passieren muss. Alternativ kann man sich zB ein dictionary bauen, das Feldnamen auf Hilfsfunktionen abbildet, die dann immer das passende machen. Und den Vorteil haben, zB eine kryptische Abkuerzung in einem Feld der Datenbank in etwas lesbares zu uebersetzen, bevor das dann tatsaechlich dargestellt wird. Mal eine Skizze, die ein paar Annahmen trifft:
- der Datensatz liegt als dictionary vor (also zB { feld: wert, ...} aus der Datenbankabfrage/der Tabellenzeile)
- per Namen sind die Controls des Feldes auffindbar.
- der Datensatz liegt als dictionary vor (also zB { feld: wert, ...} aus der Datenbankabfrage/der Tabellenzeile)
- per Namen sind die Controls des Feldes auffindbar.
Code: Alles auswählen
def convert_drivers_license(control, value):
real_value = something_with_value(value)
control.setCurrentText(real_value)
CONVERTERS = {
"title": QComboBox. setCurrentText,
"drivers_license": convert_drivers_license,
}
def setDataFromEntry(self, entry):
for name, value in entry.items():
converter = CONVERTERS.get(name, QLineEdit.setText) # default annahme: es ist ein LineEdit
converter(self.ui.findObject(name), value)
Danke für dein Beispiel.
So lange es sich um ein QLineEdit Feld handelt, ist alles ok. Auch den richtigen Wert in die ComboBox zu bekommen, ist gelöst. Ich mache es so:
Aber zu unterscheiden ob es sich um ein QLineEdit oder QComboBox Feld handelt, ist in deinem Beispiel nicht aufgeführt. Oder täusche ich mich da?
Die Idee mit dem Dictionary ist gut. Ich denke, damit klappt es.
Danke
So lange es sich um ein QLineEdit Feld handelt, ist alles ok. Auch den richtigen Wert in die ComboBox zu bekommen, ist gelöst. Ich mache es so:
Code: Alles auswählen
def setzeCombo(self):
Feld = ["Zustand"] # Array mit Feldnamen
preset = "self."
inhalt = "schlecht" # Daten aus dem TableWidget
befehl = preset + Feld[0] + ".findText('" + inhalt + "')"
print('a = ' + befehl) # nur zur Kontrolle
a = eval(befehl)
print (a) # Index in der Combobox
self.Zustand.setCurrentIndex(a) #damit geht's
Die Idee mit dem Dictionary ist gut. Ich denke, damit klappt es.
Danke
Strings setzt man nicht mit + zusammen, sondern benutzt Stringformatierung. Der Inhalt von inhalt muß auch entsprechend behandelt werden, dass er keine Sonderzeichen enthält:
ABER: `eval` sollte man nicht benutzen. Hier kann man einfach `getattr` benutzen:
Code: Alles auswählen
befehl = f"self.{Feld[0]}.findText({inhalt!r})"
Code: Alles auswählen
def setzeCombo(self):
Feld = ["Zustand"] # Array mit Feldnamen
inhalt = "schlecht" # Daten aus dem TableWidget
a = getattr(self, Feld[0]).findText(inhalt)
print (a) # Index in der Combobox
self.Zustand.setCurrentIndex(a)
@django122: doch, mein Beispiel unterscheidet zwischen LineEdit und ComboBox - du musst nochmal genau hinschauen. Ich mache das allerdings NICHT via des Typs, eben weil ich die Moeglichkeit fuer spezifische Behandlung freihalten will. Die ich ja auch zeige.
Und Sirius3 hat's schon erwaehnt, aber ich betone das nochmal: vergiss, dass es eval (und den grossen Bruder exec) gibt. Die sind klar auf der dunklen Seite der Macht, und man muss viel wissen, bis man an einen Punkt kommt, wo man sie sicher handhaben kann.
Und Sirius3 hat's schon erwaehnt, aber ich betone das nochmal: vergiss, dass es eval (und den grossen Bruder exec) gibt. Die sind klar auf der dunklen Seite der Macht, und man muss viel wissen, bis man an einen Punkt kommt, wo man sie sicher handhaben kann.