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