tkinter — Python-Schnittstelle zu Tcl/Tk

Quellcode: Lib/tkinter/__init__.py


Das Paket tkinter (Tk-Schnittstelle) ist die Standard-Python-Schnittstelle zum Tcl/Tk GUI-Toolkit. Sowohl Tk als auch tkinter sind auf den meisten Unix-Plattformen, einschließlich macOS, sowie auf Windows-Systemen verfügbar.

Wenn Sie python -m tkinter in der Befehlszeile ausführen, sollte ein Fenster geöffnet werden, das eine einfache Tk-Oberfläche demonstriert und Ihnen mitteilt, dass tkinter korrekt auf Ihrem System installiert ist. Außerdem wird die installierte Version von Tcl/Tk angezeigt, sodass Sie die Dokumentation zu Tcl/Tk lesen können, die spezifisch für diese Version ist.

Tkinter unterstützt eine Reihe von Tcl/Tk-Versionen, die entweder mit oder ohne Thread-Unterstützung kompiliert wurden. Die offizielle binäre Python-Distribution bündelt Tcl/Tk 8.6 mit Thread-Unterstützung. Weitere Informationen zu unterstützten Versionen finden Sie im Quellcode des Moduls _tkinter.

Tkinter ist keine dünne Hülle, sondern fügt eine beträchtliche Menge eigener Logik hinzu, um die Benutzererfahrung pythonischer zu gestalten. Diese Dokumentation konzentriert sich auf diese Ergänzungen und Änderungen und verweist für unveränderte Details auf die offizielle Tcl/Tk-Dokumentation.

Hinweis

Tcl/Tk 8.5 (2007) führte einen modernen Satz thematisierter Benutzeroberflächenkomponenten zusammen mit einer neuen API zu deren Verwendung ein. Sowohl die alte als auch die neue API sind weiterhin verfügbar. Die meisten online verfügbaren Dokumentationen verwenden noch die alte API und können veraltet sein.

Siehe auch

  • TkDocs

    Umfassendes Tutorial zur Erstellung von Benutzeroberflächen mit Tkinter. Erklärt Schlüsselkonzepte und veranschaulicht empfohlene Vorgehensweisen unter Verwendung der modernen API.

  • Tkinter 8.5 Referenz: eine GUI für Python

    Referenzdokumentation für Tkinter 8.5 mit Details zu verfügbaren Klassen, Methoden und Optionen.

Tcl/Tk Ressourcen

  • Tk-Befehle

    Umfassende Referenz für jeden der zugrundeliegenden Tcl/Tk-Befehle, die von Tkinter verwendet werden.

  • Tcl/Tk Homepage

    Zusätzliche Dokumentation und Links zur Kernentwicklung von Tcl/Tk.

Bücher

Architektur

Tcl/Tk ist keine einzelne Bibliothek, sondern besteht aus einigen separaten Modulen, jedes mit eigener Funktionalität und eigener offizieller Dokumentation. Die binären Python-Distributionen enthalten auch ein Add-on-Modul.

Tcl

Tcl ist eine dynamische interpretierte Programmiersprache, ähnlich wie Python. Obwohl es eigenständig als Allzweck-Programmiersprache verwendet werden kann, wird es am häufigsten in C-Anwendungen als Skript-Engine oder als Schnittstelle zum Tk-Toolkit eingebettet. Die Tcl-Bibliothek verfügt über eine C-Schnittstelle zur Erstellung und Verwaltung einer oder mehrerer Instanzen eines Tcl-Interpreters, zur Ausführung von Tcl-Befehlen und Skripten in diesen Instanzen und zum Hinzufügen benutzerdefinierter Befehle, die entweder in Tcl oder C implementiert sind. Jeder Interpreter verfügt über eine Ereignisschleife und Einrichtungen zur Übermittlung von Ereignissen an diese und deren Verarbeitung. Im Gegensatz zu Python ist das Ausführungsmodell von Tcl auf kooperatives Multitasking ausgelegt, und Tkinter überbrückt diesen Unterschied (siehe Threading model für Details).

Tk

Tk ist ein Tcl-Paket, das in C implementiert ist und benutzerdefinierte Befehle zur Erstellung und Manipulation von GUI-Widgets hinzufügt. Jedes Tk-Objekt bettet seine eigene Tcl-Interpreterinstanz mit geladenem Tk ein. Die Widgets von Tk sind sehr anpassbar, allerdings auf Kosten eines veralteten Erscheinungsbilds. Tk verwendet die Tcl-Ereignisschleife, um GUI-Ereignisse zu generieren und zu verarbeiten.

Ttk

Themed Tk (Ttk) ist eine neuere Familie von Tk-Widgets, die ein wesentlich besseres Erscheinungsbild auf verschiedenen Plattformen bieten als viele der klassischen Tk-Widgets. Ttk wird seit Tk Version 8.5 als Teil von Tk vertrieben. Python-Bindings werden in einem separaten Modul, tkinter.ttk, bereitgestellt.

Intern verwenden Tk und Ttk Einrichtungen des zugrunde liegenden Betriebssystems, d. h. Xlib unter Unix/X11, Cocoa unter macOS, GDI unter Windows.

Wenn Ihre Python-Anwendung eine Klasse in Tkinter verwendet, z. B. zur Erstellung eines Widgets, setzt das Modul tkinter zunächst eine Tcl/Tk-Befehlszeichenfolge zusammen. Diese Tcl-Befehlszeichenfolge wird an ein internes Binärmodul _tkinter übergeben, das dann den Tcl-Interpreter aufruft, um sie auszuwerten. Der Tcl-Interpreter ruft dann die Tk- und/oder Ttk-Pakete auf, die wiederum Xlib, Cocoa oder GDI aufrufen.

