Hi I hope someone can help me with the following problem: I have attached a menu class which is part of a project I have written. As my main menu names can be multiple lines I am using the image facility, without text, of Menu. However I cannot get an accelerate key to work. Can anyone please assist me? --
Regards |
Phone: |
+27 (0)21-671-1866 |
Mobile: |
+27 (0)82-900-5260 |
Fax: |
+27 (0)86-262-1838 |
""" SYNOPSIS These is the Menu class used in TARTAN. This file is part of Tartan Systems (TARTAN).
AUTHOR Written by Paul Malherbe, <p...@tartan.co.za> COPYING Copyright (C) 2004-2013 Paul Malherbe. Free use of this software is granted under the terms of the GNU General Public License (GPL) as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. TARTAN is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with TARTAN, if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA or view/download it at http://www.gnu.org/licenses/gpl.txt """ from Tkinter import * from PIL import Image, ImageDraw, ImageFont, ImageTk def getUnderline(dic, txt, sav=False): """ dic = dictionary name to use txt = text to find underline for sav = keep existing underlined character """ if not txt: return dic, 0 if sav and txt.count("_"): return dic, txt.index("_") pos = 0 for c in txt: # If the label is Exit, try and make x the hot key if txt == "Exit" and c == "E": continue if (ord(c) in range(65, 91) or ord(c) in range(97, 123)) and \ (dic.count(c.lower()) == 0 and \ dic.count(c.upper()) == 0): dic.append(c) pos = txt.index(c) break return pos class TartanMenu: """ Use this to class to draw menus as follows: Create a list of lists of MenuBar Items for example: men = [["MM","Control", "Control Routines and exit"], ["MM","General", "General Ledger Menu"], ["MM","Creditors", "Creditor's Ledger Menu"], ["MM","Debtors", "Debtor's Ledger Menu"], ["MM","Stores", "Stores Ledger Menu"], ["MM","Help", "User's Manual and About","right"]] Where the fields are as follows: MM = Main Menu: Menu Name Detail CM = Cascade Menu: Parent Name Menu Name Detail Create a list of lists of Menu Items for example: mod = [["F","Control","tarCfg","Configure Tartan"], ["PNN","Control","co1010","Company Records"], ["F","Control","sysEnd","Exit Program"], ["CY","Control","l -l","Directory"]] Where the fields are as follows: Type F = Function P123 where 1 = Requiring Company Number (Y/N) 2 = Requiring Period Selection (Y/N) 3 = Pass the User Name to the Module Parent Menu Name Program, Function or Command Security Level Prompt Routine number if required for type P above Draw the menus as follows: menu = TartanMenu(usr, men, mod, ign, lvl, cmd) mf = Tartan MainFrame usr = User Name men = Menues mod = Modules lvl = Security Level cmd = Command to Execute on Selection img = Background Image to Display """ def __init__(self, **args): for arg in args: exec "self.%s = args[arg]" % arg self.setVariables() def setVariables(self): # Create a list of menues and a dictionary of modules menues = [] self.moddic = {} for m in self.mod: if not self.lvl == None and m[3] > self.lvl: continue if m[1] not in menues: menues.append(m[1]) if m[0][0] == "P": mm = "mm_%s" % m[2][:2] if mm not in menues: menues.append(mm) if len(m) == 6: mod = "%s%s" % (m[2][:-1], m[5]) self.moddic[mod] = [m[0], m[4], m[5]] else: mod = "%s%s" % (m[2][:-1], 0) self.moddic[mod] = [m[0], m[4], None] else: mod = m[2] self.moddic[mod] = [m[0], m[4], None] self.menues = [] for men in self.men: if men[0] == "MM" and men[1] in menues: self.menues.append(men) elif men[2] in menues: self.menues.append(men) def drawMenu(self): self.menubar = Menu(fg="black", bg="white", activebackground="black") self.mf["menu"] = self.menubar labs = {} mwth = 0 for m in self.menues: if m[0] == "MM": if "mbar" in labs: pass else: labs["mbar"] = [] exec "%s = Menu(self.menubar, tearoff=False)" % m[1] pos = getUnderline(labs["mbar"], m[2]) img = self.createLabel(m[2], pos) nam = m[2].split()[0].split("'")[0] exec "image_%s = img" % nam exec "self.menubar.add_cascade(image=img, menu=%s)" % m[1] exec "cm1 = lambda event, self=self, menu=%s: "\ "self.postMenu(event, menu)" % m[1] self.menubar.bind_all("<Alt_L><%s>" % m[2][pos].upper(), cm1) self.menubar.bind_all("<Alt_L><%s>" % m[2][pos].lower(), cm1) self.menubar.bind_all("<Escape>", self.unpostMenu) mwth += img.width() elif m[0] == "CM": if m[1] in labs: pass else: labs[m[1]] = [] exec "%s = Menu(%s, tearoff=False)" % (m[2], m[1]) pos = getUnderline(labs[m[1]], m[3]) exec '%s.add_cascade(label="%s", menu=%s, '\ 'underline=pos)' % (m[1], m[3], m[2]) for m in self.mod: if m[3] > self.lvl: continue if m[1] in labs: pass else: labs[m[1]] = [] if m[0][0] == "P" and len(m) == 6: rtn = int(m[5]) else: rtn = None if m[4] == "Quit": exec "%s.add_separator()" % m[1] pos = getUnderline(labs[m[1]], m[4]) cmd = (self.menubar.register(self.cmd), m[0], m[2], rtn) #stk = m[2].lower() #if stk in images: # image = Image.open(images[stk]) #elif stk in aliases and os.path.isfile(aliases[stk]): # image = Image.open(aliases[stk]) #else: # image = None image = None if image: image = image.resize((20, 20), 0) exec "self.image%s = ImageTk.PhotoImage(image)" % stk exec '%s.add_command(label="%s", command=cmd, underline=pos, '\ 'image=self.image%s, compound="left")' % (m[1], m[4], stk) else: exec '%s.add_command(label="%s", command=cmd, underline=pos)' \ % (m[1], m[4]) self.mf.geometry("%sx%s" % (mwth, 200)) self.mf.mainloop() def postMenu(self, event, menu): menu.event_generate("<Enter>") menu.event_generate("<Button-1>") menu.event_generate("<Leave>") #menu.post(event.x_root, event.y_root) #self.posted = menu #menu.focus_force() def unpostMenu(self, event): try: self.posted.unpost() except: pass def createLabel(self, text, pos): unl = text[pos] text = text.split() if len(text) == 1: text.insert(0, "") elif len(text) == 3: text[1] = "%s %s" % (text[1], text[2]) del text[2] self.font = ImageFont.truetype("DejaVuSans-Bold.ttf", 12) img = Image.new("RGBA", (70,30), (255,255,255)) self.draw = ImageDraw.Draw(img) self.draw.text((0, 0),text[0],(0,0,0), font=self.font) done = self.drawUnderline(text[0], unl, 14) self.draw.text((0, 15),text[1],(0,0,0), font=self.font) if not done: self.drawUnderline(text[1], unl, 28) return ImageTk.PhotoImage(img) def drawUnderline(self, text, unl, y): done = False x = 0 for c in text: if c == unl: w = self.font.getsize(c)[0] self.draw.line((x, y, x+w, y), fill=(0,0,0), width=1) done = True break return done def closeMenu(self, children=True): self.menubar.destroy() self.mf.quit() if __name__ == "__main__": def doNothing(m0, m2, rtn): print m0, m2, rtn if m2 == "sysEnd": menu.closeMenu() tk = Tk() args = { "mf": tk, "men": [ ["MM","mm_sy","System"], ["MM","mm_uy","General Utilities"], ["MM","mm_hp","Help","right"]], "mod": [ ["F","mm_sy","chgUsr",0,"Change User"], ["F","mm_sy","chgPwd",0,"Change Password"], ["F","mm_sy","tarUsr",7,"User's Maintenance"], ["F","mm_sy","sysUpd",0,"Upgrade System"], ["F","mm_sy","tarUpd",5,"Update File Formats"], ["PNNN","mm_sy","tb1040",9,"Copy Tables"], ["F","mm_sy","tarBck",0,"Backup Database"], ["F","mm_sy","tarRes",5,"Restore Database"], ["F","mm_sy","tarCfg",0,"Preferences"], ["F","mm_sy","sysEnd",0,"Quit"], ["PYNN","mm_uy","bm1010",0,"Bulk Mail/SMS Utility"], ["PNNN","mm_uy","fc1010",0,"Loan/Lease Calculator"], ["PNNY","mm_uy","pm1010",0,"Personal Password Manager"], ["PNNY","mm_uy","rp1010",2,"Report Generator"], ["PNNN","mm_uy","pw1010",0,"Server User Maintenance"], ["PNNY","mm_uy","td1010",0,"Telephone Directory"], ["PNNN","mm_uy","tp1010",5,"Template Manager"], ["F","mm_uy","showCal",0,"Calendar"], ["F","mm_hp","doAbout",0,"About"], ["F","mm_hp","doManual",0,"Manual"]], "lvl": 9, "cmd": doNothing} menu = TartanMenu(**args) menu.drawMenu()
_______________________________________________ Tkinter-discuss mailing list Tkinter-discuss@python.org http://mail.python.org/mailman/listinfo/tkinter-discuss