Der Geometrie-Manager "Packer"


Am einfachsten lernt man die Arbeitsweise des "Packers" an Beispielen kennen.

Standardmäßig werden die Elemente von oben nach unten im Master-Widget plaziert:

Beispiel 1:

	
#! /usr/bin/python
import Tkinter 
from Tkconstants import *

class test1_GUI:
   def __init__(self):               
      #
      # Fenster mit Startposition und Startabmessungen definieren (Abschnitt 1)
      #
      self.oWindow=Tkinter.Tk()
      self.oWindow.title("Test - Dr. Kokavecz") 

      # Beschriftung oberhalb Eingabezeile  (Abschnitt 2)
      oLabel=Tkinter.Label(self.oWindow, text='Hallo 1')
      oLabel.pack(padx=5, pady=5)

      # Eingabezeile  (Abschnitt 3)
      self.oEingabe=Tkinter.Entry(self.oWindow)
      self.oEingabe.pack(padx=5, pady=5) 
      self.oEingabe.bind("<Return>",self._Aktion)

      # Beschriftung unterhalb Eingabezeile   (Abschnitt 4)
      oLabel=Tkinter.Label(self.oWindow, text='Hallo 2')
      oLabel.pack(padx=5, pady=5)

      # Weitere Beschriftung unterhalb Eingabezeile   (Abschnitt 5)
      oLabel=Tkinter.Label(self.oWindow, text='Hallo 3')
      oLabel.pack(padx=5, pady=5)

      Tkinter.mainloop()


   def _Aktion(self,event):
      self.oWindow.destroy()

      

x=test1_GUI()

d10

Und hier das per Maus vergrößerte Fenster:


d11

Werden keine Vorgaben über die Startgröße des Fensters gemacht, so berechnet der "Packer" die erforderliche Größe automatisch. Welche Konsequenzen bestimmte pack-Anweisungen haben, erkennt man oft erst nach dem "Aufziehen" (Vergrößern) des Fensters mit der Maus. Aus diesem Grunde sind für die Beispielprogramme immer zwei Bildschirmphotos gemacht worden.

Hier einige Erläuterungen zu den einzelnen Programmabschnitten:


Beispiel 2: Will man die Elemente untereinander aber mit unterschiedlicher Ausrichtung haben, so erfolgt das mit Hilfe der "anchor"-Angabe (Süd, West usw.):

#! /usr/bin/python
import Tkinter 
from Tkconstants import *

class test1_GUI:
   def __init__(self):               
      #
      # Fenster mit Startposition und Startabmessungen definieren
      #
      self.oWindow=Tkinter.Tk()
      self.oWindow.title("Test - Dr. Kokavecz") 

      # Beschriftung oberhalb Eingabezeile
      oLabel=Tkinter.Label(self.oWindow, text='Hallo 1')
      oLabel.pack(padx=5, pady=5, anchor=E)

      # Eingabezeile
      self.oEingabe=Tkinter.Entry(self.oWindow)
      self.oEingabe.pack(padx=5, pady=5) 
      self.oEingabe.bind("<Return>",self.Aktion)

      # Beschriftung unterhalb Eingabezeile
      oLabel=Tkinter.Label(self.oWindow, text='Hallo 2')
      oLabel.pack(padx=5, pady=5, anchor=W)

      # Weitere Beschriftung unterhalb Eingabezeile
      oLabel=Tkinter.Label(self.oWindow, text='Hallo 3')
      oLabel.pack(padx=5, pady=5)

      Tkinter.mainloop()

   def Aktion(self,event):
      self.oWindow.destroy()
      

x=test1_GUI()



Das Ergebis ist:

ausrichtung


Beispiel 3:

Im folgenden Beispiel werden die Objekte von oben nach positioniert, das 4. Objekt wird aber mit Bezug zur unteren Fensterkante gepackt (side=BOTTOM):

#! /usr/bin/python
import Tkinter 
from Tkconstants import *

class test1_GUI:
   def __init__(self):               
      #
      # Fenster mit Startposition und Startabmessungen definieren
      #
      self.oWindow=Tkinter.Tk()
      self.oWindow.title("Test - Dr. Kokavecz") 

      # Beschriftung oberhalb Eingabezeile
      oLabel=Tkinter.Label(self.oWindow, text='Hallo 1')
      oLabel.pack(padx=5, pady=5, anchor=E)

      # Eingabezeile
      self.oEingabe=Tkinter.Entry(self.oWindow)
      self.oEingabe.pack(padx=5, pady=5) 
      self.oEingabe.bind("<Return>",self.Aktion)

      # Beschriftung unterhalb Eingabezeile
      oLabel=Tkinter.Label(self.oWindow, text='Hallo 2')
      oLabel.pack(padx=5, pady=5, anchor=W)

      # Weitere Beschriftung unterhalb Eingabezeile
      oLabel=Tkinter.Label(self.oWindow, text='Hallo 3')
      oLabel.pack(padx=5, pady=5, side=BOTTOM)

      Tkinter.mainloop()

   def Aktion(self,event):
      self.oWindow.destroy()
      