Tkinter-Module

Die Unterstützung für Tkinter ist auf mehrere Module verteilt. Die meisten Anwendungen benötigen das Hauptmodul tkinter sowie das Modul tkinter.ttk, das den modernen Satz thematisierter Widgets und die API bereitstellt.

from tkinter import *
from tkinter import ttk
class tkinter.Tk(screenName=None, baseName=None, className='Tk', useTk=True, sync=False, use=None)

Konstruiert ein Top-Level-Tk-Widget, das normalerweise das Hauptfenster einer Anwendung ist, und initialisiert einen Tcl-Interpreter für dieses Widget. Jede Instanz hat ihren eigenen zugehörigen Tcl-Interpreter.

Die Klasse Tk wird typischerweise mit allen Standardwerten instanziiert. Derzeit werden jedoch die folgenden Schlüsselwortargumente erkannt:

screenName

Wenn angegeben (als Zeichenkette), setzt die Umgebungsvariable DISPLAY. (Nur X11)

baseName

Name der Profildatei. Standardmäßig wird *baseName* aus dem Programmnamen (sys.argv[0]) abgeleitet.

className

Name der Widget-Klasse. Wird als Profildatei und auch als Name verwendet, mit dem Tcl aufgerufen wird (argv0 in interp).

useTk

Wenn True, wird das Tk-Subsystem initialisiert. Die Funktion tkinter.Tcl() setzt dies auf False.

sync

Wenn True, werden alle X-Server-Befehle synchron ausgeführt, sodass Fehler sofort gemeldet werden. Kann zur Fehlersuche verwendet werden. (Nur X11)

use

Gibt die *id* des Fensters an, in das die Anwendung eingebettet werden soll, anstatt dass sie als unabhängiges Top-Level-Fenster erstellt wird. *id* muss auf die gleiche Weise angegeben werden wie der Wert für die -use Option für Top-Level-Widgets (d. h., sie hat die Form, die von winfo_id() zurückgegeben wird).

Beachten Sie, dass dies auf einigen Plattformen nur dann korrekt funktioniert, wenn *id* sich auf einen Tk-Frame oder ein Top-Level-Fenster bezieht, bei dem die Option -container aktiviert ist.

Tk liest und interpretiert Profildateien namens .className.tcl und .baseName.tcl in den Tcl-Interpreter und ruft exec() auf den Inhalt von .className.py und .baseName.py auf. Der Pfad für die Profildateien ist die Umgebungsvariable HOME oder, falls diese nicht definiert ist, dann os.curdir.

tk

Das Tk-Anwendungsobjekt, das durch Instanziierung von Tk erstellt wird. Dies bietet Zugriff auf den Tcl-Interpreter. Jedes Widget, das an dieselbe Instanz von Tk angehängt ist, hat denselben Wert für sein tk-Attribut.

master

Das Widget-Objekt, das dieses Widget enthält. Für Tk ist das *master* None, da es sich um das Hauptfenster handelt. Die Begriffe *master* und *parent* sind ähnlich und werden manchmal als Argumentnamen austauschbar verwendet; jedoch gibt der Aufruf von winfo_parent() eine Zeichenkette des Widget-Namens zurück, während master das Objekt zurückgibt. *parent*/*child* spiegelt die baumartige Beziehung wider, während *master*/*slave* die Containerstruktur widerspiegelt.

children

Die direkten Nachkommen dieses Widgets als dict, wobei die Namen der Kind-Widgets die Schlüssel und die Kind-Instanzobjekte die Werte sind.

tkinter.Tcl(screenName=None, baseName=None, className='Tk', useTk=False)

Die Funktion Tcl() ist eine Factory-Funktion, die ein Objekt erstellt, das dem von der Klasse Tk erstellten Objekt ähnelt, mit dem Unterschied, dass das Tk-Subsystem nicht initialisiert wird. Dies ist am nützlichsten, wenn der Tcl-Interpreter in einer Umgebung gesteuert wird, in der man keine zusätzlichen Top-Level-Fenster erstellen möchte oder wo man dies nicht kann (wie z. B. unter Unix/Linux-Systemen ohne X-Server). Ein von einem Tcl()-Objekt erstelltes Objekt kann ein Top-Level-Fenster haben, das durch Aufrufen seiner Methode loadtk() erstellt wird (und das Tk-Subsystem initialisiert wird).

Die Module, die Tk-Unterstützung bieten, umfassen

tkinter

Hauptmodul Tkinter.

tkinter.colorchooser

Dialog zur Farbauswahl durch den Benutzer.

tkinter.commondialog

Basisklasse für die Dialoge, die in den anderen hier aufgeführten Modulen definiert sind.

tkinter.filedialog

Allgemeine Dialoge, die es dem Benutzer ermöglichen, eine zu öffnende oder zu speichernde Datei anzugeben.

tkinter.font

Dienstprogramme zur Unterstützung der Arbeit mit Schriftarten.

tkinter.messagebox

Zugriff auf Standard-Tk-Dialogfelder.

tkinter.scrolledtext

Text-Widget mit einer integrierten vertikalen Scrollleiste.

tkinter.simpledialog

Grundlegende Dialoge und Komfortfunktionen.

tkinter.ttk

Thematisierte Widget-Sammlung, eingeführt in Tk 8.5, die moderne Alternativen zu vielen der klassischen Widgets im Hauptmodul tkinter bietet.

Zusätzliche Module

_tkinter

Ein Binärmodul, das die Low-Level-Schnittstelle zu Tcl/Tk enthält. Es wird automatisch vom Hauptmodul tkinter importiert und sollte niemals direkt von Anwendungsprogrammierern verwendet werden. Es ist normalerweise eine Shared Library (oder DLL), kann aber in einigen Fällen statisch mit dem Python-Interpreter verknüpft sein.

