GUI – 38 Eingabefelder und 38 Beschriftungen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Benutzeravatar
Strawk
User
Beiträge: 229
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

Code: Alles auswählen

import tkinter

# Funktion zu den Schaltflächen
def ende():
    master.destroy()

def anzeigen():
    eingabe = e_nummer.get()
    l_anzeige["text"] = eingabe

master = tkinter.Tk()
master.geometry("800x600+30+30") 

# nummer, codierung
e_nummer = tkinter.Entry(master)
e_nummer.grid(row=0, column=0)
e_codierung = tkinter.Entry(master).grid(row=1, column=0)
tkinter.Label(master, text="nummer").grid(row=0, column=1)
tkinter.Label(master, text="codierung").grid(row=1, column=1)

# name_oder_firmenname, geburtsname, vorname_bezeichnung
tkinter.Entry(master).grid(row=0, column=2)
tkinter.Entry(master).grid(row=2, column=2)
tkinter.Entry(master).grid(row=4, column=2)
tkinter.Label(master, text="name_oder_firmenname").grid(row=1, column=2)
tkinter.Label(master, text="geburtsname").grid(row=3, column=2)
tkinter.Label(master, text="vorname_bezeichnung").grid(row=5, column=2)

# strasse_hausnummer, plz, ort_stadt
tkinter.Entry(master).grid(row=0, column=3)
tkinter.Entry(master).grid(row=2, column=3)
tkinter.Entry(master).grid(row=4, column=3)
tkinter.Label(master, text="strasse_hausnummer").grid(row=1, column=3)
tkinter.Label(master, text="plz").grid(row=3, column=3)
tkinter.Label(master, text="ort_stadt").grid(row=5, column=3)

# ortsteil, bundesland_provinz_kanton, land_nation
tkinter.Entry(master).grid(row=0, column=4)
tkinter.Entry(master).grid(row=2, column=4)
tkinter.Entry(master).grid(row=4, column=4)
tkinter.Label(master, text="ortsteil").grid(row=1, column=4)
tkinter.Label(master, text="bundesland_provinz_kanton").grid(row=3, column=4)
tkinter.Label(master, text="land_nation").grid(row=5, column=4)

# fahrzeugfabrikat, fahrzeugtyp, kfz_kennzeichen_historie
tkinter.Entry(master).grid(row=6, column=2)
tkinter.Entry(master).grid(row=8, column=2)
tkinter.Entry(master).grid(row=10, column=2)
tkinter.Label(master, text="fahrzeugfabrikat").grid(row=7, column=2)
tkinter.Label(master, text="fahrzeugtyp").grid(row=9, column=2)
tkinter.Label(master, text="kfz_kennzeichen_historie").grid(row=11, column=2)

# landesvorwahl, festnetzvorwahl, festnetznummer
tkinter.Entry(master).grid(row=6, column=3)
tkinter.Entry(master).grid(row=8, column=3)
tkinter.Entry(master).grid(row=10, column=3)
tkinter.Label(master, text="landesvorwahl").grid(row=7, column=3)
tkinter.Label(master, text="festnetzvorwahl").grid(row=9, column=3)
tkinter.Label(master, text="festnetznummer").grid(row=11, column=3)

# aktiv, mobile_vorwahl, mobiler_anschluss
tkinter.Entry(master).grid(row=6, column=4)
tkinter.Entry(master).grid(row=8, column=4)
tkinter.Entry(master).grid(row=10, column=4)
tkinter.Label(master, text="aktiv").grid(row=7, column=4)
tkinter.Label(master, text="mobile_vorwahl").grid(row=9, column=4)
tkinter.Label(master, text="mobiler_anschluss").grid(row=11, column=4)

# e_mail_1, e_mail_2, url
tkinter.Entry(master).grid(row=12, column=2)
tkinter.Entry(master).grid(row=14, column=2)
tkinter.Entry(master).grid(row=16, column=2)
tkinter.Label(master, text="e_mail_1").grid(row=13, column=2)
tkinter.Label(master, text="e_mail_2").grid(row=15, column=2)
tkinter.Label(master, text="url").grid(row=17, column=2)

# geschlecht, anzahl_kinder, verstorben_am_um
tkinter.Entry(master).grid(row=12, column=3)
tkinter.Entry(master).grid(row=14, column=3)
tkinter.Entry(master).grid(row=16, column=3)
tkinter.Label(master, text="geschlecht").grid(row=13, column=3)
tkinter.Label(master, text="anzahl_kinder").grid(row=15, column=3)
tkinter.Label(master, text="verstorben_am_um").grid(row=17, column=3)

