Seite 1 von 5

GUI – 38 Eingabefelder und 38 Beschriftungen

Verfasst: Samstag 2. Dezember 2017, 13:20
von Strawk
Hallo Nutzer! :)

Ich möchte meine HTML/PHP-Anwendung „Liverecord“ in Python umschreiben. Das Buch

THEIS, Thomas: Einstieg in Python. Ideal für Programmieranfänger. – Bonn: Rheinwerk Verlag GmbH 5., aktualisierte Auflage 2017 (4525)

habe ich bis Seite 387 minutiös durchgearbeitet. Leider scheitere ich noch daran, 38 Eingabefelder und ihre 38 Beschriftungen in einer tkinter-GUI schön anzuordnen. Bitte seht auf dem beigefügten Bild, wie die Sache aussehen soll. http://www.bilder-upload.eu/show.php?fi ... 217278.jpg

Weil ich mit mySQL und XAMPP arbeite, kann ich kein Python 3.6 benutzen, sondern bin auf Python 3.4 angewiesen.

Was sind die Layout-Manager „pack“, „grid“ und „place“, wie muss ich sie benutzen?

So weit bin ich bisher gekommen:

Code: Alles auswählen

import tkinter

def ende():
    main.destroy()

main = tkinter.Tk()

# 38 Eingabefelder mit Beschriftung

# Eingabefeld nummer
lb1 = tkinter.Entry(main, text= "")
'''
lb1["font"] = "Arial 8"
lb1["height"] = 1
lb1["width"] = 30
lb1["anchor"] = "w"
'''
lb1.pack(padx=100, pady=10)
# Eingabefeld nummer Beschriftung
lb1b = tkinter.Label(main, text = "nummer")
lb1b.pack(padx=100, pady=10)

main.mainloop()
Erbitte dringend eure wertvollen Tipps!

euer
Strawk

Re: GUI – 38 Eingabefelder und 38 Beschriftungen

Verfasst: Samstag 2. Dezember 2017, 14:16
von __deets__
Das es Place gibt, solltest du schnell vergessen. Außer in sehr speziellen Situationen will man das nicht, weil es auf verschiedenen Rechnern mit anderen fonts und Bildschirmauflösungen dann schlecht aussieht. Und auch einem selbst viel Arbeit macht, wenn man zb ein Label vergrößert und manuell alles anschieben muss.

Grid und pack sind dein Freund. Und dein Problem ist einfach ein Grid 3x4 mit jeweils einem frame in dem du ein vertikales pack der 6 Widgets machst.

Re: GUI – 38 Eingabefelder und 38 Beschriftungen

Verfasst: Samstag 2. Dezember 2017, 14:28
von Strawk
Hallo!

Könntest du mir dazu einen Beispielcode posten? Danke!

Grüße,
Strawk

Re: GUI – 38 Eingabefelder und 38 Beschriftungen

Verfasst: Samstag 2. Dezember 2017, 15:00
von __deets__
Nein. Ich bin hier auf dem iPad unterwegs, da Programmier es sich nicht so gut. Man kann Grid Beispiele aber auch im Netz suchen. http://effbot.org/tkinterbook/grid.htm

Nachtrag: effbot suggeriert dabei sogar das man nur Grid verwendet. Dann wird dein Problem viel einfacher. Denn dann sind es pro Widget (Label oder Entry) eine Koordinate.

Re: GUI – 38 Eingabefelder und 38 Beschriftungen

Verfasst: Samstag 2. Dezember 2017, 15:13
von Strawk
Hallo __deets__!

Ich bitte dich um einen lauffähigen Beispielcode, wenn du wieder daheim bist.

:)
Grüße,
Strawk

Re: GUI – 38 Eingabefelder und 38 Beschriftungen

Verfasst: Samstag 2. Dezember 2017, 16:50
von __deets__
Ich bin zuhause. Aber wenn ich den Rechner aufklappe, geht immer sich gleich das Rechnungsprogramm an, mit dem ich dir Programmieraufträge abrechne.

Alternativ kannst du das lauffähige Beispielprogramm aus dem Link von mir probieren und dich damit dann vertraut machen mit dem Grid Layouter. Wenn dann konkrete Fragen auftauchen, beantworte ich die gerne am iPad.

Modularisieren, zweites Skript aufrufen und Werte übergeben

Verfasst: Sonntag 3. Dezember 2017, 10:08
von Strawk
Hallo __deets__ :)