idlelib

Pythons Integrierte Entwicklungs- und Lernumgebung (IDLE). Basiert auf tkinter.

tkinter.constants

Symbolische Konstanten, die anstelle von Zeichenketten verwendet werden können, wenn verschiedene Parameter an Tkinter-Aufrufe übergeben werden. Automatisch vom Hauptmodul tkinter importiert.

tkinter.dnd

(experimentell) Drag-and-Drop-Unterstützung für tkinter. Dies wird veraltet sein, wenn es durch Tk DND ersetzt wird.

turtle

Turtle-Grafik in einem Tk-Fenster.

Tkinter Life Preserver

Dieser Abschnitt ist keine erschöpfende Einführung in Tk oder Tkinter. Dafür verweisen Sie auf eine der zuvor genannten externen Ressourcen. Stattdessen bietet dieser Abschnitt eine sehr schnelle Orientierung darüber, wie eine Tkinter-Anwendung aussieht, identifiziert grundlegende Tk-Konzepte und erklärt, wie die Tkinter-Hülle strukturiert ist.

Der Rest dieses Abschnitts hilft Ihnen, die Klassen, Methoden und Optionen zu identifizieren, die Sie in Ihrer Tkinter-Anwendung benötigen, und wo Sie detailliertere Dokumentationen dazu finden, einschließlich des offiziellen Tcl/Tk-Referenzhandbuchs.

Ein „Hallo Welt“-Programm

Wir beginnen mit einem „Hallo Welt“-Programm in Tkinter. Dies ist nicht das kleinste, das wir schreiben könnten, aber es enthält genug, um einige Schlüsselkonzepte zu veranschaulichen, die Sie kennen müssen.

from tkinter import *
from tkinter import ttk
root = Tk()
frm = ttk.Frame(root, padding=10)
frm.grid()
ttk.Label(frm, text="Hello World!").grid(column=0, row=0)
ttk.Button(frm, text="Quit", command=root.destroy).grid(column=1, row=0)
root.mainloop()

Nach den Importen erstellt die nächste Zeile eine Instanz der Klasse Tk, die Tk initialisiert und ihren zugehörigen Tcl-Interpreter erstellt. Sie erstellt auch ein Top-Level-Fenster, das als Hauptfenster der Anwendung bekannt ist.

Die folgende Zeile erstellt ein Frame-Widget, das in diesem Fall eine Beschriftung und eine Schaltfläche enthalten wird, die wir als Nächstes erstellen werden. Das Frame wird innerhalb des Hauptfensters platziert.

Die nächste Zeile erstellt ein Beschriftungs-Widget, das einen statischen Text enthält. Die Methode grid() wird verwendet, um das relative Layout (Position) der Beschriftung innerhalb ihres enthaltenden Frame-Widgets festzulegen, ähnlich wie Tabellen in HTML funktionieren.

Ein Schaltflächen-Widget wird dann erstellt und rechts neben der Beschriftung platziert. Wenn es gedrückt wird, ruft es die Methode destroy() des Hauptfensters auf.

Schließlich platziert die Methode mainloop() alles auf dem Bildschirm und reagiert auf Benutzereingaben, bis das Programm beendet wird.

Wichtige Tk-Konzepte

Selbst dieses einfache Programm veranschaulicht die folgenden Schlüsselkonzepte von Tk:

Widgets

Eine Tkinter-Benutzeroberfläche besteht aus einzelnen *Widgets*. Jedes Widget wird als Python-Objekt dargestellt, das aus Klassen wie ttk.Frame, ttk.Label und ttk.Button instanziiert wird.

Widget-Hierarchie

Widgets sind in einer *Hierarchie* angeordnet. Die Beschriftung und die Schaltfläche waren in einem Frame enthalten, der wiederum im Hauptfenster enthalten war. Beim Erstellen jedes *Kind*-Widgets wird sein *Eltern*-Widget als erstes Argument an den Widget-Konstruktor übergeben.

Konfigurationsoptionen

Widgets haben *Konfigurationsoptionen*, die ihr Aussehen und Verhalten ändern, wie z. B. den anzuzeigenden Text in einer Beschriftung oder Schaltfläche. Unterschiedliche Widget-Klassen haben unterschiedliche Optionssätze.

Geometrie-Management

Widgets werden beim Erstellen nicht automatisch zur Benutzeroberfläche hinzugefügt. Ein *Geometrie-Manager* wie grid steuert, wo sie in der Benutzeroberfläche platziert werden.

Ereignisschleife

Tkinter reagiert auf Benutzereingaben, Änderungen durch Ihr Programm und aktualisiert sogar die Anzeige nur, wenn aktiv eine *Ereignisschleife* läuft. Wenn Ihr Programm die Ereignisschleife nicht ausführt, wird Ihre Benutzeroberfläche nicht aktualisiert.

Verständnis, wie Tkinter Tcl/Tk umschließt

Wenn Ihre Anwendung Tkinter-Klassen und -Methoden verwendet, setzt Tkinter intern Zeichenketten zusammen, die Tcl/Tk-Befehle darstellen, und führt diese Befehle im Tcl-Interpreter aus, der an die Tk-Instanz Ihrer Anwendung angehängt ist.

Ob Sie versuchen, in der Referenzdokumentation zu navigieren, die richtige Methode oder Option zu finden, vorhandenen Code anzupassen oder Ihre Tkinter-Anwendung zu debuggen, es ist hilfreich zu verstehen, wie diese zugrunde liegenden Tcl/Tk-Befehle aussehen.