# geburtstag, anzahl_ereignisse, memos
tkinter.Entry(master).grid(row=12, column=4)
tkinter.Entry(master).grid(row=14, column=4)
tkinter.Entry(master).grid(row=16, column=4)
tkinter.Label(master, text="geburtstag").grid(row=13, column=4)
tkinter.Label(master, text="anzahl_ereignisse").grid(row=15, column=4)
tkinter.Label(master, text="memos").grid(row=17, column=4)

# fax, titel, beruf
tkinter.Entry(master).grid(row=18, column=2)
tkinter.Entry(master).grid(row=20, column=2)
tkinter.Entry(master).grid(row=22, column=2)
tkinter.Label(master, text="fax").grid(row=19, column=2)
tkinter.Label(master, text="titel").grid(row=21, column=2)
tkinter.Label(master, text="beruf").grid(row=23, column=2)

# ausbildung, taetigkeit, taetig_in_firma
tkinter.Entry(master).grid(row=18, column=3)
tkinter.Entry(master).grid(row=20, column=3)
tkinter.Entry(master).grid(row=22, column=3)
tkinter.Label(master, text="ausbildung").grid(row=19, column=3)
tkinter.Label(master, text="taetigkeit").grid(row=21, column=3)
tkinter.Label(master, text="taetig_in_firma").grid(row=23, column=3)

# hobbys, herkunftsland, bekanntschaft_seit
tkinter.Entry(master).grid(row=18, column=4)
tkinter.Entry(master).grid(row=20, column=4)
tkinter.Entry(master).grid(row=22, column=4)
tkinter.Label(master, text="hobbys").grid(row=19, column=4)
tkinter.Label(master, text="herkunftsland").grid(row=21, column=4)
tkinter.Label(master, text="bekanntschaft_seit").grid(row=23, column=4)

b_anzeige = tkinter.Button(master, text="Anzeigen",
                           command = anzeigen).grid(row=31, column=2)

l_anzeige = tkinter.Label(master)
l_anzeige.grid(row=36, column=2)

bende = tkinter.Button(master, text="Ende", command = ende)
bende.grid(row=31, column=3)

master.mainloop()
Der Code funktioniert nicht mehr. Seit dem letzten Rechner-Einschalten habe ich aber nichts geändert. Fehlermeldung:
ImportError: No module named tkinter
Grüße
Strawk
Ich programmiere erfolglos, also bin ich nicht.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@Strawk: Du hast wohl verschiedene Python-Versionen installiert. Nimm einfach die richtige. Mit Deinem jetzigen Vorgehen, alles linear runterzuprogrammieren, wirst Du nicht glücklich werden. Nimm Dir die Zeit, und lerne die Grundlagen von Python.
Benutzeravatar
Strawk
User
Beiträge: 229
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

Hallo Nutzer! :D

Für meine Datenbank-GUI möchte ich zwei große Frames nebeneinander. Im linken die Eingabemaske aus 38 Entry- und Label-Feldern, im rechten eine großes Ausgabetextfenster mit vertikaler Scrollbar. Aktuelles Problem: die Widgets wollen nicht in den Frame wandern; ich erhalte die Meldung:
TypeError: Tkinter objects don't support 'in' tests.
Der entsprechende Code-Schnipsel:

Code: Alles auswählen

master = tk.Tk()
master.geometry("1500x600+30+30") 

fr1 = Frame(master, width=600, height=550, relief="sunken", bd=1)
fr1.grid(row=1, column=1)

# nummer, codierung
e_nummer = Entry(master, fr1)
e_nummer.grid(row=0, column=0)
e_codierung = Entry(master, fr1)
e_codierung.grid(row=1, column=0)
Wie lautet die korrekte Syntax, um die Widgets in den Frame zu bekommen?
Liebe Grüße
Strawk :)

P.S.: An Sirius3 - Ich habe ein ganzes Python-Buch minutiös durchgeackert. Meinst du nicht auch, irgendwann muss man mal das freie Programmieren anfangen? :)
Ich programmiere erfolglos, also bin ich nicht.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@Strawk: wie's richtig geht, hab ich ja schon letzten Sonntag gezeigt.
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

Strawk hat geschrieben:Hallo Nutzer! :D

Für meine Datenbank-GUI möchte ich zwei große Frames nebeneinander. Im linken die Eingabemaske aus 38 Entry- und Label-Feldern, im rechten eine großes Ausgabetextfenster mit vertikaler Scrollbar. Aktuelles Problem: die Widgets wollen nicht in den Frame wandern; ich erhalte die Meldung:
TypeError: Tkinter objects don't support 'in' tests.
Der entsprechende Code-Schnipsel:

