Entry string not being added to listbox - python

Could anyone help me debug this? The listbox isn't updating, and I'm not sure if the entry text (ment) is even transferring to the method.
def NewTask():
ment = StringVar()
top = Toplevel()
top.title("Add New Task")
top.minsize(300,300)
top.maxsize(300,300)
label_newtask = Label(top, text = "Entry New Task:", font = ("Purisa",20))
label_newtask.pack()
button_newtask = Button(top, text="Enter", command= NewTaskCount)
button_newtask.pack()
entry_newtask = Entry(top, textvariable=ment)
entry_newtask.pack()
def NewTaskCount():
ment = StringVar()
mtext = ment.get()
listbox.insert(END, mtext)
return

Your problem is that your stringvar ment is a local variable that is only visible within the scope of NewTask. In NewTaskCount, you are creating a new StringVar -- which is initially blank -- and immediately getting the value of that new variable. You need to make it a global variable, or use an object-oriented approach so that you can use an instance variable.

Related

Is there a way for the Entry widget to not mimic the Checkbutton's value?

Right off the bat here is my code so far (please ignore the variable names. I am still learning how to use Python):
root = Tk()
testvariable = 0
bruh = 0
test = Checkbutton(root, variable = testvariable, )
test.pack()
test1 = Entry(root,textvariable = bruh, text = "0", width = 4)
test1.pack()
root.mainloop()
I notice that when I select the Checkbutton to turn it off or on, the Entry widget automatically changes its value to whatever the Checkbutton's value is. Is there a way to prevent this?
When setting variables in tkinter make sure to use the built-in types (https://docs.python.org/3/library/tkinter.html#coupling-widget-variables).
For the Entry widget you can directly use the get method to assign its value to a variable. As for the Checkbutton widget, make sure to assign it an "IntVar" type to correctly deal with its value passing. I've demonstrated how to do both of the above in the code below.
import tkinter as tk
root = tk.Tk()
checkbox_var = tk.IntVar()
testvariable = 0
bruh = 0
test = tk.Checkbutton(root, variable=checkbox_var)
test.pack()
test1 = tk.Entry(root)
test1.pack()
def testOutput():
testvariable = checkbox_var.get()
bruh = test1.get()
print("Checkbox is", testvariable)
print("Entry is", bruh)
button = tk.Button(root, text="Test Button", command=testOutput)
button.pack()
root.mainloop()
They mimic each other because both of their textvariable attributes are the same value. The short answer is to give them each different values for textvariable.
Also, you should be setting that attribute to an instance of a tkinter variable such as StringVar or IntVar. However you rarely need to use that attribute with Entry widgets, since the widget itself gives you methods for getting and setting the value.

Python/Tkinter - clear the graphical interface screen

i am developing an application to calculate some taxes and show the result in the graphical interface. The code itself works perfectly, but if i use numbers with bigger squares, the result overlaps over the previous one. My question is, is it possible to clear the previous result and calculate the new one?
Follow the complete code below:
from tkinter import *
root = Tk()
l_vlrRec = Label(root, text='Receita')
l_vlrRec.place(x=10, y=10)
e_vlrRec = Entry(root)
e_vlrRec.place(x=75, y=10, width=75)
def calcular():
receita = float(e_vlrRec.get())
l_result = Label(root, text='{:.2f}'.format(receita))
l_result.place(x=10, y=150)
e_vlrRec.delete(0, END)
bt = Button(root, text='Calcular', command=calcular)
bt.place(x=10, y=50)
root.mainloop()
You can use the label's textvariable and also you don't have to instantiate a new Label every time the button is pressed:
v_result = DoubleVar()
l_result = Label(root, textvariable=v_result)
l_result.place(x=10, y=150)
def calcular():
v_result.set(round(float(e_vlrRec.get()),2))
You can do the same for your Entry object e_vlrRec so you don't have to cast the string you get by calling e_vlrRec.get() but use the variable's get() instead
Without using textvariable you can also reconfigure the label's text parameter:
l_result.configure(text='{:.2f}'.format(receita))
or
l_result['text'] = '{:.2f}'.format(receita)

Get checkbox to create/delete window when checked/unchecked

I want a checkbox that when check, creates a scrolled text widget and when unchecked, removes the widget.
Currently it creates the widget only once I've checked the box and then unchecked it, and then when checked again, it does nothing and when unchecked again, it creates a second widget below.
I've tried different ways of coding it but I can't figure out what I'm doing wrong.
# Creates Normal Checkbutton
chk_state = BooleanVar()
chk_state.set(False) # set check state
chk = Checkbutton(window, text='Normal Entries', var=chk_state)
chk.place(x=0, y=0)
#Checks Checkbutton State
def chk_checked(event):
txt = scrolledtext.ScrolledText(window, height=15, width=35)
if chk_state.get():
txt.insert(END, 'Paste Normal Entries Here...')
txt.pack(anchor='nw', padx=50, pady=50)
elif txt.winfo_exists():
txt.pack_forget()
else:
pass
#Event when checkbox checked
chk.bind('<Button-1>', chk_checked)
You can try as this
import tkinter as tk
from tkinter.scrolledtext import ScrolledText
def chk_checked():
global txt
if chk_state.get():
txt = ScrolledText(window, height=15, width=35)
txt.insert(tk.END, 'Paste Normal Entries Here...')
txt.pack(anchor='nw', padx=50, pady=50)
else:
txt.pack_forget()
window = tk.Tk()
chk_state = tk.BooleanVar()
chk_state.set(False) # set check state
chk = tk.Checkbutton(window, text='Normal Entries', var=chk_state, command=chk_checked)
chk.place(x=0, y=0)
txt = None
window.mainloop()
This isn't the best way for do that, maybe you can create a class, i think that would be better.
The problem with your code is that each time that you click the CheckButton the function chk_checked(event) creates a new ScrolledText and after works on it instead working on the ScrolledText that was created previously. You have to declare a global variable (instead of a local variable) in wich you store the ScrolledText that you want to use and work only with it

Updating a label from an entry field on button push with tkinter in Python 3.5.2

I am trying to create a window with a line label, an entry field, a current value label, and an "Update Value" button.
Here is an example:
This is what I have so far. I can get the entered value to print to console, but I can't seem to work out how to get an entered value and change the currentValue Label to reflect that value by pressing the button:
from tkinter import*
main=Tk()
#StringVar for currentValue in R0C2
currentValue = StringVar(main, "0")
#Called by the setValues button, looks for content in the entry box and updates the "current" label
def setValues():
content = entry.get()
print(content)
#This kills the program
def exitProgram():
exit()
#Title and window size
main.title("Title")
main.geometry("350x200")
#Descriptions on the far left
Label(main, text="Duration (min): ").grid(row=0, column=0)
#Entry boxes for values amidship
entry=Entry(main, width=10)
entry.grid(row=0, column=1)
#Displays what the value is currently set to.
currentValue = Label(textvariable=currentValue)
currentValue.grid(row=0,column=2)
#Takes any inputted values and sets them in the "Current" column using def setValues
setValues=Button(text='Set Values',width=30,command=setValues)
setValues.grid(row=9, column=0, columnspan=2)
#Red button to end program
exitButton=Button(main, text='Exit Program',fg='white',bg='red',width=30, height=1,command=exitProgram)
exitButton.grid(row=20, column = 0, columnspan=2)
main.mainloop()
There are a couple of problems with your code.
Firstly, you are overwriting the setValues function with the setValues Button widget, and similarly, you are overwriting the currentValue StringVar with the currentValue Label.
To set a StringVar, you use its .set method.
Don't use plain exit in a script, that's only meant to be used in an interactive interpreter session, the proper exit function is sys.exit. However, in a Tkinter program you can just call the .destroy method of the root window.
Here's a repaired version of your code.
import tkinter as tk
main = tk.Tk()
#StringVar for currentValue in R0C2
currentValue = tk.StringVar(main, "0")
#Called by the setValues button, looks for content in the entry box and updates the "current" label
def setValues():
content = entry.get()
print(content)
currentValue.set(content)
#This kills the program
def exitProgram():
main.destroy()
#Title and window size
main.title("Title")
main.geometry("350x200")
#Descriptions on the far left
tk.Label(main, text="Duration (min): ").grid(row=0, column=0)
#Entry boxes for values amidship
entry = tk.Entry(main, width=10)
entry.grid(row=0, column=1)
#Displays what the value is currently set to.
currentValueLabel = tk.Label(textvariable=currentValue)
currentValueLabel.grid(row=0,column=2)
#Takes any inputted values and sets them in the "Current" column using def setValues
setValuesButton = tk.Button(text='Set Values',width=30,command=setValues)
setValuesButton.grid(row=9, column=0, columnspan=2)
#Red button to end program
exitButton = tk.Button(main, text='Exit Program',fg='white',bg='red',width=30, height=1,command=exitProgram)
exitButton.grid(row=20, column = 0, columnspan=2)
main.mainloop()
BTW, it's a Good Idea to avoid "star" imports. Doing from tkinter import * dumps 130 names into your namespace, which is unnecessary and creates the possibility of name collisions, especially if you do star imports from several modules. It also makes the code less readable, since the reader has remember which names you defined and which ones came from the imported module(s).
In my opinion the easiest way to do this would be using an object orientated method. This way you could declare a button with a command that calls a def which runs self.label.configure(text=self.entry.get()).
This can be seen below:
import tkinter as tk
class App:
def __init__(self, master):
self.master = master
self.label = tk.Label(self.master)
self.entry = tk.Entry(self.master)
self.button = tk.Button(self.master, text="Ok", command=self.command)
self.label.pack()
self.entry.pack()
self.button.pack()
def command(self):
self.label.configure(text=self.entry.get())
root = tk.Tk()
app = App(root)
root.mainloop()
The above creates a label, entry and button. The button has a command which calls a def within the class App and updates the value of the label to be the text contained within the entry.
This all works very smoothly and cleanly and more importantly is drastically easier (in my opinion) to read and update in the future.
From your code you are setting the 'currentValue', which is a StringVar:
#StringVar for currentValue in R0C2
currentValue = StringVar(main, "0")
to an object Label further down in your code. You cannot do this!
#Displays what the value is currently set to.
currentValue = Label(textvariable=currentValue) ** this line is wrong
currentValue.grid(row=0,column=2)
You should name the label something different like:
#Displays what the value is currently set to.
lblCurrentValue = Label(textvariable=currentValue)
lblCurrentValue.grid(row=0,column=2)
Then in your "setValues" method you should use 'StringVar.set(value) to update the label like so:
def setValues():
content = entry.get()
currentValue.set(entry.get())------------------Here I set the value to the entry box value
print(content)
I tend to avoid stringVar and just use:
Label.config(text='*label's text*')
If you need more help I can post you my solution but try and solve it first becasue its the best way to learn. My tip is to make sure you are using correct naming conventions. In tkinter I tend to use lbl..., entryBox... etc before widgets so I know what they are and not to confuse them with variables.

Linking Tkinter label based on Entry value

Is there a way to make a Tkinter label that automatically updates to reflect changes in the text of an Entry field? For example, if the Entry has the text "1", the label should say "T1", but if the user changes the text in entry to "x" then the label should say "Tx", without having to press a button.
Yes, this is possible. The easiest way I can think of is using the .trace method of a StringVar, which calls a function if the value of the StringVar() changes. Here's an example:
def change_label(*args):
label.config(text='') # clear label
label.config(text='T' + var.get()) # set new label text
root = Tk()
var = StringVar() # make the StringVar()
label = Label(root)
entry = Entry(root, textvariable=var) # set the textvariable to var
var.trace('w', change_label) # trace var to monitor for changes, calling function on change
label.pack()
entry.pack()
root.mainloop()
More on trace: http://effbot.org/tkinterbook/variable.htm

Categories

Resources