@MissMapeL: Vergiss ``global``, das ist Mist und wenn man tatsächlich Klassen verwenden würde, bräuchte man das auch gar nicht. Die Klassen sind entweder einfach nur überkomplex ausgedrückte Funktionen oder werden falsch verwendet.
Sternchen-Importe sind Böse™. Da holt man sich gerade bei `tkinter` fast 200 Namen ins Modul von denen nur ein kleiner Bruchteil verwendet wird. Auch Namen die gar nicht in `tkinter` definiert werden, sondern ihrerseits von woanders importiert werden. Das macht Programme unnötig unübersichtlicher und fehleranfälliger und es besteht die Gefahr von Namenskollisionen.
Die Importweiche für Python 2 kann man sich sparen. Python 2 ist am Ende. Und von dem Konstrukt wird im Modul auch überhaupt nichts verwendet, das kann also ohne das sich am Programmverhalten etwas ändert entfernt werden.
Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (MixedCase).
Namen nummeriert man nicht. Entweder ist die Nummer total sinnfrei, dann lässt man sie weg, oder man möchte sich einen eigenen, sinnvollen Namen ausdenken, oder man möchte gar keine einzelnen Namen sondern die Werte in einer Datenstruktur zusammenfassen.
`Toplevel1` ist keine Klasse. Das ist einfach nur eine Funktion.
Die Argumentnamen `name_of_top` und `name_der_form` sind falsch. Da wird kein Name übergeben sondern ein Elternwidget. Der Tk-Nomenklatur entsprechend `master`. Wenn man mit dem Namen ein moralisches Problem hat wäre `parent` nicht unüblich.
`form_auf_Top` ist ebenfalls keine Klasse sondern eine Funktion. Da *sollte* vielleicht Zustand gemerkt werden, denn Du willst auf die dort erstellten Eingabeelemente ja später woanders zugreifen, aber die Aufteilung ist so auch komplett Banane.
`place()` sollte man nicht verwenden. Auch nicht mit relativen Angaben. Man muss trotzdem noch die Grösse der GUI selbst angeben und die kann immer noch zu klein für den Inhalt sein.
`entry_auf_form()` ist keine Klasse, sondern eine Funktion. `farb_index` wird dort nicht verwendet.
Was sollen die Unterstriche bei den Argumentnamen? Das ist die Konvention für Argumente die da sein müssen weil die API das verlangt, die aber nicht verwendet werden. Bei Dir werden die Argumente mit dem führenden Unterstrich aber alle verwendet.
Wenig überraschend ist auch `button_auf_form1` keine Klasse. Die ”Klasse” hat zwar eine ”Methode”, die macht aber von dem Objekt auf dem sie definiert ist aber überhaupt gar keinen Gebrauch, ist also auch einfach nur eine Funktion.
Die Defaultwerte bei den ”Methoden” machen allesamt keinen Sinn weil bei jedem Aufruf dann doch alle angegeben werden und so etwas wie eine Defaultposition auch gar keinen Sinn macht.
`bind()` ist der falsche Weg die normale Aktion für einen `Button` anzugeben. Das Eingabeelement verhält sich dann nicht so wie der Benutzer das normalerweise von anderen Programmen gewohnt ist.
Funktionen und Methoden bekommen alles was sie ausser Konstanten benötigen als Argument(e) übergeben. Darum funktioniert Dein ``e1.get()`` & Co nicht, weil `e1` und `e2` undefiniert sind. Die Namen gab es mal lokal in der `form_auf_Top.__init__()` aber eben nur da und nur solange wie diese Methode ausgeführt wurde.
Den ``%``-Operator würde ich nicht mehr zum formatieren von Werten in Zeichenketten verwenden. Dafür gibt es die `format()`-Methode auf Zeichenketten und ab Python 3.6 f-Zeichenkettenliterale.
`print()` kennt ein `flush`-Argument, da braucht man `sys.stdout.flush()` nicht.
Die ”Klassen” als Funktionen geschrieben sähe das so aus:
Code: Alles auswählen
#!/usr/bin/env python3
import tkinter as tk
from functools import partial
def create_entry(master, relx, rely, relwidth, relheight):
entry = tk.Entry(master)
entry.place(relx=relx, rely=rely, relwidth=relwidth, relheight=relheight)
return entry
def on_button(first_name_entry, last_name_entry):
print(
f"First Name: {first_name_entry.get()}\n"
f"Last Name: {last_name_entry.get()}",
flush=True,
)
def create_button(
master,
text,
first_name_entry,
last_name_entry,
relx,
rely,
relwidth,
relheight,
):
button = tk.Button(
master,
text=text,
pady=0,
command=partial(on_button, first_name_entry, last_name_entry),
)
button.place(relx=relx, rely=rely, relwidth=relwidth, relheight=relheight)
return button
def populate_widget(master):
frame = tk.Frame(master, background="red")
frame.place(relx=0.05, rely=0.05, relheight=0.9, relwidth=0.9)
first_name_entry = create_entry(frame, 0.2, 0.25, 0.15, 0.05)
last_name_entry = create_entry(frame, 0.6, 0.25, 0.15, 0.05)
create_button(
frame,
"drucken",
first_name_entry,
last_name_entry,
0.2,
0.55,
0.55,
0.15,
)
def configure_and_populate_toplevel(toplevel):
toplevel.geometry("800x600+279+154")
toplevel.configure(background="lightblue")
populate_widget(toplevel)
def main():
root = tk.Tk()
configure_and_populate_toplevel(root)
root.mainloop()
if __name__ == "__main__":
main()
Das ist aber sehr komisch strukturiert. Die beiden `create_*()`-Funktionen sind kaum mehr als Zusammenfassen von erstellen eines Widgets und den `place()`. Und die `create_button()` ist auch ein bisschen sehr speziell, weil da ein festes Verhalten für die Aktion hinter dem Button auch gleich mit drin ist. Bei `configure_and_populate_toplevel()` ist im Namen schon abzulesen das die Funktion vielleicht zu viel tut.
Was letztlich von dem ganzen Code übrig bleibt ist das hier:
Code: Alles auswählen
#!/usr/bin/env python3
import tkinter as tk
from functools import partial
def on_button(first_name_entry, last_name_entry):
print(
f"First Name: {first_name_entry.get()}\n"
f"Last Name: {last_name_entry.get()}",
flush=True,
)
def main():
root = tk.Tk()
root.geometry("800x600+279+154")
root.configure(background="lightblue")
frame = tk.Frame(root, background="red")
frame.place(relx=0.05, rely=0.05, relheight=0.9, relwidth=0.9)
first_name_entry = tk.Entry(frame)
first_name_entry.place(relx=0.2, rely=0.25, relwidth=0.15, relheight=0.05)
last_name_entry = tk.Entry(frame)
last_name_entry.place(relx=0.6, rely=0.25, relwidth=0.15, relheight=0.05)
tk.Button(
frame,
text="drucken",
pady=0,
command=partial(on_button, first_name_entry, last_name_entry),
).place(relx=0.2, rely=0.55, relwidth=0.55, relheight=0.15)
root.mainloop()
if __name__ == "__main__":
main()