...
Da in den gesamten Code-Schnipsel *kein* "in" vorkommt, passt der nicht zur Fehlermeldung.

Und bezueglich der Grundlagen: die scheinen immer noch zu fehlen, Buch durchgearbeitet hin oder her. Wir kommentieren hier was wir sehen.
Benutzeravatar
Strawk
User
Beiträge: 229
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

Hallo Sirius3, __deets__! :D

Sirius3, dein Beispiel funktioniert bei mir nicht. Auch nicht mit deinem Nachtrag und dem von narpfel. Ich arbeite mit Python 2.7 und der Shell "Anaconda Navigator / Spyder".

__deets__, im gesamten Skript ist kein "in". Die Bedeutung der Fehlermeldung muss wohl eine andere sein.

Ich möchte bitte für meinen Code nur die Syntax, wie ich die Widgets in den Frame bekommen. Danke!

Grüße
Strawk
:)
Ich programmiere erfolglos, also bin ich nicht.
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

@Strawk: widgets in ein anderes widget bekommt man, indem man das Objekt als parent-Objekt uebergibt. So, wie das in deinem von dir selbst geposteten Beispiel passiert. Wo also liegt die Unklarheit?

Und du packst eine Fehlermeldung dazu, die mit dem problem halt nichts zu tun hat. Was anderes kann man dazu nicht sagen :K
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@__deets__: das `in` steht ja auch in den Funktionen, die aufgerufen werden. Natürlich wäre da der gesamte Traceback hilfreich gewesen.

@Strawk: welche Python-Version Du im Moment benutzt, kann niemand erraten, weil Du die ständig wechselst. Ich schreibe hier keinen Code, der sofort benutzbar ist, sondern die Konzepte zeigen soll, die Du, wenn Du Dir die Mühe gemacht hast, zu verstehen, wie das Programm arbeitet, leicht auf Dein Problem übertragen kannst. Daher: mein Code zeigt wie man Widgets in Frames packt.
narpfel
User
Beiträge: 645
Registriert: Freitag 20. Oktober 2017, 16:10

@Strawk: Unter Python 2.7 heißt das Modul `Tkinter`. Von daher sieht das eher nach Python 3 aus. Was sagt `sys.version` (in der selben Umgebung wie das Programm ausgeführt)?

Zu der Fehlermeldung: Guck’ dir nochmal an, was für eine Signatur `tk.Entry` hat und was du übergibst. Ansonsten: Bitte poste den gesamten Traceback, nicht nur die letzte Zeile. Dann kann man schneller und einfacher den Fehler erkennen, ohne dabei raten zu müssen.

Zu dem Beispiel von Sirius3: Auch hier ist es im Sinne der Problemlösung hilfreich, wenn du den gesamten Traceback (und eventuell auch den Code, wenn du ihn verändert hast), zeigst.
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

Sirius3 hat geschrieben:@__deets__: das `in` steht ja auch in den Funktionen, die aufgerufen werden. Natürlich wäre da der gesamte Traceback hilfreich gewesen.
Ahhh. Jetzt erst sehe ich das.

@Strawk: du uebergibst Entry zwei Widgets. Willst offensichtlich, das das zweite davon der Parent ist. Warum also das erste ueberhaupt angeben?
Benutzeravatar
Strawk
User
Beiträge: 229
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

Hallo! :)

Bin jetzt einen Schritt weiter und die Widgets sind im Frame.

Aktuelles Problem: Ich habe die Datenbankabfrage in ein externes Skript und in eine dortige Funktion ausgelagert. Wie erreiche ich jetzt, dass das SQL-result im aufrufenden (Haupt-)Skript im Textfenster ausgegeben werden kann?

Bisher funktioniert das in beiden Richtungen nicht. Will heißen: Entweder kennt das Unter-Skript das Textfenster nicht, oder das Haupt-Skript kennt das SQL-result nicht. Gibt es einen Befehl, ein Objekt wie "result" global verfügbar zu machen? Oder wie anders realisiere ich das?

Grüße
Strawk
:D
Ich programmiere erfolglos, also bin ich nicht.
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

In dem Buch, das du ja so gruendlich durchgearbeitet hast, gibt es bestimmt auch eine Einfuehrung in Funktionsparameter und Rueckgabewerte, und deren Nutzung. Da noch mal nachschauen.
Benutzeravatar
Strawk
User
Beiträge: 229
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

Hallo __deets__!

Nein, zur skriptübergreifenden Übergabe steht im Einstiegsbuch nichts. Wäre es ein Ansatz, das SQL-Abfrageergebnis als Instanz einer Klasse zu gestalten? Wie sähe dann die Klassendefinition grob aus?

