Python function returns PY_VAR1 unexpectedly - python

I am expecting my button function to print a number (minutes_selected) based on the current value of the Spinner UI element, but the variable is always PY_VAR1:
from tkinter import *
from tkinter import ttk
def get_minutes():
global minutes_selected
minutes_selected.get()
print(mintes_selected)
root = Tk()
minutes_selected = StringVar()
minutes_spinbox = Spinbox(root, from_ = 1, to = 1440, textvariable = minutes_selected).pack()
Is there some basic misunderstanding with regards to how variables can be access from within a function?

You need to use the get method to get the value of the variable.
Change this:
print(mintes_selected)
To this:
print(minutes_selected.get())

Related

Retrieve the input value of an entry - Tkinter

I am just getting started with making basic GUI's with Tkinter.
I have previously created a script in python and I wanted to create a basic GUI for it.
My issue is I need to get the value of an entry widget to use as a parameter value, but methods online are not working for me.
This is what I am trying.
def retrieve_input():
eq_input = eq_textbox.get()
return eq_input
equation_input = retrieve_input()
eq_textbox is my entry and equation_input will be the parameter value.
from tkinter import *
window = Tk()
entry_var = StringVar() #initializing a string var
eq_textbox = Entry(window, textvariable = entry_var) #add textvariabe to store value
def retrieve_input():
eq_input = entry_var.get() #see here
return eq_input
equation_input = retrieve_input()
window.mainloop()
You need a varible to store that value... see above

Accessing a Tkinter widget directly by its name when held in a list

I have a complicated GUI interface and to keep the code in my __init__ method as concise as possible I like to create widgets of the same type in a list. My question is how can I access a particular widget by name if it is held in a list without iterating through the list and comparing the name.
Here is some example code.
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
def change():
for l in labs:
if l._name == s.get():
l.configure(text="Changed")
return
labs = []
for x in range(5):
labs.append(tk.Label(root, text="Original", name=str(x)))
labs[x].pack()
b = ttk.Button(root, text="Change", command=change)
s = tk.Spinbox(width=2, values=[0,1,2,3,4])
s.pack()
b.pack()
root.mainloop()
In the change() function I want to configure the text without iterating through the entire list. Is this even possible?
Okay, perhaps this is the correct way:
def change():
root.children[str(s.get())].configure(text="Changed")

Tkinter: is there a way to check checkboxes by default?

I have this piece of code that will create a simple checkbox :
from Tkinter import *
CheckVar = IntVar()
self.checkbutton = Checkbutton(self.root, text = "Test", variable = CheckVar)
However this checkbox in unchecked by default and I'm searching for a way to check it.
So far I have tried to insert
CheckVar.set(1)
right after CheckVar but it didn't work.
Thanks for your help
Edit : here is my full piece of code. When I run it, the box is still unchecked
from Tkinter import *
class App():
def __init__(self, root):
self.root = root
CheckVar = IntVar()
CheckVar.set(1)
self.checkbutton = Checkbutton(self.root, text = "Test", variable = CheckVar)
self.checkbutton.grid(row=0, column=0,)
root = Tk()
app = App(root)
root.mainloop()
Your CheckVar is a local variable. It's getting garbage collected. Save it as an object attribute. Also, you can create the variable and initialize it all in one step:
self.CheckVar = IntVar(value=1)
self.checkbutton = Checkbutton(..., variable = self.CheckVar)
You can also use the select function of the checkbutton:
self.checkbutton.select()
I think the function you are looking for is .select()
This function selects the checkbutton (as can be assumed from the function name)
Try calling this function after your widget is defined:
from Tkinter import *
CheckVar = IntVar()
self.checkbutton = Checkbutton(self.root, text = "Test", variable = CheckVar)
self.checkbutton.select()
By calling the function right after the widget is created, it looks as though it's selected by default.
Just adding onto GunnerStone's answer - Because I was looking for something where I can reset my values/checkboxes.
If you'd like to de-select the checkbox value for whatever reason, use deselect():
from Tkinter import *
CheckVar = IntVar()
self.checkbutton = Checkbutton(self.root, text = "Test", variable = CheckVar)
self.checkbutton.deselect()
or use toggle to switch between the two:
self.checkbutton.toggle()
I was using ttk and the only thing that worked was
self.checkbutton.state(["selected"])
Check the state via
"selected" in self.checkbutton.state()
var4 = IntVar(value=1)
Checkbutton(root, text="New", variable=var4, bg="light green").grid(row=12, column=0)
This will check all the check boxs.

