"tkinter" --- Python interface to Tcl/Tk
****************************************

**Quellcode:** Lib/tkinter/__init__.py

======================================================================

The "tkinter" package ("Tk interface") is the standard Python
interface to the Tcl/Tk GUI toolkit.  Both Tk and "tkinter" are
available on most Unix platforms, including macOS, as well as on
Windows systems.

Running "python -m tkinter" from the command line should open a window
demonstrating a simple Tk interface, letting you know that "tkinter"
is properly installed on your system, and also showing what version of
Tcl/Tk is installed, so you can read the Tcl/Tk documentation specific
to that version.

Tkinter supports a range of Tcl/Tk versions, built either with or
without thread support. The official Python binary release bundles
Tcl/Tk 8.6 threaded. See the source code for the "_tkinter" module for
more information about supported versions.

Tkinter ist kein dünner Wrapper, sondern ergänzt eine ganze Menge
eigener Logik, damit sich die Nutzung pythonischer anfühlt. Diese
Dokumentation konzentriert sich auf diese Ergänzungen und Änderungen
und verweist für unveränderte Einzelheiten auf die offizielle Tcl/Tk-
Dokumentation.

Bemerkung:

  Tcl/Tk 8.5 (2007) introduced a modern set of themed user interface
  components along with a new API to use them. Both old and new APIs
  are still available. Most documentation you will find online still
  uses the old API and can be woefully outdated.

Siehe auch:

  * TkDocs
       Ausführliches Tutorial zum Erstellen von Benutzeroberflächen
       mit Tkinter. Erklärt die zentralen Konzepte und zeigt
       empfohlene Vorgehensweisen anhand der modernen API.

  * Tkinter 8.5 reference: a GUI for Python
       Referenzdokumentation zu Tkinter 8.5 mit einer ausführlichen
       Darstellung der verfügbaren Klassen, Methoden und Optionen.

  Tcl/Tk-Ressourcen:

  * Tk commands
       Umfassende Referenz zu jedem der zugrunde liegenden Tcl/Tk-
       Befehle, die Tkinter verwendet.

  * Tcl/Tk Home Page
       Weitere Dokumentation sowie Links zur Kernentwicklung von
       Tcl/Tk.

  Bücher:

  * Modern Tkinter for Busy Python Developers
       Von Mark Roseman. (ISBN 978-1999149567)

  * Python and Tkinter Programming
       By Alan Moore. (ISBN 978-1788835886)

  * Programming Python
       Von Mark Lutz. Behandelt Tkinter ausgezeichnet. (ISBN
       978-0596158101)

  * Tcl and the Tk Toolkit (2nd edition)
       Von John Ousterhout, dem Erfinder von Tcl/Tk, und Ken Jones.
       Behandelt Tkinter nicht. (ISBN 978-0321336330)


Architektur
===========

Tcl/Tk ist keine einzelne Bibliothek, sondern besteht aus mehreren
eigenständigen Modulen mit jeweils eigener Funktionalität und eigener
offizieller Dokumentation. Die Binärversionen von Python liefern
zusätzlich ein Erweiterungsmodul mit.

Tcl
   Tcl ist eine dynamische, interpretierte Programmiersprache, genau
   wie Python. Zwar lässt sie sich eigenständig als Allzwecksprache
   verwenden, am häufigsten wird sie jedoch als Skript-Engine oder als
   Schnittstelle zum Tk-Werkzeugkasten in C-Anwendungen eingebettet.
   Die Tcl-Bibliothek bietet eine C-Schnittstelle, um eine oder
   mehrere Instanzen eines Tcl-Interpreters zu erzeugen und zu
   verwalten, darin Tcl-Befehle und -Skripte auszuführen und eigene
   Befehle hinzuzufügen, die entweder in Tcl oder in C umgesetzt sind.
   Jeder Interpreter hat eine Ereigniswarteschlange, und es gibt
   Mittel, um Ereignisse dorthin zu senden und zu verarbeiten. Anders
   als bei Python ist das Ausführungsmodell von Tcl auf kooperatives
   Multitasking ausgelegt, und Tkinter überbrückt diesen Unterschied
   (Einzelheiten unter Threading model).

Tk
   Tk ist ein in C umgesetztes Tcl package, das eigene Befehle zum
   Erzeugen und Bearbeiten von GUI-Widgets hinzufügt. Jedes
   "Tk"-Objekt bettet eine eigene Instanz des Tcl-Interpreters ein, in
   die Tk geladen ist. Die Widgets von Tk lassen sich weitgehend
   anpassen, allerdings um den Preis eines altmodischen
   Erscheinungsbilds. Tk nutzt die Ereigniswarteschlange von Tcl, um
   GUI-Ereignisse zu erzeugen und zu verarbeiten.

