In diesem Beitrag werden wir uns den Unterschied zwischen den tk Widgets und den ttk Widgets im Detail ansehen.
Inhaltsverzeichnis
1. Warum Label Widgets allein nicht reichen
Im früheren Verlauf dieser Tutorial-Reihe haben wir bisher nur mit einer Art von Widget gearbeitet, nämlich mit Labels. Allerdings kann man mit Labels allein noch keine wirklich sinnvollen Anwendungen programmieren.
Genau deshalb werden wir uns in den kommenden Beiträgen auch noch weitere Widgets ansehen. Mit Kenntnis über diese Widgets können wir dann auch schon unsere ersten Anwendungen bauen und ab dann fängt die Programmierung mit Python und Tkinter so richtig an, Spaß zu machen.
Zuvor muss ich dir allerdings in diesem Blogartikel noch etwas sehr Wichtiges erklären: den Unterschied zwischen den sogenannten tk Widgets und den ttk Widgets.
Das werde ich dir anhand eines kleinen Beispiels mit einem Label Widget zeigen, da wir dieses bereits kennen.
2. Ein Label Widget erzeugen
Das Python File, in welchem wir starten, sieht aktuell folgendermaßen aus:
Bisher haben wir im Verlauf des Kurses Label Widgets erzeugt, indem wir eine Variable definiert und dieser ein Label-Objekt zugewiesen haben.
Genau das setzen wir jetzt beispielhaft um. Der Text soll dabei 'Label 1' lauten und zudem vergeben wir einen Hintergrund in der Farbe Grün:
label1 = tk.Label(root, text="Label 1", bg="green")
root.mainloop()
Anschließend müssen wir das Ganze mithilfe des Pack Layout Managers noch in die GUI packen:
label1 = tk.Label(root, text="Label 1", bg="green")
label1.pack()
In anderen Worten haben wir beim Erzeugen eines Labels im Namensraum von Tkinter ein Objekt der Klasse Label erzeugt.
3. Was sind tk Widgets?
Wenn wir ein Label Widget auf diese Art und Weise erzeugen, handelt es sich dabei um ein normales tk Widget. Das sind die Widgets, die Tkinter bereits von Anfang an zur Verfügung gestellt hat. Im Laufe der Zeit hat sich Tkinter allerdings weiterentwickelt, wodurch vor einigen Jahren die sogenannten ttk Widgets hinzukamen.
4. Was sind ttk Widgets?
Die Grundidee für die ttk Widgets besteht darin, dass man den Code, der das Verhalten eines Widgets implementiert, so weit wie möglich vom Code trennt, der sein Erscheinungsbild implementiert. Das klingt erst mal kompliziert, aber wir können uns das ganz einfach am aktuellen Beispiel bewusst machen.
Darin haben wir gerade ein tk Label erzeugt, das den Text „Label 1“ anzeigt. Warum ist das so? Weil wir in unserer Zeile Code als Text den String „Label 1“ zugewiesen haben. Darüber hinaus haben wir darin die Hintergrundfarbe des Labels mit der Zeile bg=“green“ festgelegt.
5. Erzeugen eines ttk Label Widgets
Die Grundidee der neueren ttk Widgets besteht wie bereits gesagt darin, dass man den Code, der das Verhalten eines Widgets implementiert, so weit wie möglich vom Code trennt, der sein Erscheinungsbild implementiert.
Die Hintergrundfarbe des Label Widgets ändert offensichtlich das Erscheinungsbild. Sie hat also keine funktionale Wirkung, sondern nur Einfluss auf die Optik. Bei ttk Widgets wird das jetzt voneinander getrennt bzw. hat man die Möglichkeit, es voneinander zu trennen. Man muss es also nicht zwangsläufig tun, kann dies aber.
Das bedeutet, dass wir bei den ttk Widgets, um das Aussehen eines Widgets zu verändern, die Details nicht mehr über die Optionen setzen müssen, was wir bisher bei den normalen tk Widgets mit den Schlüsselwortargumenten getan haben. Stattdessen können wir das in einem separaten Schritt mithilfe sogenannter Style-Klassen umsetzen, die wir den entsprechenden Widgets zuweisen.
An dieser Stelle erzeugen wir uns ein zweites Label Widget. Allerdings nicht das normale tk Label Widget wie gerade eben, sondern das ttk Label Widget. Hierzu müssen wir zunächst einen weiteren Import-Befehl angeben:
import tkinter as tk
from tkinter import ttk
Sobald wir diesen Import-Befehl in unser Programm gesetzt haben, bietet sich uns zusätzlich die Möglichkeit, die neueren ttk Widgets zu verwenden.
Davon erzeugen wir uns nun folgendermaßen ein zweites Label Widget:label1.pack()
label2 = ttk.Label(root, text="Label 2", bg="red")
Um dieses Widget sichtbar zu machen, packen wir es ebenfalls in die GUI.
label2 = ttk.Label(root, text="Label 2", bg="red")
label2.pack()
6. Fehlermeldungen bei ttk Label Widgets
Wie du siehst, besteht der einzige Unterschied zum normalen tk Widget im aktuellen Code darin, dass wir „ttk.Label“ schreiben anstatt „tk.Label“.
Wenn wir das Programm jetzt ausführen, erhalten wir allerdings eine Fehlermeldung: "Unknown option 'bg'". Das bedeutet, dass das ttk Label Widget nicht die Option 'bg' kennt, um die Hintergrundfarbe zu setzen, was wir in diesem Fall mit dem Argument bg="red" versucht haben.
Die ttk Label Widgets stellen also nicht die exakt gleichen Optionen bereit wie die tk Label Widgets.
Aus diesem Grund löschen wir das Schlüsselwortargument, mit dem wir die Hintergrundfarbe modifizieren möchten, für dieses Beispiel einfach noch mal heraus.
label2 = ttk.Label(root, text="Label 2", bg="red")
Wenn wir das Programm jetzt erneut ausführen, sehen wir, dass es durchläuft und das Ganze funktioniert:
Wir haben nach wie vor die Möglichkeit, die Hintergrundfarbe des ttk Labels zu verändern, allerdings geschieht das auf eine andere Art und Weise. Dafür existieren nämlich andere Optionen innerhalb des ttk-Labels. Das werden wir im nächsten Beitrag sehen.
7. Style-Klassen
Zudem gibt es eigene sogenannte Style-Klassen, anhand derer wir das Aussehen gesondert modifizieren können.
Auf das Thema Style-Klassen gehen wir unter anderem im Tkinter-Masterkurs mit einem komplett eigenen Modul ein. Darin wirst du detailliert lernen, welche Abstraktionslevel es beim Styling der GUI gibt, was sogenannte Default-Style-Klassen sind, wie man diese konfiguriert, wie man eigene Style-Klassen erzeugen kann und vieles mehr.
Mithilfe dieser Style-Klassen erreichen wir die gewünschte Entkopplung zwischen dem Code, der für die Funktionalität verantwortlich ist, und dem Code, der für das Styling der GUI sorgt. Diese Entkopplung macht den Code nicht nur übersichtlicher, sondern bringt auch einen weiteren großen Vorteil mit sich.
8. Vorteile der Style-Klassen
Stell dir vor, du hast in deiner GUI 60 unterschiedliche Widgets eingebaut. Bei allen Widgets hast du das Aussehen jeweils direkt beim Erzeugen des Objekts festgelegt, indem du die entsprechenden Optionen mit Schlüsselwortargumenten gesetzt hast.
Wenn du jetzt etwas grundlegend am Aussehen der GUI ändern möchtest, müsstest du diese Änderungen in jedem einzelnen Widget-Objekt vornehmen. Wenn du hingegen allen Objekten einfach nur eine Style-Klasse zuweisen würdest, müsste eine Änderung nur an einer Stelle im Code, nämlich in der Style-Klasse, umgesetzt werden. Alle Widgets würden diese Änderungen dann automatisch übernehmen.
9. Vorteile der ttk Widgets
Zudem haben die ttk Widgets den Vorteil, dass es mehrere von ihnen gibt. Insgesamt existieren von den tk Widgets 12 Stück, wohingegen es von den ttk Widgets 18 Stück gibt. Es stehen damit also 6 Widgets mehr zur Verfügung als bei den normalen tk Widgets. Zudem bieten ttk Widgets ein besseres plattformübergreifendes Erscheinungsbild aufgrund ihrer Themes.
Jeder Style folgt einem gewissen übergeordneten Theme, was die ganze GUI optisch nativer an die entsprechende Plattform anpasst. Wenn du dein Programm beispielsweise auf Windows ausführst, übernimmt es das Grundaussehen einer Windows-Applikation. Führst du dein Programm auf einem Mac aus, übernimmt es das Grundaussehen einer Mac-Applikation. Es fügt sich also „schöner“ ein.
10. Fazit
Aufgrund der genannten Punkte werden wir im weiteren Verlauf dieser Tutorial-Reihe immer mit den ttk Widgets arbeiten. Wie gesagt, sind die neuen ttk Widgets nicht ausnahmslos genauso anwendbar wie die normalen TK Widgets, weil beispielsweise Schlüsselwortargumente wie „bg“ nicht entgegengenommen werden können. Dafür gibt es andere Schlüsselwortargumente als Optionen, wie wir im nächsten Beitrag sehen werden.
Merken solltest du dir also, dass es sowohl die normalen tk Widgets als auch die ttk Widgets gibt und sich diese in gewissen Belangen voneinander unterscheiden.
Das zu verstehen ist besonders wichtig, wenn du beispielsweise eine spezifische Frage googeln solltest. Denn oftmals sieht man dann Beispiele mit normalen tk Widgets und Beispiele mit ttk Widgets und wenn man dann nichts von den Unterschieden weiß, sorgt das schnell für Verwirrung. Da du diesen Beitrag gelesen hast, sollte das allerdings nicht mehr passieren. Im Verlauf der nächsten Blogartikel wird das noch wesentlich klarer werden.