Python Forum

Full Version: tkinter.Menu – How to make text-variable?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Problem context:
"tkinter" module has its own mutable alternatives for str, int, ... .
They are StringVar, IntVar, ... .
Widgets like Button, Label, ... do support them.
One can pass StringVar object to a widget via textvariable parameter.
Eg.
tkinter.Button(master= tkinter.Tk(), textvariable= tkinter.StringVar())
But, here tkinter.Menu stands out.
All its nested “widgets“ are loaded with .add_command(), .add_cascade(), ... methods.
Unfortunately, I don't know all their parameters, therefore, if someone posts a link to them they will have my gratitude.
Anyway, instead of having textvariable parameter, they possess label and [command or menu or sth].
Eg.
from tkinter import *
Win= Tk()
Menu1= Menu(master= Win)
Menu1.add_command(label= "My text.", command= print)
Menu1.add_cascade(label= "My another text.", menu= Menu(Menu1))
Win.configure(menu= Menu1)
Win.mainloop()

My purpose:
I'm making a multilingual object-orientet game. Which has a dictionary full of StringVar-s which change their value each time a user changes languages (I want to make a pull-down menu with languages). Widgets have textvariable-s connected with my dictionary. Dictionary draws values for StringVar-s from sqlite3 database, when language changes. Everything works for every widget, except for the Menu.

What I need:
I want my menubar to also be labelled with StringVar-s, so that I can keep a collection (dictionary) with references to these objects with their values. I would like to control the labels via my dictionary. #Update: Yes, I know I can rebuild the menu or change its properties on every dictionary shift. Eventually I may create such a method for my menubar, which would provide integrity if I cannot use StringVars.
Eg.
from tkinter import *
Win= Tk()
Mydict= {"command": StringVar(master= Win)}
Menu1= Menu(master= Win)
Menu1.add_command(label= Mydict["command"], command= print)
This doesn't work obviously.

Questions:
Does anyone know how to get StringVar-s into menu?
Does anyone know more parameters for tkinter.Menu's .add_...() methods.
#Update: I've got to know a Menubutton, which can hold StringVar(), but its children (content) are still problematic. Can I pack a normal widget into Menu? Eg. button, that would solve the problem. How?
You could build a new menu. That may be the easiest way since you can probably do this without changing any of the code, just pass in a different set of labels.

You can configure menu entries, just like buttons and labels and the like. This code changes a "Quit" label to "Exit" in the file_menu.
import tkinter as tk

root = tk.Tk()
menubar = tk.Menu(root)
file_menu = tk.Menu(menubar, tearoff=False)
file_menu.add_command(label='Print', command=lambda: print("Hello World"))
file_menu.add_command(label='Quit', command=quit)
menubar.add_cascade(label='File', menu=file_menu)
root.configure(menu=menubar)
file_menu.entryconfig(1, label='Exit')
root.mainloop()
The best documentation for tkinter may be to look at the underlying tk commands.

https://www.tcl.tk/man/tcl8.6/TkCmd/contents.htm

For example, the tk documentation has this to say about label.
Quote:Command-Line Name: -textvariable
Database Name: textVariable
Database Class: Variable
Specifies the name of a global variable. The value of the variable is a text string to be displayed inside the widget; if the variable value changes then the widget will automatically update itself to reflect the new value. The way in which the string is displayed in the widget depends on the particular widget and may be determined by other options, such as -anchor or -justify.

Looking under menu I only find 1 variable.
Quote:-variable value
Available only for checkbutton and radiobutton entries. Specifies the name of a global variable to set when the entry is selected. For checkbutton entries the variable is also set when the entry is deselected. For radiobutton entries, changing the variable causes the currently-selected entry to deselect itself.
For checkbutton entries, the default value of this option is taken from the -label option, and for radiobutton entries a single fixed value is used. It is recommended that you always set the -variable option when creating either a checkbutton or a radiobutton.
Thank you deanhystad. I've got to know more about those parameters.