Ttk
   Themed Tk (Ttk) ist eine neuere Familie von Tk-Widgets, die auf den
   verschiedenen Plattformen deutlich besser aussehen als viele der
   klassischen Tk-Widgets. Ttk wird ab Tk-Version 8.5 als Teil von Tk
   ausgeliefert. Die Python-Anbindung steht in einem eigenen Modul zur
   Verfügung, "tkinter.ttk".

Internally, Tk and Ttk use facilities of the underlying operating
system, i.e., Xlib on Unix/X11, Cocoa on macOS, GDI on Windows.

When your Python application uses a class in Tkinter, e.g., to create
a widget, the "tkinter" module first assembles a Tcl/Tk command
string. It passes that Tcl command string to an internal "_tkinter"
binary module, which then calls the Tcl interpreter to evaluate it.
The Tcl interpreter will then call into the Tk and/or Ttk packages,
which will in turn make calls to Xlib, Cocoa, or GDI.


Tkinter Modules
===============

Support for Tkinter is spread across several modules. Most
applications will need the main "tkinter" module, as well as the
"tkinter.ttk" module, which provides the modern themed widget set and
API:

   from tkinter import *
   from tkinter import ttk

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

   Construct a toplevel Tk widget, which is usually the main window of
   an application, and initialize a Tcl interpreter for this widget.
   Each instance has its own associated Tcl interpreter.

   Die Klasse "Tk" wird üblicherweise mit allen Vorgabewerten
   instanziiert. Derzeit werden jedoch die folgenden
   Schlüsselwortargumente erkannt:

   *screenName*
      Wenn angegeben (als Zeichenkette), wird damit die
      Umgebungsvariable "DISPLAY" gesetzt. (nur X11)

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

   *className*
      Name der Widget-Klasse. Wird als Profildatei und zugleich 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 Befehle an den X-Server synchron
      ausgeführt, sodass Fehler sofort gemeldet werden. Nützlich zur
      Fehlersuche. (nur X11)

   *use*
      Specifies the *id* of the window in which to embed the
      application, instead of it being created as an independent
      toplevel window. *id* must be specified in the same way as the
      value for the -use option for toplevel widgets (that is, it has
      a form like that returned by "winfo_id()").

      Beachte, dass dies auf manchen Plattformen nur dann richtig
      funktioniert, wenn *id* auf einen Tk-Frame oder ein Toplevel
      verweist, bei dem die Option -container eingeschaltet ist.

   "Tk" reads and interprets profile files, named ".*className*.tcl"
   and ".*baseName*.tcl", into the Tcl interpreter and calls "exec()"
   on the contents of ".*className*.py" and ".*baseName*.py".  The
   path for the profile files is the "HOME" environment variable or,
   if that isn't defined, then "os.curdir".

   tk

      Das Tk-Anwendungsobjekt, das beim Instanziieren von "Tk" erzeugt
      wird. Es gibt Zugriff auf den Tcl-Interpreter. Jedes Widget, das
      an dieselbe "Tk"-Instanz angehängt ist, hat denselben Wert für
      sein Attribut "tk".

   master

      The widget object that contains this widget.  For "Tk", the
      *master* is "None" because it is the main window.  The terms
      *master* and *parent* are similar and sometimes used
      interchangeably as argument names; however, calling
      "winfo_parent()" returns a string of the widget name whereas
      "master" returns the object. *parent*/*child* reflects the tree-
      like relationship while *master*/*slave* reflects the container
      structure.

   children

      Die unmittelbaren Nachfahren dieses Widgets als "dict", mit den
      Namen der Kind-Widgets als Schlüsseln und den Instanzobjekten
      der Kinder als Werten.

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

   The "Tcl()" function is a factory function which creates an object
   much like that created by the "Tk" class, except that it does not
   initialize the Tk subsystem.  This is most often useful when
   driving the Tcl interpreter in an environment where one doesn't
   want to create extraneous toplevel windows, or where one cannot
   (such as Unix/Linux systems without an X server).  An object
   created by the "Tcl()" object can have a Toplevel window created
   (and the Tk subsystem initialized) by calling its "loadtk()"
   method.

Zu den Modulen mit Tk-Unterstützung gehören:

"tkinter"
   Das Hauptmodul von 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"
   Standarddialoge, mit denen der Benutzer eine Datei zum Öffnen oder
   Speichern auswählen kann.

"tkinter.font"
   Hilfsmittel für die Arbeit mit Schriftarten.

"tkinter.messagebox"
   Zugriff auf die Standarddialoge von Tk.

"tkinter.scrolledtext"
   Text-Widget mit integrierter senkrechter Bildlaufleiste.

"tkinter.simpledialog"
   Einfache Dialoge und Hilfsfunktionen.