Grüße
Strawk
:?
Ich programmiere erfolglos, also bin ich nicht.
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

Natuerlich steht dazu etwas darin. Es behandelt Module, also die Aufteilung eines Programms in mehrere Teile. Und es behandelt Funktionen mit Parametern und Rueckgabewerten. Das findet sich im Inhaltsverzeichnis:

https://www.rheinwerk-verlag.de/einstie ... n_4374/toc

Deutlich vor der von dir angegebenen Seitennummer irgendwo bei 370.

Und die Ergebnisse einer Abfrage sind ja schon ein Objekt - naemlich ein Cursor. An sich kann man den auch einfach zurueckgeben. Allerdings kann man sich da Aerger einhandeln, weil dessen Gueltigkeit an der Verbindung und anderen Einfluessen haengt. Aber ein simples "return cursor.fetchall()" reicht, und du hast dein Objekt - eine Liste von Tupeln.
Benutzeravatar
Strawk
User
Beiträge: 229
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

Hallo __deets__!

Das funktioniert schon anhand einfacher Beispiele nicht.

Code: Alles auswählen

def testFunktion():
    a = 42
    return a

Code: Alles auswählen

import sys

sys.path.append('C:/Users/Karl Kraft/Documents/Programmierung_ausser_PHP/Python/Anaconda_Navigator/Liverecord_Python')

import aufgerufenes_skript_01
aufgerufenes_skript_01.testFunktion()
print a
ergibt
NameError: name 'a' is not defined
Grüße
Strawk
Ich programmiere erfolglos, also bin ich nicht.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ja, weil a nur im Namensraum der Funktion bekannt ist. Das schwirrt nicht einfach so im Raum. Schon gar nicht modulübergreifend. Aus solchen Gründen solltest du dich mit den Grundlagen beschäftigen, bevor du weiter an GUI-Programmierung herumdoktorst. Das dauert nun mal ein paar Monate bis man es drauf hat. Das lernt man nicht an 3 Abenden. Mit anderen Worten: Du hast gerade Plus und Minus gelernt und willst direkt zur Analysis übergehen. Das funktioniert eben nicht.
Zuletzt geändert von snafu am Sonntag 10. Dezember 2017, 17:22, insgesamt 1-mal geändert.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@Strawk: erstens ist das kein Skript das da aufgerufen wird, sondern Du importierst ein Modul, zweitens lergt man das Modul in ein Verzeichnis, das schon im Modulpfad ist (z.B. das aktuelle) drittens gibt man dem Modul einen sinnvollen Namen. Und jetzt lies nochmal nach, wie das mit den Funktionen funktioniert.
Benutzeravatar
Strawk
User
Beiträge: 229
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

Hallo!

Och, Leute, lasst euch doch nicht alles aus der Nase ziehen. Ja, ich gebe dir recht, dass das mindestens Monate, wenn nicht Jahre dauert. Aber ist denn eure Rolle im Forum, immer einfach nur zu sagen: Finde es selbst raus? Also, wie mache ich die Variable/das Objekt außerhalb nun bekannt?

Grüße
Strawk
:idea:
Ich programmiere erfolglos, also bin ich nicht.
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du musst einen rückgabewert schon an einen Namen binden. Der erscheint nicht magisch in dem Namensraum um die aufrufstelle herum.

Code: Alles auswählen

wert = funktion_die_was_tut()
Das steht auch so ganz bestimmt NICHT in deinem Buch. Du wirst nicht darum herum kommen, das nochmal anzuschauen.
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
Gibt es einen Befehl, ein Objekt wie "result" global verfügbar zu machen?
Unter Python nutzt man _keine_ globalen Namensraum, über den Werte von Variablen abgerufen werden können. Entweder nutzt du Instanzen von Objekten, deren Attribute Werte enthalten (können) oder du bindest einen Wert an die Rückgabe einer Funktion wie gezeigt.

Bei der GUI-Programmierung mit Python ist es _essentiell_ wichtig, dass man die Objektorientierung von Python verstanden hat - sonst wird das nix. Alle GUI-Frameworks, nicht nur Tkinter, nutzen das sehr umfassend. Mit Python anfangen und dann direkt eine (größere) GUI programmieren wollen geht nun mal in der Regel schief...
Aber ist denn eure Rolle im Forum, immer einfach nur zu sagen: Finde es selbst raus?

In der Tat sehen die meisten das hier als "Hilfe zur Selbsthilfe", zumindest bei den gängigen / nicht-schwierigen Problemen wie diesem hier.

Gruß, noisefloor
Antworten