• Home
  • |
  • Blog
  • |
  • Python Tkinter Tutorial #9 – Das Tkinter Button Widget

Python Tkinter Tutorial #9 – Das Tkinter Button Widget

Zuletzt aktualisiert: September 17, 2024

Heute wirst du das Tkinter Button Widget kennenlernen, welches man nahezu immer verwendet und deshalb unheimlich nützlich ist. Im bisherigen Verlauf dieser Tutorial-Reihe haben wir uns lediglich das Label-Widget angesehen. Die kommenden Beiträge werden also noch um einiges interessanter.

Inhaltsverzeichnis

1. Ein Tkinter Button Widget erstellen

Um direkt loszulegen, erzeugen wir uns jetzt schon mal ein Tkinter Button Widget innerhalb unserer Entwicklungsumgebung. Dafür definieren wir zunächst eine Variable, die wir beispielhaft button1 nennen und weisen dann Folgendes zu:

root.geometry("400x400")

 button1 = ttk.Button()

 root.mainloop()

Auch hier schreiben wir wieder an erster Stelle zwischen die Klammern „root“ und übergeben als Text beispielsweise „Klick mich!“.

root.geometry("400x400")

 button1 = ttk.Button(root, text="Klick mich!")

 root.mainloop()

Wie du siehst, ist der Name der Klasse, von welcher wir das Objekt erzeugen, „Button“. Auch hier geben wir als erstes Argument wieder den Parent root an, bei welchem es sich um unser Hauptfenster handelt. Ein Button kann zudem genau wie ein Label einen Text besitzen, weshalb wir die text-Option direkt mithilfe des Strings „Klick mich!“ setzen.

Mit der pack-Methode können wir diesen Button nun wieder wie gewohnt in der GUI platzieren:

button1 = ttk.Button(root, text="Klick mich!")
button1.pack()

Wenn wir das Programm jetzt ausführen, sehen wir tatsächlich einen Button innerhalb unseres GUI-Fensters, der sich sogar klicken lässt:

Ein Tkinter Button, auf den man klicken kann

Natürlich passiert noch nichts, solange wir das noch nicht explizit implementiert haben. Die Klick-Funktion kann sich allerdings schon mal sehen lassen.

2. Die Position des Buttons festlegen

Auch bei diesem Button können wir der pack-Methode, wie bereits in Artikel 5 dieser Tutorial-Reihe gezeigt, gewisse Schlüsselwortargumente übergeben. Wir könnten also beispielsweise wieder festlegen, dass der Button nicht standardmäßig mit side=“top“ platziert werden soll, sondern links oder rechts. Für unser Beispiel wählen wir links:

button1 = ttk.Button(root, text="Klick mich!")
button1.pack(side="left")

Nachdem wir das Programm so ausgeführt haben, befindet sich der Button nun links:

Der Tkinter Button ist nun links ausgerichtet

3. Die Schlüsselwortargumente fill und expand einsetzen

Genauso funktionieren an dieser Stelle und bei allen anderen Widgets, die noch folgen, die Schlüsselwortargumente fill und expand, welche du ebenfalls im fünften Teil dieser Tutorial-Reihe kennengelernt hast.

Wir können jetzt also zum Beispiel anstelle von side=“left“, fill=“x“ angeben:

button1 = ttk.Button(root, text="Klick mich!")
button1.pack(fill="x")

Wenn wir das Programm so ausführen, sehen wir, dass sich der Button nun über den gesamten x-Bereich, also die x-Achse erstreckt:

Der Tkinter Button erstreckt sich nun über die gesamte x-Achse

Mit expand=“true“ könnten wir diesen dann wieder anweisen, auch den kompletten möglichen Platz in die vertikale Richtung zu allokieren, also nach unten. Das werde ich an dieser Stelle allerdings nicht noch einmal demonstrieren, da wir dieses Thema schließlich bereits im fünften Beitrag dieser Tutorial-Reihe ausführlich besprochen haben.

4. Mögliche Optionen vom Tkinter Button Widget anzeigen lassen

Vielmehr möchte ich dir jetzt zeigen, welche Optionen man bei einem Tkinter Button Widget setzen kann.

Dazu können wir uns wieder mit unserem kleinen Trick behelfen, indem wir folgenden Code schreiben:

button1 = ttk.Button(root, text="Klick mich!")
button1.pack()

for item in button1.keys():
            print(item, ": ", button1[item])

