===== TKK ===== TTK-Widgets sehen eher wie Widgets des Betriebssystems und besser als Tkinter-Widgets. Dafür sind die Tkinter-Widgets leichter konfigurierbar. Die Widgets Combobox, Notebook, Treeview, Progressbar, Separator und Sizegrip gibt es nur als TTK-Widget. Ein GUI-Formular wird mit Hilfe von Widgets aufgebaut. Das sind die grafischen Komponenten, die in der Tkinter- bzw. TTK-Symbolleiste zur Verfügung stehen. Nachfolgend wird grundlegendes zur Verwendung von Widgets angegeben, was in vielen Fällen auch ausreicht. Detailliertere Angaben findet man z.B. in der [[https://anzeljg.github.io/rin2/book2/2405/docs/tkinter/index.html| Tkinter Referenz]]. Ein GUI-Programm legt man mit dem Symbol {{:tkapp.png}} für neue Tk/TTK-Anwendung auf der Registerkarte Programm an. Widgets können per Drag&Drop oder durch Anklicken eines Widgets und anschließendes Klicken in das GUI-Formular platziert werden. Es wird nur absolutes Layout unterstützt. Das reicht für die meisten Zwecke vollkommen aus. Die Gestaltung einer GUI-Oberfläche mit Layoutmanagern ist deutlich schwieriger. Attribute und Ereignisse eines Widgets werden im Objektinspektor konfiguriert. Anfangs werden nur die allerwichtigsten Attribute und Ereignisse angezeigt. Diese Filterung vereinfacht die Arbeit mit dem Objektinspektor. Man kann sich in zwei weiteren Stufen mehr beziehungsweise alle Attribute und Methoden anzeigen lassen. Viele Widgets verfügen über eine Kontrollvariable (CV, engl. control variable) über die man mit get() einen Wert aus dem Widget einlesen oder mit set() in ein Widget ausgeben kann. Der Name einer Kontrollvariable besteht aus den drei Teilen "self.", "Name des Widgets" und "CV". self.CV Der Pythoncode eines GUI-Programms wird unter der Dateierweiterung .pyw gespeichert, das dazugehörige Formular mit der Dateierweiterung .pfm. Beide werden zusammen geöffnet. Schließt man das Formular, so kann man es über das Symbol {{:arrange.png}} der Editorsymbolleiste wieder öffnen. ==== Label ==== {{:label.png}} Mit einem Label-Widget beschriftet man Widgets eines GUI-Formulars. Ein Label kann außer Text auch ein Bild oder Beides darstellen. Um ein Bild darzustellen wählt man im Objektinspektor beim Attribut //Image// die gewünschte Bilddatei aus.\\ Beispiel: {{:de:autolabel.png}} Mit der Methode place(x, y) des Label-Widgets kann man ein Bild animieren. Im [[Beispiele#Auto |Auto-Beispiel]] wird gezeigt, wie das funktioniert. \\ ---- ==== Entry==== {{:entry.png}} Mit einem Entry-Widget kann man Text oder Zahlen ein- oder ausgeben. Den eingegebenen Text erhält man über die get()-Methode der zum Entry gehörenden Kontrollvariablen CV. Beispiel: {{:de:eanentry.png}} EAN = self.eEANCV.get() Benötigt man eine Zahl, so wandelt man den Text mit //int()// in eine Integerzahl oder mit //float()// in eine Dezimalzahl um. Beispiel: Menge = float(self.eMengeCV.get()) ---- ==== Text ==== {{:text.png}} Ein Text-Widget stellt im Gegensatz zum Entry-Widget einen mehrzeiligen Text dar. Im Objektinspektor kann man den Text eingeben. Zur Laufzeit kann man die im Beispiel gezeigte Methode benutzen, um in ein Text-Widget mit dem Namen Output zeilenweise etwas auszugeben. Die Zeilen werden durch das Steuerzeichen "\n" (new line) voneinander getrennt. Beispiel: def output(self, line): self.Output.insert('end', line + '\n') \\ ---- ==== Button ==== {{:button.png}} Jedes Button-Widget erhält automatisch eine Ereignismethode, die beim Anklicken eines Buttons aufgerufen wird. Beim Doppelklicken eines Buttons im GUI-Formular wird der Cursor an den Anfang der zugehörigen Ereignismethode platziert. Beispiel: def button1_Command(self): # ToDo insert source code here pass ---- ==== Checkbutton ==== {{:checkbutton.png}} Ein Checkbutton kann ausgewählt sein oder nicht. Den aktuellen Zustand liefert die zugehörige Kontrollvariable CV mit den Werten 0 (nicht ausgewählt) bzw. 1 (ausgewählt). Beispiel: {{:de:checkbutton.png}} if (cbAusgewaehltCV.get() == 0): ---- ==== RadiobuttonGroup ==== {{:radiobuttongroup.png}}\\ Eine RadiobuttonGroup bietet mehrere Auswahlmöglichkeiten aus denen man eine Option auswählen kann. Eine neu angelegte RadiobuttonGroup erhält automatisch eine Gruppe mit den drei Auswahlmöglichkeiten "America, Europe und Asia" und das Label " Continent ". Im Objektinspektor findet man diese Werte im Attribut //Items// bzw. //Label_// und kann sie dort leicht anpassen. Soll die RadiobuttonGroup keinen Rahmen haben, so löscht man das Label. Zur RadiobuttonGroup gehört eine Kontrollvariable CV, über die man die ausgewählte Option ein- oder ausgeben kann: Beispiele: print(self.rbgKontinentCV.get())) self.rbgKontinentCV.set('Asia') ---- ==== Listbox ==== {{:listbox.png}} Eine Listbox zeigt eine Liste von Strings an, die man im Objektinspektor über das Attribut //ListItems// eingibt. In Abhängigkeit von //SelectMode// kann man ein oder mehrere Strings auswählen. Zur Listbox gehört eine Kontrollvariable CV über die man Zugriff auf alle Strings hat. Für den Zugriff auf die ausgewählten Strings hat die Listbox spezifische Methoden. //curselection()// liefert ein Tupel mit den Positionen aller ausgewählten Strings und //get(i)// den String an Position i. Beispiele: # Ausgabe des ausgewählten Strings bei SelectMode browse oder single i = lbKontinent.curselection()[0] print(self.lbKontinent.get(i) # Ausgabe aller ausgewählten Strings bei SelectMode multiple oder extended for i in self.lbKontinent.curselection(): print(self.lbKontinent.get(i)) Weitere Listbox-Methoden findet man unter [[https://anzeljg.github.io/rin2/book2/2405/docs/tkinter/listbox.html]] ---- ==== Combobox ==== {{:combobox.png}} Eine Combobox ist eine Kombination aus einer Eingabezeile und einer ausklappbaren Auswahlliste. Der Anwender kann zur Laufzeit in der Eingabezeile Text eingeben oder ein Listenelement auswählen. Im Objektinspektor kann man über das Attribut //Values// Strings in die Auswahlliste eingeben. Zur Combobox gehört eine Kontrollvariable CV, über die man die Eingabezeile lesen oder schreiben kann. print(self.combobox1CV.get()) ---- ==== Spinbox ==== {{:spinbox.png}} Mit einer Spinbox kann man Zahlen aus einem Bereich oder Strings einer vorgegebenen Liste auswählen. Im Objektinspektor legt man für einen Zahlbereich Minimum (//From_//), Maximum (//To//), Schrittweite (//Increment//) und aktueller Wert (//Value//) fest. Eine Liste von Strings gibt man beim Attribut //Values// ein. Zur Spinbox gehört eine Kontrollvariable CV, über die man den ausgewählten Wert abfragen kann. Beispiel: print(self.spinbox1CV.get()) ---- ==== Scrollbar ==== {{:scrollbar.png}} Mit einem Scrollbar kann man einen Bildlauf durchführen, bei dem der sichtbare Ausschnitt eines dargestellten Textes oder einer Grafik verschoben wird. Einige Widgets wie z. B. Entry, Text, Listbox oder Canvas können über das //Scrollbar//-Attribut ganz einfach mit horizontalen oder vertikalen Scrollbars versehen werden. ---- ==== Message==== {{:message.png}} Das Message-Widget ähnelt dem Label-Widget, ist aber zur Anzeige von mehrzeiligem Text gedacht. ---- ==== Canvas==== {{:canvas.png}} Ein Canvas ist ein rechteckiger Bereich zum Zeichnen von Grafiken. \\ Das Beispiel wurde mit diesen Zeichenbefehlen gezeichnet. self.canvas1.create_line(10, 10, 10, 100, 100, 10) self.canvas1.create_oval(20, 20, 100, 100) {{:canvasexample.png}} Eine Dokumentation der Zeichenbefehle findet man unter [[https://anzeljg.github.io/rin2/book2/2405/docs/tkinter/canvas.html]]. ---- ==== Frame==== {{:frame.png}} Ein Frame ist ein Container für andere Widgets. Beispielsweise ist die RadiobuttonGroup ein Frame, der Radiobuttons enthält. Mit Frames kann man gut grafische Oberflächen strukturieren. Zum Platzieren eines Widgets in einem Frame klickt man es in der TTK-Symbolleiste an und klickt dann in das Frame. Frames werden beispielsweise beim Notebook-Widget benutzt. ---- ==== LabelFrame ==== {{:labelframe.png}} Ein LabelFrame ist ein Frame, das zusätzlich einen Rahmen mit integriertem Label hat. ---- ==== Scale ==== {{:ttkscale.png}} Der Zweck eines Scale-Widgets besteht darin, einen Zahlenwert innerhalb eines bestimmten Bereichs festzulegen. Ein Scale-Widget hat eine Kontrollvariable CV, um den aktuellen Wert zu lesen oder zu schreiben. print(self.scale1CV.get()) ---- ==== LabeledScale ==== {{:labeledscale.png}} Im Unterschied zum Scale-Widget wird beim LabeledScale der Zahlenwert als Zahl angezeigt. {{:labeledscaleexample.png}} ---- ==== PanedWindow ==== {{:ttkpanedwindow.png}} Ein PanedWindow ist ein Container für untergeordnete Widgets. Jedes PanedWindow enthält einen horizontalen oder vertikalen Stapel untergeordneter Widgets. Mit der Maus kann der Benutzer die Grenzen zwischen den untergeordneten Widgets hin und her ziehen. Im Beispiel befindet sich oben ein Canvas und unten ein Text-Widget. {{:ttkpanedwindowexample.png}} Zum Einfügen eines Widgets in ein PanedWindow klicken Sie in der TTK-Symbolleiste zuerst das Widget und dann in das PanedWindow. ---- ==== Menu ==== {{:menu.png}} Ein Menu-Widget ist eine Menüleiste mit aufklappbaren Untermenüs. {{:menuexample.png}} Das Menü wird über das Attribut //MenuItems// definiert, bei dem durch entsprechende Einrückung die Menüstruktur erzeugt wird. Bei einem neu erzeugtem Menu sieht diese Struktur so aus: File New Python XML Load Save Edit Copy Paste - Delete Für die Menüeinträge werden Ereignismethoden angelegt, die bei der Auswahl des Menüeintrags aufgerufen werden. def menu1FileNewPython_Command(self): # ToDo insert source code here pass ---- ==== PopupMenu ==== {{:popupmenu.png}} Ein PopupMenu ist ein Kontextmenu, das mit der rechten Maustaste aufgerufen wird. Es wird wie beim Menu-Widget über das Attribut //MenuItems// definiert. Man kann jedem Widget ein PopupMenu zuweisen. Dazu öffnet man im Objektinspektor die Registerkarte //Ereignisse// und wählt Button "Rechts" für das ButtonPress-Ereignis. {{:de:popupmenuexample.png}} In der dabei angelegten Ereignismethode programmiert man das Anzeigen des PopupMenüs an der angeklickten Position. def root_ButtonPress(self, event): self.popupMenu1.post(event.x_root, event.y_root) pass ---- ==== Menubutton ==== {{:menubutton.png}} Ein Menubutton ist ein Button, der beim Anklicken ein PopupMenu anzeigt. Das PopupMenu muss zusätzlich angelegt und dann beim Attribut //Menu// des Menubuttons eingetragen werden. ---- ==== OptionMenu ==== {{:optionmenu.png}} Mit einem OptionMenu kann man in der Art eines Menüs aus einer vorgegebenen Stringliste ein Element auswählen. Die Stringliste wird im Attribut //MenuItems// angegeben. Auf die ausgewählte Option greift man über die Kontrollvariable CV zu. print(self.optionMenu1CV.get()) ---- ==== Notebook==== {{:notebook.png}} Ein Notebook-Widget stellt oben Registerkarten bereit, mit denen unten befindliche Frames aufgeschlagen werden können. {{:notebookexample.png}} ---- ==== Treeview==== {{:treewidget.png}} Ein Treeview stellt eine hierarchische Struktur baumartig dar. Durch entsprechende Einrückung wird die Struktur über das Attribut //Items// festgelegt. Diese Struktur ist anfangs vorgegeben: First node A node B Second node C node D ---- ==== Progressbar ==== {{:progressbar.png}} Ein Progressbar stellt einen Fortschrittsbalken dar. ---- ==== Separator ==== {{:separator.png}} Ein Separator ist eine horizontale oder vertikale Strecke, mit der die GUI-Oberfläche strukturiert werden kann. ---- ==== Sizegrip ==== {{:sizegrip.png}} Ein Sizegrip-Widget wird in die rechte untere Ecke platziert um die Größe des gesamten Anwendungsfensters ändern zu können. ----