Radiobutton not updating values when clicked in python with tkinter - python

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.

Related

How to display the label ( text) value dynamically based on combo box selection value ( List box) in Tkinter?

I am new to tkinter application. The below code is working fine. Please help how to implement mentioned features.
The dynamic value should be displayed above clear button or below the combo box ( Used pack is bottom )- Now working
Clear the label value on combo box selection.
import tkinter as tk
from tkinter import ttk
from tkinter import *
from datetime import datetime
# root window
root = tk.Tk()
root.geometry("500x350")
root.resizable(False, False)
root.title('Test')
# Log Generator in frame
Generator = tk.Frame(root)
Generator.pack(padx=10, pady=10, fill='x', expand=True)
def clear():
combo.set('')
# Function to print the index of selected option
# in Combobox
def get_log_file_name(*arg):
date_Value = datetime.now().strftime("%Y_%m_%d_%I%M%S")
output_file_name_value = "Log_"+date_Value
if var.get() == "apple":
Label(Generator, text="The value at index: "+output_file_name_value+".txt", font=('Helvetica 12')).pack()
else:
Label(Generator, text="The value at index: "+output_file_name_value+".html", font=('Helvetica 12')).pack()
# Define Tuple of months
months = ('apple','banana')
# Create a Combobox widget
label = ttk.Label(Generator, text="Selection_Option:",font=('Helvetica', 10, 'bold'))
label.pack(fill='x', expand=True)
var = StringVar()
combo = ttk.Combobox(Generator, textvariable=var)
combo['values'] = months
combo['state'] = 'readonly'
combo.pack(padx=5, pady=5)
# Set the tracing for the given variable
var.trace('w', get_log_file_name)
# Create a button to clear the selected combobox
# text value
button = Button(Generator, text="Clear", command=clear)
button.pack(side=left)
# Make infinite loop for displaying app on
# the screen
Generator.mainloop()
Clear the label value on combo box selection.
You need to capture the ComboboxSelect event to do that and the function to execute if captured
the function should be like this
What you want to do here, is to capture the combobox event, and then, do the label configuration when capturing it,
Below is the code to do the thing. and you can add code there.
def comboboxEventCapture(e=None):
label.configure(text='')
# Your code after resetting variables!
Here's the event capturing part
combo.bind("<<ComboboxSelect>>", comboboxEventCapture)
You can name the function whatever you want though.
Note that the arguement e is needed because if the event is captured, the event itself is passed as a parameter into the function, that is of no use here (unless you are going to do something with it, then use e.objname)
The dynamic value should be displayed above clear button
The second label could be outside of get_log_file_name() function.
And also configure inside function. So you don't do duplicate Label widget, naming Label2
Also the pack() must be split to prevent an error.
To clear Label2 use .configure(text='')
We will be using ttk. So don't do this from tkinter import *
Code:
import tkinter as tk
from tkinter import ttk
from datetime import datetime
root = tk.Tk()
root.geometry("500x350")
root.resizable(False, False)
root.title('Test')
Generator = tk.Frame(root)
Generator.pack(padx=10, pady=10, fill='x', expand=True)
def clear():
label2.configure(text='')
def get_log_file_name(*arg):
date_Value = datetime.now().strftime("%Y_%m_%d_%I%M%S")
output_file_name_value = "Log_"+date_Value
if var.get() == "apple":
label2.configure(text="The value at index: "+output_file_name_value+".txt", font=('Helvetica 12'))
else:
label2.configure(text="The value at index: "+output_file_name_value+".html", font=('Helvetica 12'))
# Define Tuple of months
months = ('apple','banana')
# Create a Combobox widget
label2 = ttk.Label(Generator)
label2.pack()
label = ttk.Label(Generator, text="Selection_Option:",font=('Helvetica', 10, 'bold'))
label.pack(fill='x', expand=True)
var = tk.StringVar()
combo = ttk.Combobox(Generator, textvariable=var)
combo['values'] = months
combo['state'] = 'readonly'
combo.pack(padx=5, pady=5)
# Set the tracing for the given variable
var.trace('w', get_log_file_name)
# Create a button to clear the selected combobox
# text value
button = ttk.Button(Generator, text="Clear", command=clear)
button.pack(side='left')
# Make infinite loop for displaying app on
# the screen
Generator.mainloop()
Screenshot for apple:
Screenshot for banana:
Screenshot to clear Label2:

Calling function using label Tkinter python

Working on a unit converter using Tkinter python, I want to change all other units according to the input unit but can't able to call that function which later configures other labels of units.
mainEntry = Entry(width=15,font="arial 15 bold")
mainEntry.grid(row=0,column=0)
This Entry will get the input from user and other labels get update according to input without clicking any button.
Set a variable to Entry widget and use the trace method to detect any changes in the text and update labels accordingly.
Here is an example:
from tkinter import *
def change_lbl(*args):
lbl['text']=var.get()
root = Tk()
var = StringVar()
var.trace('w', change_lbl)
lbl = Label(root, text='Hello')
lbl.pack()
entry = Entry(root, textvariable=var)
entry.pack()
root.mainloop()

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()

error in using optionmenu widget in tkinter

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)

Dynamically generated list of checkboxes in Tkinter only returns 0s

I am writing a small gui with Tkinter in python 2,7. At some point I call a function that creates a popup window that is populated by a number of checkboxes, the number of checkboxes is defined by the attributes variable.
def attribute_select(attributes):
popup = tk.Tk()
popup.wm_title("Attribute selection")
label = ttk.Label(popup, text="Please select which of the following \n attributes will undergo k-anonymity.",
font=NORMAL_FONT)
label.pack(side="top", fill="x", pady=10)
def read_status(key):
var_obj = var.get(key)
print "key is:", key
print "var_obj.get() is:", var_obj.get()
def leave_mini():
popup.destroy()
var = dict()
count = 1
for child in range(attributes):
var[child] = tk.IntVar()
chk = tk.Checkbutton(popup, text='Attribute: '+str(count), variable=var[child], justify="left", onvalue=1,
offvalue=0, command=lambda key=child: read_status(key))
count += 1
chk.pack()
print var
exit_button = ttk.Button(popup, text="OK", command=leave_mini)
exit_button.pack()
popup.mainloop()
Everything runs just fine but when I try to check one of the boxes the variable value doesn't change the printout every time is: [ key is: 0 var_obj.get() is: 0 ] or [ key is: 5 var_obj.get() is: 0 ]. So the key is proper for every box but the variable doesn't change. I'm sure it's a simple fix I just can't see it... any ideas?
You must not create more than one instance of Tk. By creating an instance in attribute_select I must assume you've create the "real" root window somewhere else. One of the side effects of creating more than one instance of Tk is that your tkinter variables (IntVar, etc) don't behave the way you expect them to.
If you need popup windows, create instances of Toplevel.

Categories