I have a Tkinter option menu like this:
import Tkinter as tk
choices = [1,2,3]
GUI = tk.Tk()
var2set = tk.IntVar(GUI)
tk.OptionMenu(GUI, var2set, *choices).grid(column=0, row=0)
GUI.mainloop()
Is it possible to change the labels of the choices [1,2,3] to strings like "title 1", "title 2", "title 3" WITHOUT a modification of the variable choices? It is important, that each option in the option menu delivers the chosen integer value from the choices-list.
If I fully understood what you are asking for then
Yes I think dictionary can be used here but as you said you want the contents of choices not to be disturbed then you can find this useful..
import Tkinter as tk
def select():
title=var.get()
print "selected string :"+title
print "corresponing integer value :"+str(choices[Dic[title]])
choices = [1,2,3]
Dic={'title 1':0,'title 2':1,'title 3':2}
GUI = tk.Tk()
var = tk.StringVar(GUI)
var.set('title 1')
op=tk.OptionMenu(GUI, var, *Dic.keys())
op.pack(side='left',padx=20,pady=10)
bt=tk.Button(GUI,text='check value',command=select)
bt.pack(side='left',padx=20,pady=10)
GUI.mainloop()
The indexing is quite messy but may be its exactly the way you want it
Also you can make dictionary of any length(same as of choices) using trivial loops that's too obvious :)
Related
So, I want the user to be able to use my program in English. They should be able to switch to their language via a dropdown-menu. My program has only four pages and a few labels on each, translating them with a toolkit would be unnecessary.
This is, what I got this so far:
# Language Settings
def display_selected(choice):
choice = variable.get()
if choice == "Deutsch":
languagelabel.config(text=str('Sprache:'))
Page1(self).label_search.config(text=str('Suche'))
else:
languagelabel.config(text=str('Language:'))
Page1(self).label_search.config(text=str('search'))
# Dropdown Menu for Languages
languages = ['Deutsch', 'English']
variable = StringVar()
variable.set(languages[0])
dropdown = OptionMenu(self, variable, *languages, command=display_selected)
The languagelabel in the same class changes, but the search_label in the class 'Page1' doesn't. Nothing happens, am I missing something?
I'm a bit of a novice, so any guidance and/or other solutions would be appreciated!
One option I can think of would be using StringVar()s to store the labels that need translation for each language option, and the assigning those variables to each label's textvariable parameter
# EXAMPLE
lang_label_var = tk.StringVar()
label_search = tk.Label(
textvariable = lang_label_var
# whatever other attributes
)
search_label_var = tk.StringVar()
languagelabel = tk.Label(
textvariable = search_label_var
# whatever other attributes
)
You should be able to set() these variables to whichever word is appropriate for English or German with similar logic following choice = variable.get(). The label text for each item should update automatically when the variable assigned to textvariable is set.
if choice == 'Deutsch':
lang_label_var.set('Sprache:')
search_label_var.set('Suche')
elif choice == 'English':
lang_label_var.set('Language:')
search_label_var.set('Search')
Here I have a basic OptionsMenu and a list with lists inside of it for my Menu options. What I need to do is display only the first item of the sub lists in the options menu but when that item is selected to pass the 2nd item in the sub list to a function.
Currently I can display all of the sub list and pass all of the sub list to a function. The main problem I am having is trying to display JUST the first item "ID 1" or "ID 2" in the drop down menu.
import tkinter as tk
root = tk.Tk()
def print_data(x):
print(x[1])
example_list = [["ID 1", "Some data to pass later"], ["ID 2", "Some other data to pass later"]]
tkvar = tk.StringVar()
tkvar.set('Select ID')
sellection_menu = tk.OptionMenu(root, tkvar, *example_list, command=print_data)
sellection_menu.config(width=10, anchor='w')
sellection_menu.pack()
root.mainloop()
This is what I get:
What I want:
As you can see in the 2nd image only the "ID 1" is displayed in the menu and the data for that ID is printed to console.
I cannot find any documentation or post abut this issue so it may not be possible.
The only way I can think about is this
import tkinter as tk
root = tk.Tk()
do a for loop that takes the first index and that is the ID
sellection_menu = tk.OptionMenu(root, tkvar,
*[ID[0] for ID in example_list],
command=print_data)
search for the given index but this is slow and not so good if you are using a lot of data
def print_data(x):
for l in example_list:
if x == l[0]:
print(l[1])
break
example_list = [["ID 1", "Some data to pass later"],
["ID 2", "Some other data to pass later"]]`
In an attempt to create a Python Entry widget with limited input(3 or 4 characters), I found this
Knowing nothing yet about validation, my question is this: can the 'subclass' for max length in that tutorial be used as its own class, referencing the entry widget as its parent instead of 'ValidatingEntry', or is all the legwork above it (validating) necessary? Is there any shorter way to accomplish this?
Then I saw this question and its answer:
Considering doing something like that. Then I discovered the builtin 'setattr' function. Is it possible to apply this to a new instance of the class 'Entry' and use it to limit characters?
I should clarify- I'm trying to apply this limit to 3 entry widgets- two with a 3 character limit and one with a 4 character limit (a phone number)
Thanks.
Regarding your stated concern of length validation in an Entry widget. An example of input length validation.
# further reference
# http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/entry-validation.html
import tkinter as tk
root = tk.Tk()
# write the validation command
def _phone_validation(text_size_if_change_allowed):
if len(text_size_if_change_allowed)<4:
return True
return False
# register a validation command
valid_phone_number = root.register(_phone_validation)
# reference the validation command
entry = tk.Entry(validate='all',
validatecommand=(valid_phone_number,'%P' ))
entry.pack()
root.mainloop()
suggestion in response to comment on focus switching between entry widgets, change validate 'all'-> 'key', and use focus_set()
import tkinter as tk
root = tk.Tk()
# write the validation command
def _phone_validation(text_size_if_change_allowed):
if len(text_size_if_change_allowed) == 3:
entry2.focus_set()
if len(text_size_if_change_allowed)<4:
return True
return False
# register a validation command
valid_phone_number = root.register(_phone_validation)
# reference the validation command
entry = tk.Entry(validate='key',
validatecommand=(valid_phone_number,'%P' ))
entry2 = tk.Entry()
entry.pack()
entry2.pack()
root.mainloop()
--UPDATE:
I changed
variable=self.optionVal.get()
to
variable=self.optionVal
But nothing changed.Also I wonder why it automatically call self.selected while compiling?
----Original:
I'm trying to get familiar with radiobutton, but I don't think I understand how radiobutton works. Here's a brief code for demonstration:
self.optionVal = StringVar()
for text, val in OPTIONS:
print(text,val)
radioButton = Radiobutton(self,
text=text,
value=val,
variable=self.optionVal.get(),
command = self.selected())
radioButton.pack(anchor=W)
def selected(self):
print("this option is :"+self.optionVal.get())
In my opinion this should work like once I choose certain button, and it prints out "this option is *the value*", however now what it does is once compiled, it prints out everything, and the self.optionVal.get() is blankspace, as if value wasn't set to that variable.
I wonder what happens to my code,
Many thanks in advance.
AHA! I beleive I've figured it out. I had the exact same issue. make sure you are assigning a master to the IntVar like self.rbv=tk.IntVar(master) #or 'root' or whatever you are using):
import Tkinter as tk
import ttk
class My_GUI:
def __init__(self,master):
self.master=master
master.title("TestRadio")
self.rbv=tk.IntVar(master)#<--- HERE! notice I specify 'master'
self.rb1=tk.Radiobutton(master,text="Radio1",variable=self.rbv,value=0,indicatoron=False,command=self.onRadioChange)
self.rb1.pack(side='left')
self.rb2=tk.Radiobutton(master,text="Radio2",variable=self.rbv,value=1,indicatoron=False,command=self.onRadioChange)
self.rb2.pack(side='left')
self.rb3=tk.Radiobutton(master,text="Radio3",variable=self.rbv,value=2,indicatoron=False,command=self.onRadioChange)
self.rb3.pack(side='left')
def onRadioChange(self,event=None):
print self.rbv.get()
root=tk.Tk()
gui=My_GUI(root)
root.mainloop()
try running that, click the different buttons (they are radiobuttons but with indicatoron=False) and you will see it prints correctly changed values!
You're very close. Just take out the .get() from self.optionVal.get(). The Radiobutton constructor is expecting a traced variable, you're giving it the result of evaluating that variable instead.
You need to:
Remove the .get() from the variable=self.optionVal argument in the constructor the button. You want to pass the variable, not the evaluated value of the variable; and
Remove the parenthesis from command=self.selected() and use command=self.selected instead. The parenthesis says "call this function now and use the return value as the callback". Instead, you want to use the function itself as the callback. To better understand this, you need to study closures: a function can return a function (and, if that was the case, that would be used as your callback).
EDIT: A quick reminder, also: Python is not compiled, but interpreted. Your callback is being called while the script is being interpreted.
def view(interface):
choice = interface.v.get()
if choice == 0:
output = "0"
elif choice == 1:
output = "1"
elif choice == 2:
output = "2"
elif choice == 3:
output = "3"
else:
output = "Invalid selection"
return tk.messagebox.showinfo('PythonGuides', f'You Selected {output}.')
class Start:
def __init__(self):
self.root = tk.Tk()
self.root.geometry('500x500')
self.root.resizable(False, False)
self.root.title('find out the degree of severity')
self.v = tk.IntVar()
dolori_ossa = {"nessun dolore": 0,
"dolori articolari": 1,
"frattura composta": 2,
"frattura scomposta": 3}
for (txt, val) in dolori_ossa.items():
tk.Radiobutton(self.root,
text=txt,
variable=self.v,
value=val,
command=lambda:view(self)
).pack()
I want to get a list of all options from an OptionMenu widget in tkinter like so:
import tkinter
root = tkinter.Tk()
var = tkinter.StringVar(root)
var.set('OptionMenu')
optionMenu = tkinter.OptionMenu(root, var, 'foo1', 'foo2')
optionMenu.pack()
listOfAllOptions = optionMenu.getOptions()
# listOfAllOptions == ['foo1', 'foo2']
root.mainloop()
Is there a function that achieve that ?
If not what is the workaround?
You can get the menu associated with the optionmenu (eg: optionMenu["menu"]), and with that you can use menu methods to get the items. It takes several lines of code. But honestly, the easiest thing to do is put the values in a list that you attach to the widget (eg: optionMenu.items = the_list_of_values)
If you want to pull the data from the actual widget, you would do something like this:
menu = optionMenu["menu"]
last = menu.index("end")
items = []
for index in range(last+1):
items.append(menu.entrycget(index, "label"))
print "items:", items