Wenn wir das Programm nun ausführen, sehen wir auf der Konsole alle möglichen Optionen. Zwei Optionen, die wieder sofort ins Auge stechen, sobald wir etwas weiterscrollen, sind image und compound.

Wir sehen die Optionen image und compound

Diese kennen wir bereits vom Label-Widget. Das heißt, wir können in den Button neben dem Buttontext auch ein Bild integrieren und mit compound wieder festlegen, wie das Bild platziert werden soll. 

Wie das Ganze mit den Optionen image und compound funktioniert, möchte ich an dieser Stelle auch kein weiteres Mal wiederholen, da wir uns das bereits ausführlich im 7. Beitrag dieser Tutorial-Reihe angesehen haben, in welchem es im Detail um das Label Widget ging.

Wenn dich das also interessieren sollte, spring gerne noch mal zurück zum 7. Beitrag dieser Reihe, um das Thema anzusehen.

5. Die Option padding setzen

Zudem sehen wir beispielsweise, dass wir auch die Option padding setzen können. Das probieren wir direkt einmal aus. Hierzu bewegen wir uns in den Code und legen für padding beispielhaft den Wert 10 fest:

button1 = ttk.Button(root, text="Klick mich!", padding=10)
button1.pack()

Wenn wir das Programm jetzt ausführen, sehen wir, dass der Button tatsächlich ein Padding besitzt. Es gibt nun also einen Abstand von 10 Pixeln nach oben, was sich auf der Abbildung sehr gut erkennen lässt:

Auf der Abbildung erkennt man das Padding über dem Tkinter Button

Das funktioniert also einwandfrei. An dieser Stelle haben wir den Button schon mal etwas modifiziert, da er nun sowohl einen Text als auch ein Padding besitzt.

6. Die command-Option

Sinnvoll wäre jetzt noch, wenn beim Klicken auf den Button etwas passieren würde. 

Denn aktuell können wir so oft wir möchten auf den Button klicken, ohne dass etwas geschieht. Das ist auch gut so, da wir schließlich noch nicht programmiert haben, was das Programm umsetzen soll. Genau das ändern wir jetzt. 

Wenn wir hierzu noch einmal einen Blick auf die Konsole werfen und uns ansehen, welche Optionen uns darüber hinaus angeboten werden, sehen wir direkt zu Beginn die Option command.

Auf der Konsole sehen wir die command-Option

Der Begriff „command“ bedeutet ins Deutsche übersetzt „Befehl“. Das heißt, wir können innerhalb unseres Python-Programms eine Funktion programmieren und den Namen der Funktion der Option command zuweisen.

Damit ist die Funktion dann an den Button gekoppelt und das bedeutet, dass die entsprechende Funktion ausgeführt wird, sobald wir den Button klicken.

7. Mit command „auf Knopfdruck“ eine Funktion ausführen

Setzen wir das Ganze also direkt einmal in der Praxis um. Im ersten Schritt programmieren wir oben im Code eine beliebige Funktion, die wir beispielhaft say_hello nennen. Darin geben wir an, dass lediglich eine print-Funktion aufgerufen werden soll, in welcher wir „Hallo, danke dass du mich geklickt hast!“ übergeben:

from tkinter import ttk

def say_hello():
            print("Hallo, danke dass du mich geklickt hast!")

root = tk.Tk()

Dieser Satz soll auf der Konsole ausgegeben werden, wenn wir auf den Button klicken. Jetzt übergeben wir bei der Erzeugung des Button-Objekts noch das command-Schlüsselwortargument:

button1 = ttk.Button(root, text="Klick mich!", padding=10, command=)
button1.pack()

Hier ist jetzt wichtig, dass wir nur den Bezeichner der Funktion angeben, also say_hello:

button1 = ttk.Button(root, text="Klick mich!", padding=10, command=say_hello)
button1.pack()

Die runden Klammern, die wir am Ende des Funktionsnamens normalerweise anfügen würden, um die Funktion aufzurufen, lassen wir an dieser Stelle ganz bewusst weg.

Wenn wir das Programm jetzt ausführen und direkt den Button klicken, sehen wir, dass auf der Konsole tatsächlich der Text ausgegeben wird:

Mit Klick auf den Tkinter Button wird der Text auf der Konsole ausgegeben

Klicken wir öfter darauf, gibt das Programm den Text entsprechend mehrmals aus. Das heißt, wir haben damit mithilfe der Option command die Funktion say_hello erfolgreich an diesen Button gebunden

8. Diesen Fehler muss man vermeiden