x=test1_GUI()


Das Ergebis ist:

d22a


Beispiel 4:

Die Kombination von "übereinander" und "nebeneinander" ist allerdings etwas komplizierter, denn aus systematischen Gründen belegt der Packer bestimmte Bereiche des Hauptfensters so, dass nach dem Packen von Objekten immer nur ein rechteckiges "Restarreal" für weitere Elemente verwendet werden kann.

d3

Der erste "Packvorgang" belegt das links durch die vertikale Linie abgetrennte Rechteck, für die weiteren Packbefehle bleibt das rechte Rechteck übrig. Der nächste Packbefehl belegt diesen Bereich nach den üblichen Regeln. Die die Packbefehle nun von oben nach unten orientiert sind, bleibt nach jedem "pack" das jeweils verbleibende Rechteck "rechts-unten" für weitere Packvorgänge übrig.

#! /usr/bin/python
import Tkinter 
from Tkconstants import *

class test1_GUI:
   def __init__(self):               
      #
      # Fenster mit Startposition und Startabmessungen definieren
      #
      self.oWindow=Tkinter.Tk()
      self.oWindow.title("Test - Dr. Kokavecz") 

      # Beschriftung oberhalb Eingabezeile
      oLabel=Tkinter.Label(self.oWindow, text='Hallo 1')
      oLabel.pack(padx=5, pady=5, side=LEFT)

      # Eingabezeile
      self.oEingabe=Tkinter.Entry(self.oWindow)
      self.oEingabe.pack(padx=5, pady=5) 
      self.oEingabe.bind("<Return>",self.Aktion)

      # Beschriftung unterhalb Eingabezeile
      oLabel=Tkinter.Label(self.oWindow, text='Hallo 2')
      oLabel.pack(padx=5, pady=5)

      # Weitere Beschriftung unterhalb Eingabezeile
      oLabel=Tkinter.Label(self.oWindow, text='Hallo 3')
      oLabel.pack(padx=5, pady=5)

      Tkinter.mainloop()

   def Aktion(self,event):
      self.oWindow.destroy()
      

x=test1_GUI()



Beispiel 5:

Zum Abschluss noch ein Demonstrationsbeispiel, an dem man die Arbeitsweise des beschriebenen "Packers" gut nachvollziehen kann. Ich habe mit Hilfslinien nach jedem Pack-Vorgang den verbleibenden Platz sichtbar gemacht. Zum Schluss kann nur noch das freie Rechteck in der Mitte mit weiteren grafischen Objekten belegt werden!

d40

Und hier noch der zugehörige Quelltext:

#! /usr/bin/python
import Tkinter 
from Tkconstants import *

class test1_GUI:
   def __init__(self):               
      self.oWindow=Tkinter.Tk()
      oLabel1=Tkinter.Label(self.oWindow, text='Hallo 1')
      oLabel1.pack(padx=5, pady=5, side=LEFT)

      oLabel2=Tkinter.Label(self.oWindow, text='Hallo 2')
      oLabel2.pack(padx=5, pady=5) # default: side=TOP !

      oLabel3=Tkinter.Label(self.oWindow, text='Hallo 3')
      oLabel3.pack(padx=5, pady=5, side=RIGHT)

      oLabel4=Tkinter.Label(self.oWindow, text='Hallo 4')
      oLabel4.pack(padx=5, pady=5, side=BOTTOM)

      oLabel5=Tkinter.Label(self.oWindow, text='Hallo 5')
      oLabel5.pack(padx=5, pady=5)

      oLabel6=Tkinter.Label(self.oWindow, text='Hallo 6')
      oLabel6.pack(padx=5, pady=5, side=RIGHT)

      oLabel7=Tkinter.Label(self.oWindow, text='Hallo 7')
      oLabel7.pack(padx=5, pady=5, side=LEFT)

      oLabel8=Tkinter.Label(self.oWindow, text='Hallo 8')
      oLabel8.pack(padx=5, pady=5)

      Tkinter.mainloop()

x=test1_GUI()


Mit Hilfe von "Frames" ist es möglich, mehrere Strukturen nach den Regeln des "Packers" ineinanderzulegen. So kann man zunächst mehrere Frames untereinander legen und dann innerhalb eines der Frames - unabhängig von der Situation in den anderen Frames - beispielsweise seine Grafik-Objekte von links nach rechts anordnen.

Dieser Technik wurde verwendet bei der Realisierung des Dateiverwaltungsfensters, das als Aufgabenstellung dieses Kapitels zu sehen ist. Zusätzlich wurden dabei Kombinationen von Grafischen Elementen zu eigenen Klassen gemacht, um zu zeigen, wie man den Schülern fertige Bausteine an die Hand geben kann. Insbesondere die Scrollbar-Programmierung ist nicht ganz einfach und man sollte in der Literatur nachlesen, welche Besonderheiten zu beachten sind.

zurück

Dr. Bernd Kokavecz
25.04.2000