error in using optionmenu widget in tkinter - python

I have written a code in python 2.7 which implements "optionmenu" widget. I am facing a problem that i have given six values in the tuple but when i select another option rather than "Gmail", i see only five values in the dropdown. can anyone tell me my mistake?
from Tkinter import *
import ttk
root = Tk()
choices = ("Gmail", "Outlook/Hotmail", "Yahoo", "Comcast", "AT&T", "Verizon")
dropdown_var = StringVar()
dropdown_var.set(choices[0]) # set default value
def data(*args):
value = dropdown_var.get()
print(value)
l = ttk.Label(root, text="Select your e-mail provider : ")
l.pack(side="left")
option = ttk.OptionMenu(root, dropdown_var, *choices)
option.pack(side="left", padx=10, pady=10)
b = ttk.Button(root, text="Click", command=data)
b.pack(side="bottom")
root.mainloop()

The issue you're facing is linked to the way you are defining the OptionMenu widget.
In fact, it's different from the tkinter OptionMenu because you set the default value inside the declaration. So when you unpack the values, the first index "Gmail" is taken as the default parameter for the widget, and the others are the options values.
(In addition, you don't need to set dropdown_var before)
Try this version :
choices = ("Gmail", "Outlook/Hotmail", "Yahoo", "Comcast", "AT&T", "Verizon")
dropdown_var = StringVar()
def data(*args):
value = dropdown_var.get()
print value # no bracket for python2
l = ttk.Label(root, text="Select your e-mail provider : ")
l.pack(side="left")
# the 3rd parameter is the default value
option = ttk.OptionMenu(root, dropdown_var, choices[0], *choices)
option.pack(side="left", padx=10, pady=10)

Related

dictionary which depends on 2nd dropbox selection with tkinter

from tkinter import *
import tkinter as tk
from tkinter import ttk
window=Tk()
window.title("RBEE Model")
window.geometry('500x450')
label7=Label(window,text='Select Pollutant:',fg='black',font=('Arial',14))
label7.grid(row=1,column=0,padx=5,pady=10)
Pollutant = ["PM2.5","PM10"]
crop_poll = [{'Rice':55,'Wheat':66,'Total Pulses':89,'Total Nine Oilseeds':69},
{'Total Pulses':89,'Total Nine Oilseeds':69}]
crop_poll_roll = ttk.Combobox(window, width=27, value=(Pollutant))
crop_poll_roll2 = ttk.Combobox(window, width=27, value=(crop_poll))
crop_poll_roll.grid(row=1, column=1, columnspan=2, padx=5, pady=10, sticky='w')
def callback2(eventObject2):
abcd = eventObject2.widget.get()
crop_p = crop_poll_roll.get()
index1=Pollutant.index(crop_p)
crop_poll_model.config(values=list(crop_poll[index1].keys()))
# crop_poll_model = ttk.Combobox(window, width=27,values=list(crop_poll[index1].keys()))
crop_poll_model = ttk.Combobox(window, width=27)
crop_poll_model.grid(row=2, column=1, columnspan=2, padx=5, pady=10, sticky='w')
crop_poll_model.bind('<Button-1>', callback2)
def emissions():
crop_p = crop_poll_roll.get()
index1=Pollutant.index(crop_p)
# crop_i=crop_poll_model.get()
# index2=crop_poll_model.index(crop_i)
# blank.delete(0, tk.END)
emiss= float((list(crop_poll[index1].values()))[index1])
# blank.insert(0, emiss)
emptylabel.config(text='Emissions:'+ str(emiss))
# blank = tk.Entry(window)
button1=Button(window,command=emissions,text='Calculate Emissions',fg='red',font=('Arial',14))
button1.grid(row=11,column=1)
emptylabel=Label(window,fg='green',font=('Arial',14))
emptylabel.grid(row=12,column=1,pady=10)
window.mainloop()
This code is working fine I just want to access the value of a dictionary within the list.enter image description here
I have attached the pic of the output here if I select the PM2.5 then I can choose another dropdown list.
so I select rice I want to display the square root of the value 55.
if I select wheat same thing I want to do with value 66 and so on.
You only have two values: "PM2.5"(index1=0) and "PM10"(index1=1).
When you execute this line of code,
emiss= float((list(crop_poll[index1].values()))[index1])
it means:
emiss= float((list(crop_poll[0].values()))[0])
or
emiss= float((list(crop_poll[1].values()))[1])
These are 'Rice': 55 in the first dictionary and 'Total Nine Oilseeds':69 in the second dictionary.
You can get the desired value from the dictionary like this:
import math
def emissions():
crop_p = crop_poll_roll.get()
index1=Pollutant.index(crop_p)
# Option 1
# string, dictionary key
selected_crop_value = crop_poll_model.get()
print(f"selected_crop_value: {selected_crop_value}")
# get value in dict by key
emiss= float(crop_poll[index1][selected_crop_value])
# Option 2
# integer, index in dropdown list
selected_crop_index = crop_poll_model.current()
print(f"selected_crop_index: {selected_crop_index}")
# get the value by the index of its key
# since version 3.6+, Python dictionaries are ordered
emiss= float(list(crop_poll[index1].values())[selected_crop_index])
emiss_sqrt = math.sqrt(emiss)
emptylabel.config(text='Emissions:'+ str(emiss_sqrt))
See also ttk.Combobox widget methods:
Python documentation
Combobox - Tcl/Tk version 8.5 (Newer versions of Python use version 8.6, but this link is helpful too).
You can also use the combobox event:
crop_poll_roll.bind('<<ComboboxSelected>>', callback)
For example, create a callback function for crop_poll_roll in which you change the state of crop_poll_model depending on whether you select "PM2.5" or "PM10".

Tkinter Accessing Variables from Different Function

Is there a way to access variables from different files if the widget is an Entry? I have tried using the command option but found that was exclusive to Buttons. I'm trying to separate my functions into different files to modulate.
ttk.Label(root, text="How many points do you want to input:").pack()
cell_content = StringVar()
cell_content.trace_add("write", my_tk.retrieve_cell_content)
cell_content_entry = Entry(root, width = 8, textvariable = cell_content)
cell_content_entry.pack()
tkinterFunctions.py
def retrieve_cell_col(self, *args):
global CELL_COL
temp = cell_col.get()
temp = temp.upper()
If I get it right, you want to get your text in Entry widget when it is writing. Not by pushing a Button. please check this if I am right:
from tkinter import *
def call(tex):
print(tex.get())
root = Tk()
tx = StringVar()
tx.trace("w", lambda name, index, mode, tex=tx: call(tex))
entry = Entry(root, textvariable=tx)
entry .pack()
root.mainloop()

Radiobutton not updating values when clicked in python with tkinter

This is my first attempt at a GUI. Right now I just want to be able to click a radiobutton and make it print the value I assigned to the button. However, var.get() isn't giving me anything. I tried it with IntVar (and had my values as 1 and 2 instead of "proton" and "electron") and var.get() would just give me 0. With StringVar it gives nothing (nothing prints when choosecharge is called by the radiobutton). I've tried reading stuff about radiobuttons and I wrote my code based on how I saw it done and it successfully creates the radiobuttons, but the whole point is to be able to use their values when clicked.
import tkinter as tk
def choosecharge():
print(var.get())
root = tk.Tk()
var = tk.StringVar()
proton = tk.Radiobutton(root, text = "proton", variable = var, value = "proton", command = choosecharge)
proton.pack( )
electron = tk.Radiobutton(root, text="electron", variable = var, value= "electron", command = choosecharge)
electron.pack( )
root.mainloop()
I have taken a slightly different approach to accomplish this task.
I created a dictionary of the integer radiobutton values as key and
the string that you wish to print as value.
Used a label widget to print the string in the GUI
import tkinter as tk
root = tk.Tk()
# define an IntVar
var = tk.IntVar()
# create a dictionary of key:value pair as radiobutton_value: str_name_to_print
values = {1: "proton", 2: "electron"}
# instantiate a label widget
lbl = tk.Label(root)
def choosecharge():
# update the label widgets using the dictionary
lbl.config(text=values[var.get()])
proton = tk.Radiobutton(root, text="proton", variable=var, value=1, command=choosecharge)
proton.pack(anchor=tk.W)
electron = tk.Radiobutton(root, text="electron", variable=var, value=2, command=choosecharge)
electron.pack(anchor=tk.W)
# pack the label widget below the two radiobuttons
lbl.pack()
root.mainloop()
Screenshot
I have commented the lines in the code for better understanding. I hope this solution helps you.

Adding Checkbutton Options from database with Tkinter Menubutton

I have categories saved in a database on table Geo_Cat. I know my geo_list is getting populated correctly, because I was able to make an OptionMenu earlier. I also printed the list and it worked. So the query is good. However, I need to be able to select more than one option at a time and need to use a MenuButton instead. The options that I need are none and the categories in the table. I've been able to add the "None" checkbutton, but I haven't been able to add the geo_list. Below is a code excerpt:
from Tkinter import *
root = Tk()
location_frame = Frame(root)
location_frame.grid(column=0, row=0, sticky=(N, W, E, S))
location_frame.columnconfigure(0, weight=1)
location_frame.rowconfigure(0, weight=1)
location_frame.pack(pady=25, padx=50)
geo_list= ["geo1","geo2","geo3","geo4"]
amb = Menubutton(location_frame,text="Geo Category", relief=RAISED)
amb.grid(sticky="ew", row=1,column=0)
amb.menu = Menu(amb,tearoff=0)
amb['menu'] = amb.menu
Item0 = IntVar()
amb.menu.add_checkbutton(label="None", variable=Item0)
location_vars = {}
for category in geo_list:
location_vars["Item{0}".format(category)] = IntVar()
amb.menu.add_checkbutton(label=geo_list[category])
amb.pack()
root.mainloop()
I also tried this:
location_vars["Item{0}".format(category)] = IntVar()
amb.menu.add_checkbutton(label=geo_list[category],
variable=location_vars["Item{0}".format(category)])
How can I add my geo_list to the checkbuttons? Any advice would be greatly appreciated.
If you want the items in the geo_list for menu labels, why not just set them; you are already looping over them:
amb.menu.add_checkbutton(label=category)
Also, don't pack amb at the very end; you have already gridded it earlier.
I'm adding an example of how to trace changes associated with each menu item. I have changed the code slightly but I think you will have no problem to get the general idea.
I'm using a BooleanVar() instead of an IntVar(), then each var is saved in location_vars with the key "Item{0}".format(category). Finally I'm setting up a trace for changes in each menu item to to a callback function which will inspect the selections.
Is this what you are after?
from tkinter import *
root = Tk()
amb = Menubutton(root, text="Geo Category", relief=RAISED)
amb.pack(padx=50, pady=25)
amb.menu = Menu(amb, tearoff=0)
amb['menu'] = amb.menu
def callback(*args):
# Callvack function is called when menu items are changed
for key, value in location_vars.items():
print(key, value.get())
print() # To make the printout more readable
geo_list= ["None","geo1","geo2","geo3","geo4"]
location_vars = {}
for category in geo_list:
location_vars["Item{0}".format(category)] = BooleanVar()
# Set "variable" for every menu item
amb.menu.add_checkbutton(label=category,
variable=location_vars["Item{0}".format(category)])
# Trace changes in the variables
location_vars["Item{0}".format(category)].trace("w", callback)
root.mainloop()

Tkinter: AttributeError using .get()

I am trying to retrieve a variable from a Tkinter Wiget but I am running into this error message:
AttributeError: 'int' object has no attribute 'get'
Here is the widget code
JobNEntry = tkinter.Entry(menu, textvariable = tk.IntVar(JobNo))
JobNEntry.grid(row=2, column=2, sticky="W")
Here is the call code
JobNo=JobNo.get()
Also I need to know if the variable JobNo is writable to a file.
Thanks in advance
The get() method is part of several widgets in tkinter and is not something that you can use on a normal int or str object. get() must be called on a variable that is a widget object that has a get() method, like Entry.
Its likely you need to do:
JobNEntry.get()
This will get the current value from the entry field as a string.
If you want to save the value of that string you can. There are several tutorials on Stack Overflow and the web that go into detail on how to save a string to a file.
Looking at the code you have shown us, it's possible you have not created your IntVar() correctly.
Make sure you define the IntVar() first then set that variable as the textvariable.
Something like this:
JobNo = tk.IntVar()
JobNEntry = tkinter.Entry(menu, textvariable = JobNo)
The attribute error might be because you havnt already initialized the variable JobNo as an 'IntVar'
This is the code i have come up with :
import tkinter as tkinter
menu=tkinter.Tk()
JobNo=tkinter.IntVar()
JobNEntry = tkinter.Entry(menu, textvariable = JobNo)
JobNEntry.grid(row=2, column=2, sticky="W")
JobNo=JobNo.get()
menu.mainloop()
You need to initialize JobNo as an Integer Variable using IntVar()
JobNo=tkinter.IntVar()
And then use it in the Entrybox.
If you had some string to add to the entry, you should initialise as StringVar()
Also when you initialize, make sure you do it after opening the Tk window.(here i put it after menu=tkinter.Tk())
Something like this:
from tkinter import *
from tkinter import ttk
def save_job_no():
try:
n = job_no.get()
except TclError:
status.config(text = "This is not an integer")
return False
status.config(text="")
f = open("my_file.txt", "w")
f.write(str(n))
return True
root = Tk()
job_no = IntVar()
entry = ttk.Entry(root, width = 30, textvariable = job_no)
entry.grid()
label = ttk.Label(root, textvariable = job_no)
label.grid()
status = ttk.Label(root)
status.grid()
button = ttk.Button(root, text = "Write to a file", command = save_job_no)
button.grid()
root.mainloop()

Categories