Zur Veranschaulichung ist hier das Tcl/Tk-Äquivalent des Hauptteils des obigen Tkinter-Skripts.

ttk::frame .frm -padding 10
grid .frm
grid [ttk::label .frm.lbl -text "Hello World!"] -column 0 -row 0
grid [ttk::button .frm.btn -text "Quit" -command "destroy ."] -column 1 -row 0

Die Syntax von Tcl ähnelt vielen Shell-Sprachen, bei denen das erste Wort der auszuführende Befehl ist, gefolgt von den Argumenten zu diesem Befehl, getrennt durch Leerzeichen. Ohne zu viele Details zu erfahren, beachten Sie Folgendes:

  • Die Befehle zur Erstellung von Widgets (wie ttk::frame) entsprechen den Widget-Klassen in Tkinter.

  • Tcl-Widget-Optionen (wie -text) entsprechen Schlüsselwortargumenten in Tkinter.

  • Widgets werden in Tcl durch einen *Pfadnamen* referenziert (wie .frm.btn), während Tkinter keine Namen, sondern Objektverweise verwendet.

  • Die Position eines Widgets in der Widget-Hierarchie ist in seinem (hierarchischen) Pfadnamen kodiert, der einen . (Punkt) als Pfadtrennzeichen verwendet. Der Pfadname für das Hauptfenster ist einfach . (Punkt). In Tkinter wird die Hierarchie nicht durch den Pfadnamen definiert, sondern durch die Angabe des Eltern-Widgets bei der Erstellung jedes Kind-Widgets.

  • Operationen, die in Tcl als separate *Befehle* implementiert sind (wie grid oder destroy), werden als *Methoden* auf Tkinter-Widget-Objekten dargestellt. Wie Sie gleich sehen werden, verwendet Tcl zu anderen Zeiten Aufrufe, die wie Methoden auf Widget-Objekten aussehen, was dem in Tkinter verwendeten näher kommt.

Wie mache ich...? Welche Option...?

Wenn Sie unsicher sind, wie Sie etwas in Tkinter tun können, und es in der Tutorial- oder Referenzdokumentation, die Sie verwenden, nicht sofort finden, gibt es einige Strategien, die hilfreich sein können.

Erstens, denken Sie daran, dass die Details, wie einzelne Widgets funktionieren, je nach Version von Tkinter und Tcl/Tk variieren können. Wenn Sie nach Dokumentation suchen, stellen Sie sicher, dass sie mit den auf Ihrem System installierten Python- und Tcl/Tk-Versionen übereinstimmt.

Bei der Suche nach der Verwendung einer API ist es hilfreich, den genauen Namen der Klasse, Option oder Methode zu kennen, die Sie verwenden. Introspektion, entweder in einer interaktiven Python-Shell oder mit print(), kann Ihnen helfen, das zu identifizieren, was Sie brauchen.

Um herauszufinden, welche Konfigurationsoptionen für ein Widget verfügbar sind, rufen Sie seine Methode configure() auf, die ein Wörterbuch zurückgibt, das verschiedene Informationen über jedes Objekt enthält, einschließlich seiner Standard- und aktuellen Werte. Verwenden Sie keys(), um nur die Namen jeder Option zu erhalten.

btn = ttk.Button(frm, ...)
print(btn.configure().keys())

Da die meisten Widgets viele Konfigurationsoptionen gemeinsam haben, kann es hilfreich sein, herauszufinden, welche für eine bestimmte Widget-Klasse spezifisch sind. Ein Vergleich der Optionsliste mit der eines einfacheren Widgets, wie z. B. eines Frames, ist eine Möglichkeit, dies zu tun.

print(set(btn.configure().keys()) - set(frm.configure().keys()))

Ebenso können Sie die verfügbaren Methoden für ein Widget-Objekt mit der Standardfunktion dir() finden. Wenn Sie es ausprobieren, werden Sie feststellen, dass es über 200 gängige Widget-Methoden gibt, daher ist die Identifizierung der spezifischen Methoden für eine Widget-Klasse hilfreich.

print(dir(btn))
print(set(dir(btn)) - set(dir(frm)))

Threading-Modell

Python und Tcl/Tk haben sehr unterschiedliche Threading-Modelle, die tkinter zu überbrücken versucht. Wenn Sie Threads verwenden, müssen Sie sich dessen möglicherweise bewusst sein.

Ein Python-Interpreter kann viele Threads enthalten, die mit ihm assoziiert sind. In Tcl können mehrere Threads erstellt werden, aber jeder Thread hat einen separaten Tcl-Interpreter, der mit ihm assoziiert ist. Threads können auch mehr als eine Interpreterinstanz erstellen, obwohl jede Interpreterinstanz nur von dem Thread verwendet werden kann, der sie erstellt hat.

Jedes von tkinter erstellte Tk-Objekt enthält einen Tcl-Interpreter. Es merkt sich auch, welcher Thread diesen Interpreter erstellt hat. Aufrufe von tkinter können von jedem Python-Thread erfolgen. Intern, wenn ein Aufruf von einem anderen Thread als dem stammt, der das Tk-Objekt erstellt hat, wird ein Ereignis in die Ereigniswarteschlange des Interpreters gestellt und, wenn es ausgeführt wird, das Ergebnis an den aufrufenden Python-Thread zurückgegeben.