"tkinter.ttk"
   Themed widget set introduced in Tk 8.5, providing modern
   alternatives for many of the classic widgets in the main "tkinter"
   module.

Weitere Module:

"_tkinter"
   A binary module that contains the low-level interface to Tcl/Tk. It
   is automatically imported by the main "tkinter" module, and should
   never be used directly by application programmers. It is usually a
   shared library (or DLL), but might in some cases be statically
   linked with the Python interpreter.

"idlelib"
   Python's Integrated Development and Learning Environment (IDLE).
   Based on "tkinter".

"tkinter.constants"
   Symbolic constants that can be used in place of strings when
   passing various parameters to Tkinter calls. Automatically imported
   by the main "tkinter" module.

"tkinter.dnd"
   (experimental) Drag-and-drop support for "tkinter". This will
   become deprecated when it is replaced with the Tk DND.

"tkinter.tix"
   (deprecated) An older third-party Tcl/Tk package that adds several
   new widgets. Better alternatives for most can be found in
   "tkinter.ttk".

"turtle"
   Turtle-Grafik in einem Tk-Fenster.


Tkinter Life Preserver
======================

Dieser Abschnitt ist nicht als vollständige Einführung in Tk oder
Tkinter gedacht. Nutze dafür eine der weiter oben genannten externen
Quellen. Stattdessen gibt er einen kurzen Überblick darüber, wie eine
Tkinter-Anwendung aussieht, benennt die grundlegenden Tk-Konzepte und
erklärt, wie der Tkinter-Wrapper aufgebaut ist.

Im weiteren Verlauf dieses Abschnitts erfährst du, welche Klassen,
Methoden und Optionen du in deiner Tkinter-Anwendung brauchst und wo
du ausführlichere Dokumentation dazu findest, unter anderem im
offiziellen Tcl/Tk-Referenzhandbuch.


A Hello World Program
---------------------

Wir gehen zunächst eine „Hello World"-Anwendung in Tkinter durch. Sie
ist nicht die kleinstmögliche, zeigt aber genug, um einige wichtige
Konzepte zu verdeutlichen, die du kennen solltest.

   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 erzeugt die nächste Zeile eine Instanz der Klasse
"Tk", die Tk initialisiert und den zugehörigen Tcl-Interpreter anlegt.
Außerdem entsteht ein Fenster der obersten Ebene, das sogenannte Root-
Fenster, das als Hauptfenster der Anwendung dient.

Die folgende Zeile erzeugt ein Frame-Widget, das in diesem Fall ein
Label und einen Button aufnimmt, die wir gleich anlegen. Der Frame
wird in das Root-Fenster eingepasst.

The next line creates a label widget holding a static text string. The
"grid()" method is used to specify the relative layout (position) of
the label within its containing frame widget, similar to how tables in
HTML work.

A button widget is then created, and placed to the right of the label.
When pressed, it will call the "destroy()" method of the root window.

Zuletzt bringt die Methode "mainloop()" alles zur Anzeige und reagiert
auf Benutzereingaben, bis das Programm beendet wird.


Important Tk Concepts
---------------------

Schon dieses einfache Programm veranschaulicht die folgenden zentralen
Tk-Konzepte:

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" erzeugt wird.

Widget-Hierarchie
   Widgets sind in einer *Hierarchie* angeordnet. Das Label und der
   Button lagen in einem Frame, der wiederum im Root-Fenster lag. Beim
   Erzeugen jedes *Kind*-Widgets wird sein *Eltern*-Widget als erstes
   Argument an den Widget-Konstruktor übergeben.

Konfigurationsoptionen
   Widgets haben *Konfigurationsoptionen*, die ihr Aussehen und
   Verhalten verändern, etwa den Text, der in einem Label oder Button
   angezeigt wird. Verschiedene Widget-Klassen haben unterschiedliche
   Sätze von Optionen.

Geometrieverwaltung
   Widgets werden beim Erzeugen nicht automatisch zur
   Benutzeroberfläche hinzugefügt. Ein *Geometriemanager* wie "grid"
   steuert, an welcher Stelle der Benutzeroberfläche sie platziert
   werden.

Ereignisschleife
   Tkinter reagiert auf Benutzereingaben und auf Änderungen aus deinem
   Programm und aktualisiert sogar die Anzeige nur dann, wenn eine
   *Ereignisschleife* aktiv läuft. Läuft in deinem Programm keine
   Ereignisschleife, wird die Benutzeroberfläche nicht aktualisiert.


Understanding How Tkinter Wraps Tcl/Tk
--------------------------------------

When your application uses Tkinter's classes and methods, internally
Tkinter is assembling strings representing Tcl/Tk commands, and
executing those commands in the Tcl interpreter attached to your
applicaton's "Tk" instance.