Erstmal vielen Dank für deine Hilfe. Hier siehst du meine bisherige GUI.

http://www.bilder-upload.eu/show.php?fi ... 292214.jpg

Sieht doch schon ganz passabel aus, nicht wahr?

Ich möchte nun testweise in die Felder Werte eintragen. Ein zweites Skript soll aufgerufen werden und die Werte ausgeben, mit „print“. Nun habe ich aber von Python-Modularisierung keine Ahnung. In PHP machte ich das mit „post“ und „get“. Wie modularisiert man eine Python-Anwendung?

Erbitte deine wertvollen Tipps!

Strawk
:)

Re: GUI – 38 Eingabefelder und 38 Beschriftungen

Verfasst: Sonntag 3. Dezember 2017, 10:13
von Sirius3
@Strawk: was meinst Du mit zweitem Skript? Reicht Dir nicht, eine Funktion aufzurufen? Für's erste kann das dann auch alles in einer Datei stehen. Sollte das Skript mit der Zeit doch zu groß werden, kann man immer noch eine Einteilung in mehrere Module vornehmen.

Re: GUI – 38 Eingabefelder und 38 Beschriftungen

Verfasst: Sonntag 3. Dezember 2017, 10:21
von Strawk
Hallo Sirius3!

Das Ursprungsprogramm in PHP besteht aus 19 Skripten. Mein Ziel ist die Übertragung in Python. Eine Datenbank soll angesprochen und verändert werden können. Denke, ich komme um Modularisierung nicht drum rum.

Grüße
Strawk
:o

Re: GUI – 38 Eingabefelder und 38 Beschriftungen

Verfasst: Sonntag 3. Dezember 2017, 12:17
von __deets__
Schön das du weitergekommen bist!

Das ein größeres Projekt modularisiert ist stimmt schon. Nur wirkt es so als ob du hier konkret versuchst, die gleiche Einteilung wie in PHP einzuführen. Und das ist fraglich. Es gibt ja technische Gründe, warum die Web Anwendung aufgebaut ist wie sie ist. Nämlich um die benötigten URL-Pfade zu erzeugen. Aber bei der GUI hast du diese Anforderungen ja nicht. Du kannst oder solltest also entlang anderer Grenzen schneiden.

Die Frage ist, welche das sind. Wenn du eine DB ansprichst, dann kann es zB sinnvoll sein, eben diese und die Operationen welche auf ihr durchgeführt werden in ein extra Modul zu packen.

Und das Modul System von Python ist gut dokumentiert, inklusive einer Tutorial-Sektion. Das einzige, das daran IMHO etwas schwierig ist, ist das Thema der Suchpfade. Aber das kriegen wir hin.

Hat deine Anwendung einen Namen?

Re: GUI – 38 Eingabefelder und 38 Beschriftungen

Verfasst: Sonntag 3. Dezember 2017, 13:24
von Sirius3
Hier noch der Code zum Erzeugen des Formulars.

Code: Alles auswählen

import tkinter as tk

LABELS = ["Name", "Geburtsname","Vorname",
    "Straße", "PLZ", "Ort",
    "Ortsteil", "Bundesland", "Land",
    "Fahrzeugfabrikat", "Fahrzeugtyp", "Kennzeichen",
    "Landesvorwahl", "Ortsvorwahl", "Telefonnummer",
    "aktiv", "Mobilvorwahl", "Mobilnummer",
    "Email 1", "Email 2", "URL"]

def generate_form(window, labels):
    entries = []
    for idx, label in enumerate(labels):
        framenum, idx = divmod(idx, 3)
        if idx == 0:
            frame = tk.Frame()
        entry = tk.Entry(frame)
        entry.pack()
        entries.append(entry)
        lb = tk.Label(frame, text=label)
        lb.pack()
        if idx == 2:
            row, column = divmod(framenum, 3)
            frame.grid(row=row, column=column, padx=5, pady=15)
    return entries

class Main(tk.Tk):
    def __init__():
        super(Main, __init__)(self)
        self.entries = generate_form(self, LABELS)

def main():
    root = Main()
    root.mainloop()

if __name__ == '__main__':
    main()

Re: GUI – 38 Eingabefelder und 38 Beschriftungen

Verfasst: Sonntag 3. Dezember 2017, 14:02
von Strawk
Hallo!

Ich habe seinerzeit das PHP-Projekt "Liverecord" getauft.