Ein sehr häufiger Fehler, den Anfänger an dieser Stelle oftmals begehen, ist, dass sie dem Funktionsnamen noch aus Gewohnheit die runden Klammern anhängen.

Sie schreiben also beim Zuweisen an die command-Option hinter say_hello noch ein rundes Klammerpaar, wie es im folgenden Codeabschnitt zu erkennen ist:

button1 = ttk.Button(root, text="Klick mich!", padding=10, command=say_hello())
button1.pack()

Wenn wir das Programm jetzt ausführen und auf den Button klicken, dann sehen wir, dass vermeintlich erst mal gar nichts in der Konsole passiert.

9. Was ein rundes Klammerpaar hinter der Funktion auslöst

Scrollen wir nun allerdings in der Konsole weiter nach oben, stellen wir fest, dass die Funktion sehr wohl aufgerufen wurde:

Die say_hello Funktion wurde aufgerufen

Und zwar nicht, als wir den Button geklickt haben, sondern als das Programm Zeile für Zeile durchlaufen wurde. An der Stelle, an der wir die Funktion say_hello aufrufen, indem wir sie an die command-Option zuweisen, wird die Funktion auch tatsächlich aufgerufen.

Folglich gibt das Programm den String auf der Konsole aus und arbeitet dann den Rest des Codes ab. Das heißt, anschließend führt es noch die for-Schleife aus, weshalb uns zudem noch die Optionen in der Konsole ausgegeben werden.

Wichtig zu verstehen ist, dass bei einem Klick auf den Button nichts passiert.
Beim Klick auf den Tkinter Button geschieht nichts

Das liegt daran, dass wir die Funktion nicht an den Buttonklick gekoppelt haben. Da wir sie direkt aufrufen, wird der Rückgabewert der Funktion an den Button gekoppelt.

Allerdings haben wir innerhalb der Funktionsdefinition oben keine return-Anweisung, mit der wir etwas zurückgeben: 

from tkinter import ttk

def say_hello():
            print("Hallo, danke dass du mich geklickt hast!")

Aus diesem Grund wird automatisch der Wert none zurückgegeben, bei welchem nichts geschieht. Das bedeutet, wir haben an den Buttonklick gekoppelt, dass das Programm none ausführt. Da dadurch nichts passiert, macht das natürlich keinen Sinn.

Merke dir also: Wenn du der command-Option eine Funktion zuweist, dann weise dieser immer nur den Bezeichner der Funktion zu, ohne die runden Klammern dahinter aufzurufen:

button1 = ttk.Button(root, text="Klick mich!", padding=10, command=say_hello())

button1.pack()

Wenn wir das Programm an dieser Stelle noch einmal ohne die runden Klammern nach dem Funktionsnamen ausführen, sehen wir, dass es jetzt so funktioniert wie wir uns das vorstellen. Klicken wir dreimal auf den Button, dann erhalten wir auch dreimal den Text in der Konsole:

Ohne rundes Klammerpaar funktioniert der Tkinter Button wie gewünscht

10. Mit einem Tkinter Button Widget die Anwendung beenden

Man hat sogar die Möglichkeit, einen Button zu erstellen, der das Fenster schließt und die Anwendung damit beendet. Das werde ich dir auch direkt einmal zeigen. Wir bauen dafür einen weiteren Button in unsere Anwendung, den wir beispielhaft quit_button nennen:

button1.pack()

quit_button

for item in button1.keys():

Diesem weisen wir wieder ttk.Button zu, wählen als Parent wie gewohnt root, womit unser Hauptfenster gemeint ist und übergeben als Text „Programm beenden“. Schließlich ist das die Aktion, die der Button gleich vollziehen soll. 

button1.pack()