Ob du dich durch die Referenzdokumentation arbeitest, die passende
Methode oder Option suchst, bestehenden Code anpasst oder deine
Tkinter-Anwendung debuggst: Es gibt Situationen, in denen es hilfreich
ist zu wissen, wie diese zugrunde liegenden Tcl/Tk-Befehle aussehen.

Zur Veranschaulichung folgt 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: Das erste Wort ist
der auszuführende Befehl, danach folgen dessen Argumente, durch
Leerzeichen getrennt. Ohne zu sehr ins Detail zu gehen, fällt
Folgendes auf:

* Die Befehle zum Erzeugen von Widgets (etwa "ttk::frame") entsprechen
  den Widget-Klassen in Tkinter.

* Widget-Optionen in Tcl (etwa "-text") entsprechen
  Schlüsselwortargumenten in Tkinter.

* Widgets werden in Tcl über einen *Pfadnamen* angesprochen (etwa
  ".frm.btn"), während Tkinter keine Namen, sondern Objektreferenzen
  verwendet.

* Der Platz eines Widgets in der Widget-Hierarchie steckt in seinem
  (hierarchischen) Pfadnamen, der einen "." (Punkt) als Trennzeichen
  verwendet. Der Pfadname des Root-Fensters ist einfach "." (Punkt).
  In Tkinter wird die Hierarchie nicht über den Pfadnamen festgelegt,
  sondern dadurch, dass beim Erzeugen jedes Kind-Widgets das Eltern-
  Widget angegeben wird.

* Operations which are implemented as separate *commands* in Tcl (like
  "grid" or "destroy") are represented as *methods* on Tkinter widget
  objects. As you'll see shortly, at other times Tcl uses what appear
  to be method calls on widget objects, which more closely mirror what
  would is used in Tkinter.


Wie mache ich...? Welche Option bewirkt...?
-------------------------------------------

Wenn du nicht sicher bist, wie sich etwas in Tkinter umsetzen lässt,
und du es in der verwendeten Einführung oder Referenzdokumentation
nicht sofort findest, helfen ein paar Vorgehensweisen.

Denk zunächst daran, dass sich die Einzelheiten zur Arbeitsweise
einzelner Widgets zwischen den Versionen von Tkinter und Tcl/Tk
unterscheiden können. Achte beim Durchsuchen der Dokumentation darauf,
dass sie zu den auf deinem System installierten Versionen von Python
und Tcl/Tk passt.

Wenn du nachschlägst, wie eine API zu verwenden ist, hilft es, den
genauen Namen der Klasse, Option oder Methode zu kennen. Introspektion
– entweder in einer interaktiven Python-Shell oder mit "print()" –
hilft dir dabei, das Nötige zu finden.

To find out what configuration options are available on any widget,
call its "configure()" method, which returns a dictionary containing a
variety of information about each object, including its default and
current values. Use "keys()" to get just the names of each option.

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

Da die meisten Widgets viele Konfigurationsoptionen gemeinsam haben,
kann es nützlich sein herauszufinden, welche für eine bestimmte
Widget-Klasse spezifisch sind. Ein Weg dahin ist, die Liste der
Optionen mit der eines einfacheren Widgets wie eines Frames zu
vergleichen.

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

Ebenso kannst du die verfügbaren Methoden eines Widget-Objekts mit der
Standardfunktion "dir()" ermitteln. Wenn du es ausprobierst, siehst du
über 200 gemeinsame Widget-Methoden. Auch hier hilft es, die für eine
Widget-Klasse spezifischen herauszufiltern.

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


Navigating the Tcl/Tk Reference Manual
--------------------------------------

As noted, the official Tk commands reference manual (man pages) is
often the most accurate description of what specific operations on
widgets do. Even when you know the name of the option or method that
you need, you may still have a few places to look.

While all operations in Tkinter are implemented as method calls on
widget objects, you've seen that many Tcl/Tk operations appear as
commands that take a widget pathname as its first parameter, followed
by optional parameters, e.g.

   destroy .
   grid .frm.btn -column 0 -row 0

Andere wiederum sehen eher wie Methoden aus, die auf einem Widget-
Objekt aufgerufen werden (tatsächlich erzeugt Tcl/Tk beim Anlegen
eines Widgets einen Tcl-Befehl mit dem Namen des Widget-Pfadnamens,
dessen erster Parameter der Name einer aufzurufenden Methode ist).

   .frm.btn invoke
   .frm.lbl configure -text "Goodbye"

In the official Tcl/Tk reference documentation, you'll find most
operations that look like method calls on the man page for a specific
widget (e.g., you'll find the "invoke()" method on the ttk::button man
page), while functions that take a widget as a parameter often have
their own man page (e.g., grid).

You'll find many common options and methods in the options or
ttk::widget man pages, while others are found in the man page for a
specific widget class.

