[SOLVED] Tkinter menu: trying to use item label in callback
Linux - SoftwareThis forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Tkinter menu: trying to use item label in callback
Hello,
In a tkinter app I have a two-level menu with book categories, like Exact - Astronomy
or Music - Classic. The second level is added to the first one with add_cascade.
I want to use the labels of any duo in the appropriate command-callback, without writing them litterally in the callback. So far in my experiments I allways get back the labels of the last duo fed into the gui. I do understand now why. But how to get the labels I clicked on ?
KlaasJan
Tkinter menu: trying to use item label in callback
Thanks for looking at my problem.
I had to translate my script from dutch into my english.
My difficulty is with the dictionary self.rubmap{},
in which each self.rubmap[mainLabel] refers to a menu for this main-label,
and to which are added the sub-labels, each with a command-option.
The script:
# make a menu-bar for one item only:
self.uMenu = Menu(self.root,type='menubar')
# fill het hele menu:
self.fillRubric()
# put the newly created rubMenu below uMenu:
self.uMenu.add_cascade(label='click',menu=self.rubMenu)
# display the completed uMenu
self.uMenu.pack(side=LEFT)
def fillRubric(self):
'''
Main-rubrics and sub-rubrics come from a file called 'afdeling',
which means rubric (!).
A part of it looks like this, an indented line is a sub-rubric:
# maak een vooralsnog onzichtbaar sub-menu rubMenu:
rubricfile = "/kappa/data/afdeling"
self.rubMenu = Menu(self.uMenu,tearoff=0)
self.rubmap = {}
rf = open(rubricfile,'r')
mainRubCounter = 0
subRubCounter = 0
for fileLine in rf:
# a sub-rubric starts in the import-file with at least one space:
mainRubric = False if fileLine.startswith(" ") else True
self.shortLine = fileLine.strip()
if self.shortLine.startswith('#'): continue
if len(self.shortLine) < 1: continue
if mainRubric:
if mainRubCounter > 0:
# A main-rubric can only be cascaded when allof its subs are read,
# at least that is what I think how it works,
# so I made it a one-fase-off procedure.
self.rubMenu.add_cascade(label=self.mainLabel,menu=self.rubmap[self.mainLabel])
print("Menu: rubMenu Index: %s Label: %s" % (self.rubMenu.index(self.mainLabel), self.mainLabel))
self.mainLabel = self.shortLine
mainRubCounter += 1
self.rubmap[self.mainLabel] = Menu(self.rubMenu, tearoff=0)
else:
# command trial: lambda: show(self.mainLabel,self.shortLine))
z = lambda: show(self.mainLabel,self.shortLine)
self.rubmap[self.mainLabel].add_command(label=self.shortLine,command=z)
print("Menu: rubmap[%s] Index: %s Label: %s" % (self.mainLabel,
self.rubmap[self.mainLabel].index(self.shortLine), self.shortLine))
# De last mainRubric, because because mainRubric telkens een achterloopt:
self.rubMenu.add_cascade(label=self.mainLabel,menu=self.rubmap[self.mainLabel])
print("Menu: rubMenu Index: %s Label: %s" % (self.rubMenu.index(self.mainLabel), self.mainLabel))
def doNothing(self):
pass
root = Tk()
root.title('Experiment with a rubric tree')
um = UniMenu(root)
root.mainloop()
Tkinter menu: trying to use item label in callback
Here is the script again, now hopefully with the original indentation:
Code:
#!/usr/bin/env python3
from tkinter import *
from tkinter.ttk import *
class UniMenu():
def __init__(self,root):
self.root = root
geometrie = "800x50+600+200"
self.root.geometry(geometrie)
self.rubric = Label(self.root,text='Rubric:')
self.rubric.pack(side=LEFT)
# make a menu-bar for one item only:
self.uMenu = Menu(self.root,type='menubar')
# fill het hele menu:
self.fillRubric()
# put the newly created rubMenu below uMenu:
self.uMenu.add_cascade(label='click',menu=self.rubMenu)
# display the completed uMenu
self.uMenu.pack(side=LEFT)
def fillRubric(self):
'''
Main-rubrics and sub-rubrics come from a file called 'afdeling',
which means rubric (!).
A part of it looks like this, an indented line is a sub-rubric:
Exact
Wiskunde_statistiek
Informatica
Natuurkunde
Astronomie
Geologie
Biologie
Mens
'''
def show(a,b):
print("Choice: %s: %s" % (a,b))
# maak een vooralsnog onzichtbaar sub-menu rubMenu:
rubricfile = "/kappa/data/afdeling"
self.rubMenu = Menu(self.uMenu,tearoff=0)
self.rubmap = {}
rf = open(rubricfile,'r')
mainRubCounter = 0
subRubCounter = 0
for fileLine in rf:
# a sub-rubric starts in the import-file with at least one space:
mainRubric = False if fileLine.startswith(" ") else True
self.shortLine = fileLine.strip()
if self.shortLine.startswith('#'): continue
if len(self.shortLine) < 1: continue
if mainRubric:
if mainRubCounter > 0:
# A main-rubric can only be cascaded when allof its subs are read,
# at least that is what I think how it works,
# so I made it a one-fase-off procedure.
self.rubMenu.add_cascade(label=self.mainLabel,menu=self.rubmap[self.mainLabel])
print("Menu: rubMenu Index: %s Label: %s" % (self.rubMenu.index(self.mainLabel), self.mainLabel))
self.mainLabel = self.shortLine
mainRubCounter += 1
self.rubmap[self.mainLabel] = Menu(self.rubMenu, tearoff=0)
else:
# command trial: lambda: show(self.mainLabel,self.shortLine))
z = lambda: show(self.mainLabel,self.shortLine)
self.rubmap[self.mainLabel].add_command(label=self.shortLine,command=z)
print("Menu: rubmap[%s] Index: %s Label: %s" % (self.mainLabel,
self.rubmap[self.mainLabel].index(self.shortLine), self.shortLine))
# De last mainRubric, because because mainRubric telkens een achterloopt:
self.rubMenu.add_cascade(label=self.mainLabel,menu=self.rubmap[self.mainLabel])
print("Menu: rubMenu Index: %s Label: %s" % (self.rubMenu.index(self.mainLabel), self.mainLabel))
def doNothing(self):
pass
root = Tk()
root.title('Experiment with a rubric tree')
um = UniMenu(root)
root.mainloop()
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.