@010010: Neben den Mehrfachimporten sind da auch explizite Importe dabei die überhaupt nicht verwendet werden.
Auf Modulebene sollte nur Code stehen, der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.
Definitionen von Funktionen mitten in anderen Code zu schreiben ist zudem noch einmal extra-unübersichtlich.
Abgekürzte Namen sollte man vermeiden, denn ein Name soll dem Leser vermitteln was der Wert bedeutet und nicht zum rätselraten zwingen. Mir ist zum Beispiel so gar nicht klar was das `n` in `nx` und `ny` bedeuten soll.
Namen sollten nicht nummeriert werden. Wenn man das tut, will man sich entweder bessere Namen ausdenken, oder eine Datenstruktur verwenden, statt einzelner Namen. Im Falle von `l1` ist die Zahl aber einfach nur überflüssig, und das `l` zu kurz für einen sinnvollen Namen. Das könnte sinnvoller einfach `label` heissen.
Das `className`-Argument ist nicht dazu da um den Titel von Fenstern zu setzen. Dazu gibt es die `title`-Methode. Die Verändert dann auch nichts an der Gross-/Kleinschreibung des übergebenen Wertes.
Funktionen und Methoden sollten alles was sie ausser Konstanten benötigen als Argumente übergeben bekommen und nicht auf magische Weise irgendwie aus der Umgebung verwenden. Das betrifft das `Label`-Objekt in `right()`. Hier braucht man dann entweder objektorientierte Programmierung (OOP); oder ein Closure per `functools.partial()`, oder ``lambda``-Ausdruck.
Funktionen werden üblicherweise nach ihrer Tätigkeit benannt. Also beispielsweise `move_right()` statt `right()`.
Um Gleichheitszeichen bei Schlüsselwortargumenten werden per Konvention *keine* Leerzeichen gesetzt.
Dem `tk.Button`-Objekt braucht man eigentlich keinen Namen geben. Auch sollte man das nicht mittels `place()` anordnen, denn so steht das ja mitten im Fenster. Beim `Label` gibt es ja den Grund, dass das frei bewegt werden können soll, aber `place()` sollte die Ausnahme sein.
Zwischenstand wäre dann so etwas in der Art:
Code: Alles auswählen
#!/usr/bin/env python3
from functools import partial
import tkinter as tk
#
# TODO Find better name to explain the `N_` prefix.
#
N_X = 5
N_Y = 5
def move_right(label):
label.place(x=N_X + 5)
def main():
window = tk.Tk()
window.title('Label Bewegen')
window.geometry('800x600')
label = tk.Label(window, bg='red', height=1, width=2)
label.place(x=N_X, y=N_Y)
tk.Button(
window, text='>>', height=2, width=2, command=partial(move_right, label)
).pack(side=tk.BOTTOM)
window.mainloop()
if __name__ == '__main__':
main()
Falls die versteckte Frage sein sollte warum das nur einen Schritt geht und bei weiteren klicks auf die Schaltfläche stehen bleibt: Weil es genau so im Code steht. Bei Klick das Label 5 Pixel neben der Konstanten `N_X` setzen.
Wenn das weiter wandern soll bei jedem Klick, dann darf man das nicht relativ zu einer Konstante, sondern muss den tatsächlich aktuellen X-Wert zugrunde legen. Da käme man zwar mit `pack_info()` heran, allerdings merkt man da das Tcl/Tk ”stringly typed” ist, also eigentlich nur Zeichenketten als einzigen Datentyp kennt. Bevor man da also anfängt wieder in Zahlen zu konvertieren um in Python damit rechnen zu können, sollte man besser auf OOP setzen und sich die Position selbst merken.