Popup - Tkinter Popup Widgets (z.B. für Context-Menüs)
Verfasst: Freitag 16. März 2007, 17:59
Erstmal ein Hallo in die Runde!
Ich habe schon viele Programme und Codesegmente gesehen, wo die Tkinter popup-Methode für Context-Menüs verwendet wurde. Aber ich kenne kein Widget und keine wirklich einfache Methode, um schnell und unkompliziert ein Popup-Widget zu erzeugen.
Darum habe ich mir mal Gedanken gemacht, wie man die Erstellung so weit wie möglich vereinfachen kann und kam zu folgendem Ergebnis:
Ich denke, der Code ist nicht zu Umfangreich und die Methoden gut dokumentiert. Wäre schön, wenn ihr eure Meinung zur Brauchbarkeit und evtl. Verbesserungsvorschläge posten würdet.
Viele Grüße,
der Michel
Ich habe schon viele Programme und Codesegmente gesehen, wo die Tkinter popup-Methode für Context-Menüs verwendet wurde. Aber ich kenne kein Widget und keine wirklich einfache Methode, um schnell und unkompliziert ein Popup-Widget zu erzeugen.
Darum habe ich mir mal Gedanken gemacht, wie man die Erstellung so weit wie möglich vereinfachen kann und kam zu folgendem Ergebnis:
Code: Alles auswählen
## -*- coding: iso-8859-1 -*- ##
###################################
## popup.py ##
##===============================##
## Michael Schneider ##
## v1.0 - 16.03.2007 ##
###################################
import Tkinter as TI
class Popup:
"Erzeugt mit wenig Aufwand ein einfaches Popup-Menu"
def __init__(self, root, items, trigger="<3>", preselect=-1):
"""Parameter:
root - Widget, auf dem das Popup erscheinen soll
items - Liste oder Tupel mit Elementen, die die Einträge
und Callbackfunktionen repräsentieren.
Mögliche Elementtypen sind Tupel, Listen und Dictionaries.
Tupel: '(' [Aufschrift, [Callbackfunktion]] ')' !!!Komma beachten!!!
Liste: '[' [Aufschrift [, Callbackfunktion]] ']'
Dict: '{' [Aufschrift ':' Callbackfunktion] '}'
=> Sind zwei Parameter angegeben, wird der erste als Aufschrift, der zweite
als Callback interpretiert.
=> Wird die Callbackfunktion ausgelassen, wird nur die Aufschrift gezeigt.
=> Werden keine Parameter übergeben, wird ein Separator eingesetzt.
trigger - der Tkinter-Event, der das Popup-Fenster aufruft, Default ist Rechtsklick
preselect - der initial ausgewählte Eintrag, Default ist -1 = popup erscheint
unterhalb rechts der aktuellen Mausposition
"""
self.wMaster = root
self.lItems = items
self.sTrigger = trigger
self.iPreselect = preselect
root.bind(trigger, self)
def __call__(self, Event):
"""Eventfunktion, die das Popup erzeugt."""
wPopup = TI.Menu(self.wMaster, tearoff=False)
self.create_menu(wPopup, self.lItems)
try:
if self.iPreselect < 0:
wPopup.tk_popup(Event.x_root, Event.y_root)
else:
wPopup.tk_popup(Event.x_root, Event.y_root, self.iPreselect)
finally:
wPopup.grab_release()
def create_menu(self, wPopup, lItems):
"""Analysiert die Liste der Einträge und setzt die Parameter."""
import types
for Item in lItems:
if type(Item) in (types.TupleType, types.ListType):
Command = None
if len(Item) is 0: sLabel = ""
if len(Item) >= 2: Command = Item[1]
else: Command = None
if len(Item) >= 1: sLabel = Item[0]
self.add_menu_item(wPopup, sLabel, Command)
if type(Item) is types.DictType:
if Item: sLabel, Command = Item.items()[0]
else: sLabel, Command = "", None ## leeres Dictionary -> Separator
self.add_menu_item(wPopup, sLabel, Command)
def add_menu_item(self, wPopup, sLabel, Command):
"""Erzeugt die Einträge anhand der Parameter."""
if sLabel: wPopup.add_command(label=sLabel, command=Command)
else: wPopup.add_separator()
if __name__=="__main__":
def print_ok():
print "okay gewaehlt"
tk = TI.Tk()
TI.Label(tk, text="Rechtsklick: langes Testmenu ; Linksklick: kurzes Testmenu").grid(padx=20, pady=10)
###################################################
## Zwei Beispiele
Popup(tk, ({"Ok": print_ok},
{},
["nix passiert"],
{"hier auch nicht":None},
(),
("Ende", tk.destroy)))
Popup(tk, [["Ende", tk.destroy]], trigger="<1>", preselect=0)
tk.mainloop()
Viele Grüße,
der Michel