Tcl/Tk-Anwendungen sind normalerweise ereignisgesteuert, was bedeutet, dass der Interpreter nach der Initialisierung eine Ereignisschleife ausführt (d. h. Tk.mainloop()) und auf Ereignisse reagiert. Da es sich um einen einzelnen Thread handelt, müssen Ereignisbehandler schnell reagieren, da sie sonst andere Ereignisse blockieren würden. Um dies zu vermeiden, sollten lang andauernde Berechnungen nicht in einem Ereignisbehandler ausgeführt werden, sondern entweder mit Timern in kleinere Teile zerlegt oder in einem anderen Thread ausgeführt werden. Dies unterscheidet sich von vielen GUI-Toolkits, bei denen die GUI in einem völlig separaten Thread von allem Anwendungscode, einschließlich Ereignisbehandlern, ausgeführt wird.

Wenn der Tcl-Interpreter die Ereignisschleife nicht ausführt und keine Ereignisse verarbeitet, schlagen alle tkinter-Aufrufe, die von anderen Threads als dem, der den Tcl-Interpreter ausführt, erfolgen, fehl.

Es gibt eine Reihe von Sonderfällen

  • Tcl/Tk-Bibliotheken können so kompiliert werden, dass sie nicht thread-fähig sind. In diesem Fall ruft tkinter die Bibliothek aus dem ursprünglichen Python-Thread auf, auch wenn dies anders ist als der Thread, der den Tcl-Interpreter erstellt hat. Eine globale Sperre stellt sicher, dass nur ein Aufruf gleichzeitig erfolgt.

  • Während tkinter Ihnen erlaubt, mehr als eine Instanz eines Tk-Objekts (mit eigenem Interpreter) zu erstellen, teilen sich alle Interpreter, die Teil desselben Threads sind, eine gemeinsame Ereigniswarteschlange, was schnell unübersichtlich wird. In der Praxis sollten Sie nicht mehr als eine Instanz von Tk gleichzeitig erstellen. Andernfalls ist es am besten, sie in separaten Threads zu erstellen und sicherzustellen, dass Sie eine thread-fähige Tcl/Tk-Version verwenden.

  • Blockierende Ereignisbehandler sind nicht die einzige Möglichkeit, den Tcl-Interpreter daran zu hindern, die Ereignisschleife erneut aufzurufen. Es ist sogar möglich, mehrere verschachtelte Ereignisschleifen auszuführen oder die Ereignisschleife ganz zu verlassen. Wenn Sie bei Ereignissen oder Threads etwas kniffliges tun, sollten Sie sich dieser Möglichkeiten bewusst sein.

  • Es gibt einige wenige ausgewählte tkinter-Funktionen, die derzeit nur funktionieren, wenn sie vom Thread aufgerufen werden, der den Tcl-Interpreter erstellt hat.

Praktische Referenz

Optionen setzen

Optionen steuern Dinge wie die Farbe und Randbreite eines Widgets. Optionen können auf drei Arten gesetzt werden

Zum Zeitpunkt der Objekterstellung unter Verwendung von Schlüsselwortargumenten
fred = Button(self, fg="red", bg="blue")
Nach der Objekterstellung, wobei der Optionsname wie ein Wörterbuchindex behandelt wird
fred["fg"] = "red"
fred["bg"] = "blue"
Verwenden Sie die Methode config(), um nach der Objekterstellung mehrere Attribute zu aktualisieren
fred.config(fg="red", bg="blue")

Eine vollständige Erklärung einer gegebenen Option und ihres Verhaltens finden Sie in den Tk-Manpages für das betreffende Widget.

Beachten Sie, dass die Manpages "STANDARDOPTIONS" und "WIDGET SPECIFIC OPTIONS" für jedes Widget auflisten. Erstere ist eine Liste von Optionen, die vielen Widgets gemeinsam sind, letztere sind die Optionen, die für dieses spezielle Widget eigen sind. Die Standardoptionen sind auf der Manpage options(3) dokumentiert.

In diesem Dokument wird keine Unterscheidung zwischen Standard- und Widget-spezifischen Optionen gemacht. Einige Optionen gelten nicht für bestimmte Widget-Typen. Ob ein gegebenes Widget auf eine bestimmte Option reagiert, hängt von der Widget-Klasse ab; Buttons haben eine command-Option, Labels nicht.

Die von einem gegebenen Widget unterstützten Optionen sind in der Manpage dieses Widgets aufgeführt oder können zur Laufzeit abgefragt werden, indem die Methode config() ohne Argumente aufgerufen wird oder indem die Methode keys() für dieses Widget aufgerufen wird. Der Rückgabewert dieser Aufrufe ist ein Wörterbuch, dessen Schlüssel der Name der Option als Zeichenkette ist (z. B. 'relief') und dessen Werte 5-Tupel sind.

Einige Optionen, wie bg, sind Synonyme für gängige Optionen mit langen Namen (bg ist eine Abkürzung für "background"). Die Übergabe des Namens einer Kurzform-Option an die Methode config() gibt ein 2-Tupel zurück, nicht ein 5-Tupel. Das zurückgegebene 2-Tupel enthält den Namen des Synonyms und die "wirkliche" Option (z. B. ('bg', 'background')).

Index

Bedeutung

Beispiel

0

Optionsname

'relief'

1

Optionsname für Datenbankabfrage

'relief'

2

Optionenklasse für Datenbankabfrage

'Relief'

3

Standardwert

'raised'

4

Aktueller Wert

'groove'

Beispiel

>>> print(fred.config())
{'relief': ('relief', 'relief', 'Relief', 'raised', 'groove')}

Natürlich enthält das ausgegebene Wörterbuch alle verfügbaren Optionen und ihre Werte. Dies ist nur als Beispiel gedacht.

Der Packer

