Kapitel 19
Komplexe Benutzungsoberflächen
554
Erläuterung:
Das Listing enthält im Wesentlichen nur die Zeilen, die eingefügt werden müssen (fett). Der
bestehende Programmtext braucht nicht geändert zu werden.
#1: Der Aufruf der privaten Methode self.__addDateimenue() erfolgt vor dem Aufruf
self.__addFormatmenue(), damit das Dateimenü – wie üblich – als Erstes (links) in der
Meleiste erscheint.
#2: Der neuen Instanz der Klasse Menu wird die Menüleiste als Master zugeordnet.
#3: Einfügen von Kommando-Choices in das Menü.
#4: Eine Separatorlinie wird nach den Kommandos Laden und Speichern hinzugefügt.
#5: Das Menu-Widget wird als Kaskade (Untermenü) in die Menüleiste eingebaut.
#6: Die Funktion filedialog.askopenfile() gibt ein zum Lesen geöffnetes File-Objekt
zurück.
#7: Der bisherige Text im Text-Widget wird gelöscht.
#8: Die geöffnete Datei wird gelesen und der String in das Text-Widget eingefügt.
#9: Die Funktion filedialog.asksaveasfile() öffnet die ausgewählte Datei zum Schrei-
ben und gibt das File-Objekt zurück.
#10: In die Datei wird der Inhalt des Text-Widgets geschrieben.
#11: Die Funktion messagebox.askyesno() gibt dann den Wert True zurück, wenn der
Button
JA angeklickt worden ist. In diesem Fall werden das Anwendungsfenster und alle
Unter-Widgets zerstört und damit die Anwendung beendet.
19.6 Applikationen mit mehreren Fenstern
In diesem Abschnitt programmieren wir eine einfache Entwicklungsumgebung für Python.
Die Besonderheit: Die Benutzungsoberfläche besteht aus zwei Applikationsfenstern, dem
Editor- und dem Ausgabe-Fenster (Abbildung 19.7).
Im Editor-Fenster kann man den Programmtext eingeben. Es gibt eine Menüleiste mit
einem einzigen Pulldown-Menü namens B
EFEHLE. Es enthält zwei Schaltflächen: PRO-
GRAMM STARTEN und ENDE.
Wenn man auf P
ROGRAMM STARTEN klickt, wird der Text im Editorfenster als Python-Pro-
gramm interpretiert und ausgeführt. Das Ergebnis – die Bildschirmausgabe von
print()-
Anweisungen oder eine Fehlermeldung – wird in einem zweiten Fenster dargestellt.
self.datei.close()
def beenden (self): #11
if messagebox.askyesno('Beenden',
'Wollen Sie wirklich das Programm beenden?'):
self.fenster.destroy()
editor = Editor()
555
19.6
Applikationen mit mehreren Fenstern
Wählt man den Befehl ENDE, werden beide Fenster geschlossen. (Dagegen bewirkt ein Klick
auf das X in der oberen rechten Ecke eines Fensters, dass lediglich das ausgewählte einzelne
Fenster geschlossen wird.)
Abb. 19.7: Eine Miniatur-Entwicklungsumgebung mit zwei Fenstern
Übrigens, auch die Entwicklungsumgebung IDLE ist mit tkinter programmiert worden.
Wenn mehrere Fenster im Spiel sind, müssen einige Dinge beachtet werden, die bei einem
einzigen Fenster keine große Rolle spielen.
Beim Start des Programms sollten sich die Fenster nicht gegenseitig überdecken, sondern
in vernünftiger Größe nebeneinander positioniert werden. Wie kann man das bewerkstelli-
gen? Fenster sind Objekte der Klasse
Tk. Sie besitzen die Methode geometry(), mit der Sie
durch einen String die Position und Größe des Fensters festlegen können (im Listing Zeilen
#2, #3). Dieser String besteht aus zwei Teilen:
Der erste Teil hat das Format nxm (z.B. "100x100") und definiert die Größe des Fensters.
Der zweite Teil hat das Format +x+y (z.B. "+10+10"). Damit wird die Position der lin-
ken oberen Ecke des Fensters bestimmt. Sie übergeben der Methode
geometry()
einen String, der entweder nur die Größe oder nur die Position oder beides bestimmt.
Gültige Aufrufe sind z.B.
geometry("100x100"), geometry("+10+10") oder geome-
try("100x100+10+10")
.
Bei Programmen mit mehreren Fenstern ist auch zu beachten, dass die Funktion
main-
loop()
nur einmal aufgerufen wird. Das ist sehr wichtig! Sonst funktioniert das Programm
nicht. Zwar ist
mainloop() eine Methode von Fenstern, d.h. Objekten der Klasse Tk. Es gibt
aber im Modul
tkinter auch eine allein stehende Funktion namens mainloop().
Abb. 19.8: UML-Klassendiagramm des Programmeditors
Das Skript enthält zwei Klassendefinitionen, eine Klasse namens Editor für das Editorfens-
ter und eine zweite Klasse namens
Ausgabe für das Ausgabefenster. Abbildung 19.8 zeigt
Editor
starten()
beenden()
Ausgabe
write()
Kapitel 19
Komplexe Benutzungsoberflächen
556
ein UML-Klassendiagramm. Ein Objekt der Klasse Ausgabe ist über das Attribut ausgabe
(Zeile #5) an das Editor-Objekt gekoppelt. Die Klasse Ausgabe muss eine Methode write()
besitzen. Denn die Systemausgabe wird an ein Objekt dieser Klasse umgeleitet (Zeile #6).
Skript:
#programm_editor.pyw
import sys #1
from tkinter import *
class Ausgabe(object):
def __init__ (self):
self.fenster = Tk()
self.fenster.geometry('200x150+10+10') #2
self.fenster.title('Ausgabe')
self.text= Text(self.fenster,
wrap=WORD, font=('Courier', 10))
self.text.pack(expand=1)
def write(self, s): #3
self.text.insert(END, s)
class Editor(object):
def __init__ (self):
self.fenster = Tk()
self.fenster.geometry('250x150+240+10') #4
self.fenster.title('Programmeditor')
self.text= Text(self.fenster,
wrap=WORD, font=('Courier', 10))
self.text.pack(expand=1)
self.menueleiste=Menu(self.fenster)
self.fenster.configure (menu=self.menueleiste)
self.menue= Menu(master=self.menueleiste)
self.menueleiste.add_cascade(label='Befehle',
menu=self.menue)
self.menue.add_command(label='Programm starten',
command = self.starten)
self.menue.add_command(label='Ende',
command=self.beenden)
self.ausgabe = Ausgabe() #5
sys.stdout = sys.stderr = self.ausgabe #6

Get Python 3 - Lernen und professionell anwenden now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.