You'll also find that many Tkinter methods have compound names, e.g.,
"winfo_x()", "winfo_height()", "winfo_viewable()". You'd find
documentation for all of these in the winfo man page.

Bemerkung:

  Etwas verwirrend ist, dass es an allen Tkinter-Widgets auch Methoden
  gibt, die gar nicht auf dem Widget arbeiten, sondern global,
  unabhängig von jedem Widget. Beispiele sind Methoden für den Zugriff
  auf die Zwischenablage oder den Systemton. (Sie sind zufällig als
  Methoden in der Basisklasse "Widget" umgesetzt, von der alle
  Tkinter-Widgets erben.)


Threading-Modell
================

Python and Tcl/Tk have very different threading models, which
"tkinter" tries to bridge. If you use threads, you may need to be
aware of this.

Einem Python-Interpreter können viele Threads zugeordnet sein. In Tcl
lassen sich ebenfalls mehrere Threads erzeugen, aber jeder Thread hat
eine eigene Tcl-Interpreter-Instanz. Threads können auch mehr als eine
Instanz erzeugen, wobei jede Interpreter-Instanz nur von dem Thread
genutzt werden kann, der sie erzeugt hat.

Each "Tk" object created by "tkinter" contains a Tcl interpreter. It
also keeps track of which thread created that interpreter. Calls to
"tkinter" can be made from any Python thread. Internally, if a call
comes from a thread other than the one that created the "Tk" object,
an event is posted to the interpreter's event queue, and when
executed, the result is returned to the calling Python thread.

Tcl/Tk applications are normally event-driven, meaning that after
initialization, the interpreter runs an event loop (i.e.
"Tk.mainloop()") and responds to events. Because it is single-
threaded, event handlers must respond quickly, otherwise they will
block other events from being processed. To avoid this, any long-
running computations should not run in an event handler, but are
either broken into smaller pieces using timers, or run in another
thread. This is different from many GUI toolkits where the GUI runs in
a completely separate thread from all application code including event
handlers.

If the Tcl interpreter is not running the event loop and processing
events, any "tkinter" calls made from threads other than the one
running the Tcl interpreter will fail.

Es gibt einige Sonderfälle:

   * Tcl/Tk libraries can be built so they are not thread-aware. In
     this case, "tkinter" calls the library from the originating
     Python thread, even if this is different than the thread that
     created the Tcl interpreter. A global lock ensures only one call
     occurs at a time.

   * While "tkinter" allows you to create more than one instance of a
     "Tk" object (with its own interpreter), all interpreters that are
     part of the same thread share a common event queue, which gets
     ugly fast. In practice, don't create more than one instance of
     "Tk" at a time. Otherwise, it's best to create them in separate
     threads and ensure you're running a thread-aware Tcl/Tk build.

   * Blockierende Ereignisbehandler sind nicht die einzige
     Möglichkeit, den Tcl-Interpreter am erneuten Eintritt in die
     Ereignisschleife zu hindern. Es ist sogar möglich, mehrere
     verschachtelte Ereignisschleifen laufen zu lassen oder die
     Ereignisschleife ganz zu verlassen. Wenn du bei Ereignissen oder
     Threads etwas Trickreiches vorhast, solltest du diese
     Möglichkeiten kennen.

   * There are a few select "tkinter" functions that presently work
     only when called from the thread that created the Tcl
     interpreter.


Handy Reference
===============


Setting Options
---------------

Optionen steuern Dinge wie Farbe und Rahmenbreite eines Widgets. Sie
lassen sich auf drei Arten setzen:

Beim Erzeugen des Objekts über Schlüsselwortargumente
      fred = Button(self, fg="red", bg="blue")

Nach dem Erzeugen des Objekts, indem der Optionsname wie ein
Dictionary-Index behandelt wird
      fred["fg"] = "red"
      fred["bg"] = "blue"

Mit der Methode config() mehrere Attribute nach dem Erzeugen des
Objekts aktualisieren
      fred.config(fg="red", bg="blue")

Eine vollständige Erklärung einer Option und ihres Verhaltens findest
du auf den Tk-Man-Pages des jeweiligen Widgets.

Beachte, dass die Man-Pages für jedes Widget „STANDARD OPTIONS“ und
„WIDGET SPECIFIC OPTIONS“ aufführen. Die ersten sind Optionen, die
viele Widgets gemeinsam haben, die zweiten gelten nur für das
jeweilige Widget. Die Standardoptionen sind auf der Man-Page
*options(3)* dokumentiert.

In diesem Dokument wird nicht zwischen Standardoptionen und widget-
spezifischen Optionen unterschieden. Manche Optionen gelten nicht für
alle Widget-Arten. Ob ein Widget auf eine bestimmte Option reagiert,
hängt von seiner Klasse ab: Buttons haben eine "command"-Option,
Labels nicht.

