In Python's Tkinter OptionMenu, is it possible to have a list of display options, but on selection, it sets a value to be some other value?
Suppose I had
variable = tk.IntVar(master)
OptionMenu(master, variable, 1, 2).pack()
options = {1:"one",2:"two"}
and wanted to display the values but assign the key to variable. Is this even possible? Or is there a way to link the OptionMenu to call a function on selection to convert it?
My real problem is more involved than the example, so the issue is just evaluating complex strings and I'd like to avoid using a StringVar.
Thanks
You already have it. Use the dictionary to map your displayed options to the actual values you want.
EG:
import Tkinter as tk
master = tk.Tk()
variable = tk.StringVar(master)
options = {"one": 1, "two": 2}
tk.OptionMenu(master, variable, *options.keys()).pack()
...
wanted = options[variable.get()]
Please note the splat operator, *, used to unpack the keys as a comma separated list of arguments to OptionMenu. Later when you want the option's "value" use variable.get() as the "key" in the dictionary.
Related
Referencing to an old thread :
Dynamically Add Values To Tkinter Menubutton (using list)
when it comes to menubuton in tkinter, i'm trying to use the same code provided in the answer to dynamically add values to menu in tkinter, given the amount of items i want in my menu.
This can be done by using a list and a dictionary as follows:
menubutton = Menubutton(root, text = "Select")
menubutton.menu = Menu(menubutton)
menubutton["menu"]= menubutton.menu
# main list holding menu values
list1 = ['a', 'b', 'c']
# Creating a dictionary
dict2 = {}
# Add key-value pairs to dictionary
for i in range(0, len(list1)):
temp = {'var'+str(i): list1[i]}
dict2.update(temp)
# Finally adding values to the actual Menubutton
for i in range(0, len(list1)):
menubutton.menu.add_checkbutton(label = dict2['var'+str(i)], variable = list(dict2.keys())[i])
menubutton.pack()
My question with this now is, how do I control the variables (i.e if i want to do a .get() or .set(0) or similar), how do i reference to it considering that my variable is being generated within the for loop as it is what is adding the actual items to the menu based in the contents of the list?
and on the same note, how do I check (just for sake of simplicity, how do I print the selected variables) (and values, i dont see for example onvalue inside the checkbutton in this case, i'm assuming I'd have to pre-assign a value to each specific item of the list, and then have this value be generated based on the index of each item being created during the for loop
Thanks in advance,
If you have any sugestions on a different widget that might be more useful and convenient for this purpose (I wanted a multiple selection checkbox but thats doesnt seem to be a thing in tkinter, so menubutton is the thing I came the closest to that outcome).
Nonetheless I'd still appreciate an explanation to the above, always good to learn...
I get the user entry as a StringVar from an Entry box but would like to convert it to uppercase.
I then use the variable in another routine. I have been unable to find the syntax to simply convert 'c6h12' to 'C6H12' when its in a StringVar.
Any help appreciated.
The following snippet does the trick, simply using the StringVar get() method to get the old value, and set() method to update the value after calling upper()
from tkinter import *
root = Tk()
sv = StringVar(value="c6h12")
sv.set(sv.get().upper())
root.mainloop()
so i have to do a snake using tkinter and i'm asked to either store the widget in a dictionary or a list.
the code i was given to work with is :
tk_frame['score'] = Frame(fen)
tk_frame['score'].pack()
tk_frame['jeu']= Frame(fen)
tk_frame['jeu'].pack()
tk_frame['gestion']= Frame(fen)
tk_frame['gestion'].pack()
The computer asked what "tk_frame was" so i created a dictionary :
tk_frame = {'score' : Frame(fen), 'jeu' : Frame(fen), 'gestion' : Frame(fen)}
but then i have to call these keys as arguments in other functions and i don't know how i can do this.
lets say you want call 'score', do:
tk_frame['score'].pack()
assuming you want to pack these widgets.
The same principle applies for the other keys
I imagine this is a fairly basic Tkinter question - but I am a noob and I haven't seen this answer after some searching.
I would like to be able to check what the attribute of my canvas is in Tkinter.
So,
canvas = tk.Canvas(root, 200,200, bg="blue")
canvas2 = tk.Canvas(root, 200,200, bg="red")
canvases = [canvas, canvas2]
What I am looking for is something to check what the attribute is of the canvas. For example -
for canvas in canvases:
if canvas.get_color() == "red": # IS THERE SOMETHING LIKE get_color... or get_attr(bg)?
print("HECK YA")
else:
print("I'm feeling blue")
Thanks for the help!
you can call canvas.config('attribute') to obtain the value of a given attribute.
For instance canvas.config('bg') returns the value of the background.
Calling canvas.config() without arguments will return a dictionary of the current configuration
Universal Widget methods that relate to configuration of options:
The methods are defined on all widgets. In the descriptions, w can be any widget of any type.
w.cget(option): Returns the current value of option as a string. You can also get the value of an option for widget w as w[option].
w.config(option=value, ...)
Same as .configure().
w.configure(option=value, ...)
Set the values of one or more options. For the options whose names are Python reserved words (class, from, in), use a trailing underbar: 'class_', 'from_', 'in_'.
You can also set the value of an option for widget w with the statement w[option] = value
If you call the .config() method on a widget with no arguments, you'll get a dictionary of all the widget's current options. The keys are the option names (including aliases like bd for borderwidth). The value for each key is:
for most entries, a five-tuple: (option name, option database key, option database class, default value, current value); or,
for alias names (like 'fg'), a two-tuple: (alias name, equivalent standard name).
I have made a variable called 'localtime2' within my def in the code and then have a label which says 'textvariable=localtime2.' the problem is that it does not display the information about the variable.
localtime2 = time.asctime(time.localtime(time.time()))
tk.Label(roots, font=('arial', 16, 'bold'), textvariable=localtime2, bd=16, anchor="w").grid(row=2, column=0)
This is all I have in the code about this variable and it is not coming up with any error in the terminal. It just doesnt show at all.
Edit: The solution to the original post was using text=localtime2.get() instead of textvariable=localtime2 in the label widget (for some strange reason). However, my original answer is still correct as tkinter variables should be used and so I will keep it up.
You must use tkinter variables in tkinter widgets and not normal python variables. Tkinter variables are slightly different to normal variables and must first be defined as a specific data type. For example, a variable which contains a string must be first created like so:
string_variable = tk.StringVar()
likewise a boolean would be created like so:
boolean_variable = tk.BooleanVar()
Read here for more information on tkinter variables.
These variables are in fact classes so in order to set them use must call the .set() method. Therefore to set a tkinter String variable to "a string" you would use the following code:
string_variable = tk.StringVar() # Create the variable
string_variable.set("a string") # Set the value of the variable
Thus to fix your code you need to make localtime2 a tkinter variable and set it to the time using the .set() method.
Example:
localtime2 = tk.StringVar() # Create the localtime2 string variable
localtime2.set(time.asctime(time.localtime(time.time()))) # Set the variable
tk.Label(roots, font=('arial', 16, 'bold'), textvariable=localtime2, bd=16, anchor="w").grid(row=2, column=0)
Whenever there is a change in a tkinter variable, the update is automatically reflected everywhere. Because of this property you cannot use a normal python variable here.
Try using StringVar() and then setting the variable content using set()