How do I link python tkinter widgets created in a for loop?

I want to create Button and Entry(state=disabled) widgets with a for loop. The number of widgets to be created will be a runtime argument. What I want is that every time I click the button, the corresponding entry will become enabled(state="normal"). The problem in my code is that any button I click, it only affects the last entry widget. Is there anyway to fix this.? Here is my code:
from tkinter import *
class practice:
def __init__(self,root):
for w in range(5):
button=Button(root,text="submit",
command=lambda:self.enabling(entry1))
button.grid(row=w,column=0)
entry1=Entry(root, state="disabled")
entry1.grid(row=w,column=1)
def enabling(self,entryy):
entryy.config(state="normal")
root = Tk()
a = practice(root)
root.mainloop()
Few issues in your code -
You should keep the buttons and entries you are creating and save them in an instance variable, most probably it would be good to store them in a list , then w would be the index for each button/entry in the list.
When you do lambda: something(some_param) - the function value of some_param() is not substituted, till when the function is actually called, and at that time, it is working on the latest value for entry1 , hence the issue. You should not depend on that and rather you should use functools.partial() and send in the index of Button/Entry to enable.
Example -
from tkinter import *
import functools
class practice:
def __init__(self,root):
self.button_list = []
self.entry_list = []
for w in range(5):
button = Button(root,text="submit",command=functools.partial(self.enabling, idx=w))
button.grid(row=w,column=0)
self.button_list.append(button)
entry1=Entry(root, state="disabled")
entry1.grid(row=w,column=1)
self.entry_list.append(entry1)
def enabling(self,idx):
self.entry_list[idx].config(state="normal")
root = Tk()
a = practice(root)
root.mainloop()
Whenever people have problem with a function created with a lambda expression instead of a def statement, I recommend rewriting the code with a def statement until it works right. Here is the simplest fix to your code: it reorders widget creation and binds each entry to a new function as a default arg.
from tkinter import *
class practice:
def __init__(self,root):
for w in range(5):
entry=Entry(root, state="disabled")
button=Button(root,text="submit",
command=lambda e=entry:self.enabling(e))
button.grid(row=w,column=0)
entry.grid(row=w,column=1)
def enabling(self,entry):
entry.config(state="normal")
root = Tk()
a = practice(root)
root.mainloop()

storing data from input box in tkinter

I got the assignment to build a program of a store.Now, the customers have to register to be able to buy, I made a main window that has buttons for each action I need to perform. When the user tries to register another window with the data needed to complete the registration appears. Now how do I store the data from the input-box into a list with a button?
Here's an example of how I'm setting each box that the user needs to fill:
var1 = StringVar()
var1.set("ID:")
label1 = Label(registerwindow,textvariable=var1,height = 2)
label1.grid(row=0,column=1)
ID=tkinter.StringVar()
box1=Entry(registerwindow,bd=4,textvariable=ID)
box.grid(row=0,column=2)
botonA= Button(registerwindow, text = "accept",command=get_data, width=5)
botonA.grid(row=6,column=2)
I tried setting the button to run a function that gets the input, but I't now working. Here's what I did
def get_data():
print (box1.get())
A few problems:
Unless you do import tkinter AND from tkinter import * - which you shouldn't; just choose one - your program will choke on either var1 = StringVar() or on ID=tkinter.StringVar().
Define the get_data() function before binding it to a Button.
You assigned box1 but then gridded box.
The following sample will get the box's contents, add it to a list, and print the list to the console every time you click "Accept." Replace the names of parent windows, grid locations of each widget, and so on to suit your program.
from tkinter import *
root = Tk()
root.wm_title("Your program")
mylist = []
def get_data(l):
l.append(box1.get())
print(l)
var1 = StringVar()
var1.set("ID:")
label1 = Label(root,textvariable=var1,height = 2)
label1.grid(row=0,column=0)
ID=StringVar()
box1=Entry(root,bd=4,textvariable=ID)
box1.grid(row=0,column=1)
botonA= Button(root, text = "accept",command=lambda: get_data(mylist), width=5)
botonA.grid(row=0,column=2)
root.mainloop()
to retrieve the value, you need to access the variable it is attached to, not the entry field on the screen:
def get_data():
print (ID.get())

Categories