The options supported by a given widget are listed in that widget's
man page, or can be queried at runtime by calling the "config()"
method without arguments, or by calling the "keys()" method on that
widget.  The return value of these calls is a dictionary whose key is
the name of the option as a string (for example, "'relief'") and whose
values are 5-tuples.

Some options, like "bg" are synonyms for common options with long
names ("bg" is shorthand for "background"). Passing the "config()"
method the name of a shorthand option will return a 2-tuple, not
5-tuple. The 2-tuple passed back will contain the name of the synonym
and the "real" option (such as "('bg', 'background')").

+---------+-----------------------------------+----------------+
| Index   | Bedeutung                         | Beispiel       |
|=========|===================================|================|
| 0       | Name der Option                   | "'relief'"     |
+---------+-----------------------------------+----------------+
| 1       | Name der Option für die           | "'relief'"     |
|         | Datenbanksuche                    |                |
+---------+-----------------------------------+----------------+
| 2       | Klasse der Option für die         | "'Relief'"     |
|         | Datenbanksuche                    |                |
+---------+-----------------------------------+----------------+
| 3       | Vorgabewert                       | "'raised'"     |
+---------+-----------------------------------+----------------+
| 4       | aktueller Wert                    | "'groove'"     |
+---------+-----------------------------------+----------------+

Beispiel:

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

Das ausgegebene Dictionary enthält natürlich alle verfügbaren Optionen
und ihre Werte. Dies ist nur als Beispiel gedacht.


The Packer
----------

The packer is one of Tk's geometry-management mechanisms.    Geometry
managers are used to specify the relative positioning of widgets
within their container - their mutual *master*.  In contrast to the
more cumbersome *placer* (which is used less commonly, and we do not
cover here), the packer takes qualitative relationship specification -
*above*, *to the left of*, *filling*, etc - and works everything out
to determine the exact placement coordinates for you.

The size of any *master* widget is determined by the size of the
"slave widgets" inside.  The packer is used to control where slave
widgets appear inside the master into which they are packed.  You can
pack widgets into frames, and frames into other frames, in order to
achieve the kind of layout you desire. Additionally, the arrangement
is dynamically adjusted to accommodate incremental changes to the
configuration, once it is packed.

Note that widgets do not appear until they have had their geometry
specified with a geometry manager.  It's a common early mistake to
leave out the geometry specification, and then be surprised when the
widget is created but nothing appears.  A widget will appear only
after it has had, for example, the packer's "pack()" method applied to
it.

The pack() method can be called with keyword-option/value pairs that
control where the widget is to appear within its container, and how it
is to behave when the main application window is resized.  Here are
some examples:

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


Packer Options
--------------

For more extensive information on the packer and the options that it
can take, see the man pages and page 183 of John Ousterhout's book.

anchor
   Anchor type.  Denotes where the packer is to place each slave in
   its parcel.

expand
   Boolean, "0" or "1".

fill
   Legal values: "'x'", "'y'", "'both'", "'none'".

ipadx and ipady
   A distance - designating internal padding on each side of the slave
   widget.

padx and pady
   A distance - designating external padding on each side of the slave
   widget.

side
   Legal values are: "'left'", "'right'", "'top'", "'bottom'".


Coupling Widget Variables
-------------------------

The current-value setting of some widgets (like text entry widgets)
can be connected directly to application variables by using special
options.  These options are "variable", "textvariable", "onvalue",
"offvalue", and "value".  This connection works both ways: if the
variable changes for any reason, the widget it's connected to will be
updated to reflect the new value.

Unfortunately, in the current implementation of "tkinter" it is not
possible to hand over an arbitrary Python variable to a widget through
a "variable" or "textvariable" option.  The only kinds of variables
for which this works are variables that are subclassed from a class
called Variable, defined in "tkinter".

There are many useful subclasses of Variable already defined:
"StringVar", "IntVar", "DoubleVar", and "BooleanVar".  To read the
current value of such a variable, call the "get()" method on it, and
to change its value you call the "set()" method.  If you follow this
protocol, the widget will always track the value of the variable, with
no further intervention on your part.

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()


The Window Manager
------------------

In Tk, there is a utility command, "wm", for interacting with the
window manager.  Options to the "wm" command allow you to control
things like titles, placement, icon bitmaps, and the like.  In
"tkinter", these commands have been implemented as methods on the "Wm"
class.  Toplevel widgets are subclassed from the "Wm" class, and so
can call the "Wm" methods directly.

To get at the toplevel window that contains a given widget, you can
often just refer to the widget's master.  Of course if the widget has
been packed inside of a frame, the master won't represent a toplevel
window.  To get at the toplevel window that contains an arbitrary
widget, you can call the "_root()" method. This method begins with an
underscore to denote the fact that this function is part of the
implementation, and not an interface to Tk functionality.