Der Packer ist einer der Geometrie-Management-Mechanismen von Tk. Geometrie-Manager werden verwendet, um die relative Positionierung von Widgets innerhalb ihres Containers – ihres gegenseitigen *Meisters* – festzulegen. Im Gegensatz zum umständlicheren *Placer* (der weniger häufig verwendet wird und hier nicht behandelt wird) verwendet der Packer qualitative Bezeichner – *über*, *links von*, *füllend* usw. – und arbeitet alles aus, um die genauen Positionierungskoordinaten für Sie zu ermitteln.

Die Größe jedes *Master*-Widgets wird durch die Größe der darin enthaltenen "Slave-Widgets" bestimmt. Der Packer wird verwendet, um zu steuern, wo Slave-Widgets innerhalb des Masters erscheinen, in den sie gepackt werden. Sie können Widgets in Frames packen und Frames in andere Frames, um das gewünschte Layout zu erzielen. Darüber hinaus passt sich die Anordnung dynamisch an inkrementelle Änderungen der Konfiguration an, sobald sie gepackt ist.

Beachten Sie, dass Widgets erst erscheinen, wenn ihre Geometrie mit einem Geometrie-Manager angegeben wurde. Es ist ein häufiger anfänglicher Fehler, die Geometrieangabe wegzulassen und sich dann zu wundern, warum das Widget erstellt wurde, aber nichts angezeigt wird. Ein Widget erscheint erst, nachdem beispielsweise die pack()-Methode des Packers darauf angewendet wurde.

Die pack()-Methode kann mit Schlüsselwort-Option-/Wert-Paaren aufgerufen werden, die steuern, wo das Widget innerhalb seines Containers erscheinen soll und wie es sich verhalten soll, wenn das Hauptanwendungsfenster vergrößert wird. Hier sind einige Beispiele

fred.pack()                     # defaults to side = "top"
fred.pack(side="left")
fred.pack(expand=1)

Packer-Optionen

Weitere ausführliche Informationen über den Packer und die von ihm akzeptierten Optionen finden Sie in den Manpages und auf Seite 183 von John Ousterhout's Buch.

anchor

Ankertyp. Bezeichnet, wo der Packer jeden Slave in seinem Feld platzieren soll.

expand

Boolesch, 0 oder 1.

fill

Gültige Werte: 'x', 'y', 'both', 'none'.

ipadx und ipady

Ein Abstand – der den inneren Abstand auf jeder Seite des Slave-Widgets bezeichnet.

padx und pady

Ein Abstand – der den äußeren Abstand auf jeder Seite des Slave-Widgets bezeichnet.

side

Gültige Werte sind: 'left', 'right', 'top', 'bottom'.

Widget-Variablen koppeln

Der aktuelle Wert einiger Widgets (wie Text-Eingabefelder) kann über spezielle Optionen direkt mit Anwendungsvariablen verbunden werden. Diese Optionen sind variable, textvariable, onvalue, offvalue und value. Diese Verbindung funktioniert in beide Richtungen: Wenn sich die Variable aus irgendeinem Grund ändert, wird das Widget, mit dem sie verbunden ist, aktualisiert, um den neuen Wert widerzuspiegeln.

Leider ist es in der aktuellen Implementierung von tkinter nicht möglich, eine beliebige Python-Variable über eine variable- oder textvariable-Option an ein Widget zu übergeben. Die einzigen Arten von Variablen, für die dies funktioniert, sind Variablen, die von einer Klasse namens Variable abgeleitet sind, die in tkinter definiert ist.

Es gibt viele nützliche Unterklassen von Variable, die bereits definiert sind: StringVar, IntVar, DoubleVar und BooleanVar. Um den aktuellen Wert einer solchen Variablen zu lesen, rufen Sie die Methode get() darauf auf, und um ihren Wert zu ändern, rufen Sie die Methode set() auf. Wenn Sie dieses Protokoll befolgen, wird das Widget immer den Wert der Variablen verfolgen, ohne dass Sie weitere Eingriffe vornehmen müssen.

Zum Beispiel

import tkinter as tk

class App(tk.Frame):
    def __init__(self, master):
        super().__init__(master)
        self.pack()

        self.entrythingy = tk.Entry()
        self.entrythingy.pack()

        # Create the application variable.
        self.contents = tk.StringVar()
        # Set it to some value.
        self.contents.set("this is a variable")
        # Tell the entry widget to watch this variable.
        self.entrythingy["textvariable"] = self.contents

        # Define a callback for when the user hits return.
        # It prints the current value of the variable.
        self.entrythingy.bind('<Key-Return>',
                             self.print_contents)

    def print_contents(self, event):
        print("Hi. The current entry content is:",
              self.contents.get())

root = tk.Tk()
myapp = App(root)
myapp.mainloop()

Der Fenstermanager

In Tk gibt es einen Dienstprogramm-Befehl, wm, zur Interaktion mit dem Fenstermanager. Optionen für den wm-Befehl erlauben Ihnen, Dinge wie Titel, Platzierung, Icon-Bitmaps und Ähnliches zu steuern. In tkinter wurden diese Befehle als Methoden der Klasse Wm implementiert. Toplevel-Widgets sind von der Klasse Wm abgeleitet und können daher die Wm-Methoden direkt aufrufen.

Um auf das Toplevel-Fenster zuzugreifen, das ein gegebenes Widget enthält, können Sie oft einfach auf den Master des Widgets verweisen. Wenn das Widget natürlich in einen Frame gepackt wurde, repräsentiert der Master kein Toplevel-Fenster. Um auf das Toplevel-Fenster zuzugreifen, das ein beliebiges Widget enthält, können Sie die Methode _root() aufrufen. Diese Methode beginnt mit einem Unterstrich, um zu kennzeichnen, dass diese Funktion Teil der Implementierung ist und keine Schnittstelle zur Tk-Funktionalität darstellt.