Momentan läuft meine GUI nicht mehr. Vor dem letzten Rechner-Ausschalten ist sie noch gelaufen.

Code: Alles auswählen

import Tkinter as tk

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

# Hauptfenster
master = tk.Tk()
master.geometry("800x600+30+30") 

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

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

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

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

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

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

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

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

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

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

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

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

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

def buttonSucheClick():
    nummer = str(e_nummer)
    # codierung = str(e_codierung.get())
    
buttonSuche = Button(master, text="Suche", width="4", command=buttonSucheClick)
buttonSuche.grid(row=30, column=0)

root.mainloop()

print(nummer)
Fehlermeldung: "NameError: name 'Entry' is not defined"

Sirius3, dein Code läuft auch nicht, Fehlermeldung: "TypeError: __init__() takes no arguments (1 given)"

Grüße
Strawk
:(
:D

Re: GUI – 38 Eingabefelder und 38 Beschriftungen

Verfasst: Sonntag 3. Dezember 2017, 14:24
von __deets__
Du hast den import verdaddelt. Entry ist im tkinter Modul. Du importierst das als tk, also musst du tk.Entry schreiben.

Für eine so umfangreiche Anwendung wirst du um Objekt orientierte Programmierung nicht rum kommen. Hast du dich damit schonmal beschäftigt? Dann kannst du auch den Fehler von Sirius selbst beheben.

Re: GUI – 38 Eingabefelder und 38 Beschriftungen

Verfasst: Sonntag 3. Dezember 2017, 14:33
von Strawk
Hallo!

Ja, mit

tk.Entry
tk.Label
tk.Button

funktioniert es. Ja, ich kenne mich mit OOP einigermaßen aus. Den Fehler von Sirius3 habe ich aber noch nicht gefunden.

Grüße
Strawk
:)

Re: GUI – 38 Eingabefelder und 38 Beschriftungen

Verfasst: Sonntag 3. Dezember 2017, 15:12
von __deets__
Wie sieht denn normalerweise ein konstruktiv aus? Da fehlt doch was bei ihm. Und der Aufruf von super ist auch nicht super. Schau mal genau hin.

Re: GUI – 38 Eingabefelder und 38 Beschriftungen

Verfasst: Sonntag 3. Dezember 2017, 16:10
von __deets__
Konstruktor. Nicht konstruktiv. Doofes iPad.

Re: GUI – 38 Eingabefelder und 38 Beschriftungen

Verfasst: Montag 4. Dezember 2017, 09:25
von Strawk
Hallo!

Mit der bekannten GUI möchte ich derzeit nur erreichen, dass in einem Anzeige-Label ausgegeben wird, was ins Feld "nummer" eingetragen wurde. Jedoch erhalte ich ständig:
AttributeError: 'NoneType' object has no attribute 'get'
Bei einem Vergleichsprogramm funktioniert das tadellos und ich habe keinerlei Idee, wo der Unterschied sein soll.

Erbitte Hilfe!
Grüße
Strawk

Re: GUI – 38 Eingabefelder und 38 Beschriftungen

Verfasst: Montag 4. Dezember 2017, 09:43
von Sirius3
@Strawk: die Glaskugel sagt nur Schneegestöber und der Kaffeesatz ist schon in der Bio-Tonne.

Ach ja, Nachtrag:

Code: Alles auswählen

class Main(tk.Tk):
    def __init__(self):
        super(Main, self).__init__()
        self.entries = generate_form(self, LABELS)

Re: GUI – 38 Eingabefelder und 38 Beschriftungen

Verfasst: Montag 4. Dezember 2017, 10:08
von narpfel
`super` ist in Python 3 noch superer geworden:

Code: Alles auswählen

class Main(tk.Tk):
    def __init__(self):
        super().__init__()
        self.entries = generate_form(self, LABELS)
Die beiden Argumente sind optional.

Re: GUI – 38 Eingabefelder und 38 Beschriftungen

Verfasst: Montag 4. Dezember 2017, 12:49
von Strawk
Hallo!

Ich konnte das Unter-Problem identifizieren.

Code: Alles auswählen

e_nummer = tkinter.Entry(master).grid(row=0, column=0)
funktioniert nicht und macht:
AttributeError: 'NoneType' object has no attribute 'get'
Aber

Code: Alles auswählen

e_nummer = tkinter.Entry(master)
e_nummer.grid(row=0, column=0)
funktioniert.

Grüße
Strawk
:D