quit_button = ttk.Button(root, text="Programm beenden", 

for item in button1.keys():

11. Die destroy-Funktion

Jetzt müssen wir noch einen entsprechenden Command übergeben, wofür wir keine eigene Funktion programmieren, da es bereits eine gibt. Auf diese können wir zurückgreifen, um das Programm zu beenden. Wir schreiben dafür root.destroy und verzichten wieder auf die runden Klammern dahinter:

button1.pack()

quit_button = ttk.Button(root, text="Programm beenden", command=root.destroy)

for item in button1.keys():

Damit der Button sichtbar ist, müssen wir diesen natürlich mit pack in die GUI packen: 

button1.pack()

quit_button = ttk.Button(root, text="Programm beenden", command=root.destroy)
quit_button.pack()

Wenn wir das Programm jetzt noch einmal ausführen, sehen wir ab sofort zwei Buttons. Klicken wir auf den Button mit der Aufschrift „Klick mich!“, wird weiterhin die Funktion say_hello mit jedem Klick ausgeführt, was sich auf der Konsole erkennen lässt. Wenn wir auf „Programm beenden“ klicken, wird das Programm direkt beendet.

Mit Klick auf den Tkinter Button "Programm beenden" schließt sich das Fenster

Wie du damit gesehen hast, können wir mit einem Button schon mal spannende Dinge anstellen. Wenn wir jetzt noch mal einen Blick auf die Konsole werfen, erkennen wir als weitere mögliche Option state, welche aktuell als normal angezeigt wird:

In der Konsole sehen wir die Option state

Schauen wir uns nun auch diese Option im Detail an.

12. Die Option state

Wir haben die Möglichkeit, einen Button auf den state „normal“ oder auf „disabled“, also „ausgeschaltet“, zu setzen.

Im normalen Zustand lässt sich der Button klicken, bei disabled hingegen nicht.

13. Der state DISABLED

Wir setzen den Button jetzt also mal von Beginn an auf den state disabled, indem wir oben im Code als weiteres Schlüsselwortargument Folgendes übergeben:

button1 = ttk.Button(root, text="Klick mich!", padding=10, command=say_hello, state=tk.DISABLED)

button1.pack()

Wenn wir das Programm jetzt ausführen, fällt auf, dass der Button zwar innerhalb der GUI angezeigt, aber etwas ausgegraut dargestellt wird:

Der Tkinter Button "Klick mich!" ist nun ausgegraut

Beim Klicken auf den Button passiert nichts. Das liegt daran, dass wir ihn mithilfe der state-Option sozusagen deaktiviert haben. Der Default-Wert für state ist aber wie gesagt „normal“, was bedeutet: Wenn wir die state-Option nicht explizit selbst setzen, ist der Button immer auf dem state „normal“, wie beispielsweise der Button „Programm beenden“. Das heißt, dass wir ihn ganz normal verwenden können. 

Wenn wir also beispielhaft darauf klicken, schließt sich das Programm tatsächlich.

14. Der state NORMAL

Darüber hinaus könnten wir den Button über die state-Option explizit auf den Zustand „normal“ setzen, indem wir im Code tk.NORMAL schreiben:

button1 = ttk.Button(root, text="Klick mich!", padding=10, command=say_hello, state=tk.NORMAL)

button1.pack()

Wenn wir diese Zeile weglassen würden, könnten wir wie bereits erwähnt, mit dem gleichen Ergebnis rechnen.

Beim Ausführen des Programms sehen wir, dass wir den Button tatsächlich wieder klicken können.

Sobald man zum ersten Mal von der state-Option gehört hat, empfindet man diese möglicherweise zunächst einmal als nutzlos, allerdings kann man damit tatsächlich sinnvolle Dinge umsetzen.

15. Wie man die state-Option in der Praxis einsetzen kann

Stell dir beispielsweise einmal vor, du schreibst eine grafische Benutzeroberfläche, über welche später eine reale Fertigungsmaschine gesteuert wird, die ein Bauteil innerhalb einer Fabrik produziert.

Wenn man die Maschine starten möchte, fährt die grafische Benutzeroberfläche hoch und über einen Startbutton lässt sich der Produktionsprozess einleiten. 

Nun muss die Maschine allerdings erst mal vorheizen, bevor sie ein Bauteil korrekt produzieren kann. Denn wenn sie beispielsweise zu kalt ist und somit die Betriebstemperatur nicht erreicht hat, produziert sie zwar dennoch die Bauteile, allerdings in einem schlechten Zustand, sodass diese letzten Endes entsorgt werden müssen.

Das möchte man natürlich vermeiden und an dieser Stelle kommt auch schon die state-Option ins Spiel. Damit kann man nämlich programmieren, dass der Button, der den Produktionsprozess startet, erst dann geklickt werden kann, wenn die Betriebstemperatur erreicht ist. Bevor die Betriebstemperatur erreicht ist, soll der Button nicht klickbar sein. Demnach lässt sich die state-Option also tatsächlich sinnvoll in einem Programm einsetzen.

Jetzt, da du die state-Option kennengelernt hast, kannst du diese auf kreative Weise in deinem eigenen Programm implementieren. 

Damit weißt du auch schon über die wichtigsten Features des Tkinter Button Widgets Bescheid und kannst im folgenden Beitrag direkt am nächsten Widget anknüpfen.