Here are some examples of typical usage:

   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()


Datentypen von Tk-Optionen
--------------------------

anchor
   Zulässige Werte sind Himmelsrichtungen: ""n"", ""ne"", ""e"",
   ""se"", ""s"", ""sw"", ""w"", ""nw"" sowie ""center"".

bitmap
   There are eight built-in, named bitmaps: "'error'", "'gray25'",
   "'gray50'", "'hourglass'", "'info'", "'questhead'", "'question'",
   "'warning'".  To specify an X bitmap filename, give the full path
   to the file, preceded with an "@", as in
   ""@/usr/contrib/bitmap/gumby.bit"".

boolean
   Du kannst die ganzen Zahlen 0 oder 1 oder die Zeichenketten ""yes""
   oder ""no"" übergeben.

callback
   Das ist eine beliebige Python-Funktion ohne Argumente. Zum
   Beispiel:

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

color
   Colors can be given as the names of X colors in the rgb.txt file,
   or as strings representing RGB values in 4 bit: ""#RGB"", 8 bit:
   ""#RRGGBB"", 12 bit: ""#RRRGGGBBB"", or 16 bit: ""#RRRRGGGGBBBB""
   ranges, where R,G,B here represent any legal hex digit.  See page
   160 of Ousterhout's book for details.

cursor
   The standard X cursor names from "cursorfont.h" can be used,
   without the "XC_" prefix.  For example to get a hand cursor
   ("XC_hand2"), use the string ""hand2"".  You can also specify a
   bitmap and mask file of your own. See page 179 of Ousterhout's
   book.

distance
   Bildschirmabstände lassen sich entweder in Pixeln oder als absolute
   Abstände angeben. Pixel werden als Zahlen angegeben, absolute
   Abstände als Zeichenketten, deren letztes Zeichen die Einheit
   bezeichnet: "c" für Zentimeter, "i" für Zoll, "m" für Millimeter,
   "p" für typografische Punkte. 3,5 Zoll werden zum Beispiel als
   ""3.5i"" ausgedrückt.

font
   Tk uses a list font name format, such as "{courier 10 bold}". Font
   sizes with positive numbers are measured in points; sizes with
   negative numbers are measured in pixels.

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

justify
   Legal values are the strings: ""left"", ""center"", ""right"", and
   ""fill"".

region
   Das ist eine Zeichenkette mit vier durch Leerzeichen getrennten
   Elementen, von denen jedes ein zulässiger Abstand ist (siehe oben).
   Zum Beispiel sind ""2 3 4 5"", ""3i 2i 4.5i 2i"" und ""3c 2c 4c
   10.43c"" alles zulässige Regionen.

relief
   Determines what the border style of a widget will be.  Legal values
   are: ""raised"", ""sunken"", ""flat"", ""groove"", and ""ridge"".

scrollcommand
   Das ist fast immer die Methode "set()" eines Scrollbar-Widgets,
   kann aber jede Widget-Methode sein, die ein einzelnes Argument
   annimmt.

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


Bindings and Events
-------------------

Die Methode bind des Widget-Befehls erlaubt es dir, auf bestimmte
Ereignisse zu achten und eine Callback-Funktion auszulösen, wenn
dieser Ereignistyp eintritt. Die Form der Methode bind lautet:

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

dabei gilt:

sequence
   is a string that denotes the target kind of event.  (See the
   *bind(3tk)* man page, and page 201 of John Ousterhout's book, *Tcl
   and the Tk Toolkit (2nd edition)*, for details).

func
   ist eine Python-Funktion mit einem Argument, die aufgerufen wird,
   wenn das Ereignis eintritt. Als Argument wird eine Event-Instanz
   übergeben. (So eingesetzte Funktionen werden üblicherweise
   *Callbacks* genannt.)

add
   ist optional und entweder "''" oder "'+'". Eine leere Zeichenkette
   bedeutet, dass diese Bindung alle anderen Bindungen ersetzt, die
   mit diesem Ereignis verknüpft sind. Ein "'+'" bedeutet, dass diese
   Funktion zur Liste der an diesen Ereignistyp gebundenen Funktionen
   hinzugefügt wird.

Zum Beispiel:

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

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

Beachte, wie im Callback "turn_red()" auf das Feld widget des
Ereignisses zugegriffen wird. Dieses Feld enthält das Widget, das das
X-Ereignis aufgefangen hat. Die folgende Tabelle führt die übrigen
Ereignisfelder auf, auf die du zugreifen kannst, und wie sie in Tk
bezeichnet werden – das ist hilfreich, wenn du in den Tk-Man-Pages
nachschlägst.