Hier sind einige Beispiele für typische Verwendungen

import tkinter as tk

class App(tk.Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.pack()

# create the application
myapp = App()

#
# here are method calls to the window manager class
#
myapp.master.title("My Do-Nothing Application")
myapp.master.maxsize(1000, 400)

# start the program
myapp.mainloop()

Tk Options-Datentypen

anchor

Gültige Werte sind Himmelsrichtungen: "n", "ne", "e", "se", "s", "sw", "w", "nw", und auch "center".

bitmap

Es gibt acht eingebaute, benannte Bitmaps: 'error', 'gray25', 'gray50', 'hourglass', 'info', 'questhead', 'question', 'warning'. Um einen X-Bitmap-Dateinamen anzugeben, geben Sie den vollständigen Pfad zur Datei an, dem ein @ vorangestellt ist, wie in "@/usr/contrib/bitmap/gumby.bit".

boolean

Sie können die Ganzzahlen 0 oder 1 oder die Zeichenketten "yes" oder "no" übergeben.

callback

Dies ist jede Python-Funktion, die keine Argumente entgegennimmt. Zum Beispiel

def print_it():
    print("hi there")
fred["command"] = print_it
color

Farben können als X-Farbnamen aus der Datei rgb.txt oder als Zeichenketten angegeben werden, die RGB-Werte in 4 Bit darstellen: "#RGB", 8 Bit: "#RRGGBB", 12 Bit: "#RRRGGGBBB" oder 16 Bit: "#RRRRGGGGBBBB"-Bereiche, wobei R,G,B hier jede gültige Hexadezimalziffer darstellen. Einzelheiten finden Sie auf Seite 160 von Ousterhout's Buch.

cursor

Die Standard-X-Cursor-Namen aus cursorfont.h können ohne das Präfix XC_ verwendet werden. Um beispielsweise einen Hand-Cursor (XC_hand2) zu erhalten, verwenden Sie die Zeichenkette "hand2". Sie können auch eine eigene Bitmap- und Maskendatei angeben. Einzelheiten finden Sie auf Seite 179 von Ousterhout's Buch.

distance

Bildschirmabstände können entweder in Pixeln oder in absoluten Entfernungen angegeben werden. Pixel werden als Zahlen und absolute Entfernungen als Zeichenketten angegeben, wobei das nachgestellte Zeichen die Einheiten bezeichnet: c für Zentimeter, i für Zoll, m für Millimeter, p für typografische Punkte. Zum Beispiel werden 3,5 Zoll als "3.5i" angegeben.

font

Tk verwendet ein Listen-Schriftart-Namensformat, wie z. B. {courier 10 bold}. Schriftgrößen mit positiven Zahlen werden in Punkten gemessen; Größen mit negativen Zahlen werden in Pixeln gemessen.

geometry

Dies ist eine Zeichenkette der Form widthxheight, wobei Breite und Höhe für die meisten Widgets in Pixeln (für Widgets, die Text anzeigen, in Zeichen) gemessen werden. Zum Beispiel: fred["geometry"] = "200x100".

justify

Gültige Werte sind die Zeichenketten: "left", "center", "right" und "fill".

region

Dies ist eine Zeichenkette mit vier durch Leerzeichen getrennten Elementen, von denen jedes eine gültige Distanz ist (siehe oben). Zum Beispiel: "2 3 4 5" und "3i 2i 4.5i 2i" und "3c 2c 4c 10.43c" sind alles gültige Regionen.

relief

Bestimmt den Randstil eines Widgets. Gültige Werte sind: "raised", "sunken", "flat", "groove" und "ridge".

scrollcommand

Dies ist fast immer die Methode set() einer Scrollbar, kann aber jede Widget-Methode sein, die ein einzelnes Argument annimmt.

wrap

Muss einer der folgenden Werte sein: "none", "char" oder "word".

Bindungen und Ereignisse

Die Methode bind des Widget-Befehls ermöglicht es Ihnen, auf bestimmte Ereignisse zu warten und eine Callback-Funktion auszulösen, wenn dieser Ereignistyp auftritt. Die Form der bind-Methode ist

def bind(self, sequence, func, add=''):

wobei

sequenz

eine Zeichenkette ist, die die Zielart des Ereignisses bezeichnet. (Einzelheiten finden Sie in der Manpage bind(3tk) und auf Seite 201 von John Ousterhout's Buch Tcl and the Tk Toolkit (2nd edition)).

func

eine Python-Funktion ist, die ein Argument entgegennimmt und aufgerufen wird, wenn das Ereignis eintritt. Eine Event-Instanz wird als Argument übergeben. (So eingesetzte Funktionen werden gemeinhin als *Callbacks* bezeichnet.)

add

optional ist, entweder '' oder '+'. Die Übergabe einer leeren Zeichenkette bedeutet, dass diese Bindung alle anderen mit diesem Ereignis verbundenen Bindungen ersetzen soll. Die Übergabe von '+' bedeutet, dass diese Funktion zur Liste der an diesen Ereignistyp gebundenen Funktionen hinzugefügt werden soll.

Zum Beispiel

def turn_red(self, event):
    event.widget["activeforeground"] = "red"

self.button.bind("<Enter>", self.turn_red)

Beachten Sie, wie auf das widget-Feld des Ereignisses in der turn_red()-Callback zugegriffen wird. Dieses Feld enthält das Widget, das das X-Ereignis abgefangen hat. Die folgende Tabelle listet die anderen Ereignisfelder auf, auf die Sie zugreifen können, und wie sie in Tk bezeichnet werden, was beim Nachschlagen in den Tk-Manpages nützlich sein kann.

Tk

Tkinter-Ereignisfeld

Tk

Tkinter-Ereignisfeld

%f

focus

%A

char

%h

height

%E

send_event

%k

keycode

%K

keysym

%s

state

%N

keysym_num

%t

time

%T

type

%w

width

%W

widget

%x

x

%X

x_root

%y

y

%Y

y_root

Der Index-Parameter

Eine Reihe von Widgets erfordert die Übergabe von "Index"-Parametern. Diese werden verwendet, um auf eine bestimmte Stelle in einem Text-Widget, auf einzelne Zeichen in einem Eingabe-Widget oder auf einzelne Menüpunkte in einem Menü-Widget zu verweisen.

Eingabe-Widget-Indizes (index, view index usw.)

Eingabe-Widgets haben Optionen, die sich auf Zeichenpositionen im angezeigten Text beziehen. Sie können diese tkinter-Funktionen verwenden, um auf diese speziellen Punkte in Text-Widgets zuzugreifen

Text-Widget-Indizes

Die Index-Notation für Text-Widgets ist sehr reichhaltig und wird am besten in den Tk-Manpages beschrieben.

Menü-Indizes (menu.invoke(), menu.entryconfig() usw.)

Einige Optionen und Methoden für Menüs manipulieren spezifische Menüeinträge. Wann immer ein Menüindex für eine Option oder einen Parameter benötigt wird, können Sie Folgendes übergeben:

  • eine Ganzzahl, die sich auf die numerische Position des Eintrags im Widget bezieht, gezählt von oben, beginnend mit 0;

  • die Zeichenkette "active", die sich auf die Menüposition bezieht, die sich gerade unter dem Cursor befindet;

  • die Zeichenkette "last", die sich auf den letzten Menüeintrag bezieht;

  • eine Ganzzahl, der ein @ vorangestellt ist, wie in @6, wobei die Ganzzahl als y-Pixelkoordinate im Koordinatensystem des Menüs interpretiert wird;

  • die Zeichenkette "none", die keinen Menüeintrag angibt, am häufigsten verwendet mit menu.activate(), um alle Einträge zu deaktivieren, und schließlich,

  • eine Textzeichenkette, die mit dem Label des Menüeintrags abgeglichen wird, gescannt von oben nach unten des Menüs. Beachten Sie, dass dieser Index-Typ nach allen anderen betrachtet wird, was bedeutet, dass Übereinstimmungen für Menüeinträge mit den Labels last, active oder none stattdessen als die oben genannten Literale interpretiert werden können.

Bilder

Bilder verschiedener Formate können über die entsprechende Unterklasse von tkinter.Image erstellt werden

  • BitmapImage für Bilder im XBM-Format.

  • PhotoImage für Bilder in den Formaten PGM, PPM, GIF und PNG. Letzteres wird ab Tk 8.6 unterstützt.

Jeder Bildtyp wird über die Option file oder data erstellt (andere Optionen sind ebenfalls verfügbar).

Geändert in Version 3.13: Hinzugefügt wurde die Methode PhotoImage copy_replace() zum Kopieren eines Bereichs von einem Bild in ein anderes Bild, möglicherweise mit Pixelzooming und/oder Untersampling. Hinzugefügt wurde der Parameter *from_coords* zu den Methoden PhotoImage copy(), zoom() und subsample(). Hinzugefügt wurden die Parameter *zoom* und *subsample* zur Methode PhotoImage copy().

Das Bildobjekt kann dann überall dort verwendet werden, wo eine image-Option von einem Widget unterstützt wird (z. B. Labels, Buttons, Menüs). In diesen Fällen behält Tk keine Referenz auf das Bild. Wenn die letzte Python-Referenz auf das Bildobjekt gelöscht wird, werden auch die Bilddaten gelöscht, und Tk zeigt eine leere Box an, wo das Bild verwendet wurde.

Siehe auch

Das Paket Pillow fügt Unterstützung für Formate wie BMP, JPEG, TIFF und WebP hinzu.

Datei-Handler

Tk erlaubt Ihnen, eine Callback-Funktion zu registrieren und zu de-registrieren, die von der Tk-Mainloop aufgerufen wird, wenn E/A auf einem File-Deskriptor möglich ist. Nur ein Handler kann pro File-Deskriptor registriert werden. Beispielcode

import tkinter
widget = tkinter.Tk()
mask = tkinter.READABLE | tkinter.WRITABLE
widget.tk.createfilehandler(file, mask, callback)
...
widget.tk.deletefilehandler(file)

Diese Funktion ist unter Windows nicht verfügbar.

Da Sie nicht wissen, wie viele Bytes zum Lesen verfügbar sind, möchten Sie vielleicht nicht die Methoden BufferedIOBase oder TextIOBase read() oder readline() verwenden, da diese darauf bestehen, eine vordefinierte Anzahl von Bytes zu lesen. Für Sockets funktionieren die Methoden recv() oder recvfrom() einwandfrei; für andere Dateien verwenden Sie Roh-Reads oder os.read(file.fileno(), maxbytecount).

Widget.tk.createfilehandler(file, mask, func)

Registriert die Callback-Funktion *func* für den Datei-Handler. Das Argument *file* kann entweder ein Objekt mit einer fileno()-Methode (wie ein Datei- oder Socket-Objekt) oder ein Integer-File-Deskriptor sein. Das Argument *mask* ist eine OR-Kombination der drei unten genannten Konstanten. Der Callback wird wie folgt aufgerufen

callback(file, mask)
Widget.tk.deletefilehandler(file)

De-registriert einen Datei-Handler.

_tkinter.READABLE
_tkinter.WRITABLE
_tkinter.EXCEPTION

Konstanten, die in den Argumenten für *mask* verwendet werden.