+------+-----------------------+------+-----------------------+
| 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   | Typ                   |
+------+-----------------------+------+-----------------------+
| %w   | width                 | %W   | widget                |
+------+-----------------------+------+-----------------------+
| %x   | x                     | %X   | x_root                |
+------+-----------------------+------+-----------------------+
| %y   | y                     | %Y   | y_root                |
+------+-----------------------+------+-----------------------+


The index Parameter
-------------------

Einige Widgets verlangen die Übergabe von Parametern vom Typ „index“.
Mit ihnen zeigt man auf eine bestimmte Stelle in einem Text-Widget,
auf bestimmte Zeichen in einem Entry-Widget oder auf bestimmte
Menüeinträge in einem Menu-Widget.

Indizes des Entry-Widgets (index, view index usw.)
   Entry widgets have options that refer to character positions in the
   text being displayed.  You can use these "tkinter" functions to
   access these special points in text widgets:

Indizes des Text-Widgets
   Die Indexschreibweise für Text-Widgets ist sehr umfangreich und
   wird am besten in den Tk-Man-Pages beschrieben.

Menü-Indizes (menu.invoke(), menu.entryconfig() usw.)
   Einige Optionen und Methoden für Menüs wirken auf bestimmte
   Menüeinträge. Wann immer ein Menü-Index für eine Option oder einen
   Parameter gebraucht wird, kannst du Folgendes übergeben:

   * eine ganze Zahl, die auf die numerische Position des Eintrags im
     Widget verweist, von oben gezählt und bei 0 beginnend;

   * die Zeichenkette ""active"", die auf die Menüposition verweist,
     die gerade unter dem Mauszeiger liegt;

   * die Zeichenkette ""last"", die auf den letzten Menüeintrag
     verweist;

   * An integer preceded by "@", as in "@6", where the integer is
     interpreted as a y pixel coordinate in the menu's coordinate
     system;

   * die Zeichenkette ""none"", die überhaupt keinen Menüeintrag
     bezeichnet und meist mit menu.activate() verwendet wird, um alle
     Einträge zu deaktivieren, und schließlich

   * eine Zeichenkette, die als Muster gegen die Beschriftung des
     Menüeintrags abgeglichen wird, von oben nach unten durch das
     Menü. Beachte, dass dieser Indextyp erst nach allen anderen
     berücksichtigt wird; Treffer für Menüeinträge mit der
     Beschriftung "last", "active" oder "none" können daher
     stattdessen als die obigen Literale gedeutet werden.


Bilder
------

Bilder verschiedener Formate lassen sich über die jeweilige
Unterklasse von "tkinter.Image" erzeugen:

* "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.

Beide Bildarten werden über die Option "file" oder "data" erzeugt
(weitere Optionen stehen ebenfalls zur Verfügung).

The image object can then be used wherever an "image" option is
supported by some widget (e.g. labels, buttons, menus). In these
cases, Tk will not keep a reference to the image. When the last Python
reference to the image object is deleted, the image data is deleted as
well, and Tk will display an empty box wherever the image was used.

Siehe auch:

  Das Paket Pillow ergänzt die Unterstützung für Formate wie BMP,
  JPEG, TIFF und WebP sowie weitere.


File Handlers
=============

In Tk lässt sich eine Callback-Funktion an- und abmelden, die aus der
Tk-Hauptschleife aufgerufen wird, sobald auf einem Dateideskriptor
Ein-/Ausgabe möglich ist. Je Dateideskriptor darf nur ein Handler
angemeldet sein. Beispielcode:

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

Diese Funktion steht unter Windows nicht zur Verfügung.

Da du nicht weißt, wie viele Bytes zum Lesen bereitstehen, solltest du
die Methoden "read()" oder "readline()" von "BufferedIOBase" oder
"TextIOBase" möglichst nicht verwenden, da sie auf dem Lesen einer
vorgegebenen Anzahl von Bytes bestehen. Bei Sockets funktionieren die
Methoden "recv()" oder "recvfrom()" gut. Bei anderen Dateien verwende
rohe Lesevorgänge oder "os.read(file.fileno(), maxbytecount)".

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

   Meldet die Dateihandler-Callback-Funktion *func* an. Das Argument
   *file* darf entweder ein Objekt mit einer Methode "fileno()" sein
   (etwa ein Datei- oder Socket-Objekt) oder ein ganzzahliger
   Dateideskriptor. Das Argument *mask* ist eine ODER-Verknüpfung aus
   den drei Konstanten weiter unten. Der Callback wird folgendermaßen
   aufgerufen:

      callback(file, mask)

Widget.tk.deletefilehandler(file)

   Meldet einen Dateihandler ab.

tkinter.READABLE
tkinter.WRITABLE
tkinter.EXCEPTION

   Konstanten, die in den *mask*-Argumenten verwendet werden.
