I have a variable that is updated on a button click, and I want to show the variable's value in a Text widget, but I'm getting a blank every time despite checking that the variable is not empty.
I'm using a StringVar called var as a middle man but the result is still blank.
from tkinter import *
import time
var = None
def get_tags():
tag_info={'hashtags':"Loading..."}
var.set(str(tag_info.get('hashtags','')))
if __name__ == '__main__':
root = Tk()
root.title("Tag Generator")
var = StringVar(root)
show_button = Button(root, text='Show',
command=lambda: get_tags())
show_button.grid(column=2,columnspan=1, padx=5, pady=5, row=num+1)
result_text = Text(root)
result_text.grid(column=0,columnspan=3, padx=5, pady=5, row=num+2, rowspan=4)
result_text.insert('1.0',var.get())
while True:
time.sleep(0.01)
root.update()
How can I show the contents of var in my Text widget?
EDIT:contents of my var variable:
var.get()
Out[86]: '.\n.\n.\n.\n.\n.\n.\n.\n.\n.\n#cat #dog #catsofinstagram #cats #pet #dogsofinstagram #catlover #cute #love #dogs #pets #catstagram #instagood #puppy #kitty #animals #petstagram #dogstagram #gato #kitten #animal #instadog #catoftheday #doglover #cats_of_instagram #adorable #instagram #dogoftheday #instacat #meow '
(which is as expected/desired)
The text is not showing because the var = '' at line result_text.insert('1.0',var.get())and you can't press the Button before mainloop so by putting the same line in function get_tags() should solve the issue.
But at this point I'm wonder why you even need var. If you're not using it for anything else then you should remove it and insert in the Text directly.
def get_tags():
tag_info={'hashtags':"Loading..."}
tag_info = my_file.get_tags()
var.set(str(tag_info.get('hashtags','')))
result_text.insert('1.0', var.get())
Related
I'm wondering why my radiobutton variable is not returning a value. Kindly see my setup below :
Global declarations of the frame, radiobuttons, template variable and 'Download' button. I placed my radiobuttons in a frame. I commented the set() function here.
root = tk.Tk()
frm_radioButtons = tk.Frame(root)
template = tk.StringVar()
# template.set("m")
rbtn_create_delete = tk.Radiobutton(frm_radioButtons, text="Create/Delete items", font=(
'Arial', 8), variable="template", value="cd")
rbtn_move = tk.Radiobutton(
frm_radioButtons, text="Move items", font=('Arial', 8), variable="template", value="m")
btn_download = tk.Button(frm_radioButtons, text="Download",
font=('Arial', 7), command=generate_template, padx=15)
And created them inside a function below. Tried using global keyword but still not working. This is the main point of entry of this script.
def load_gui():
root.geometry("300x360")
frm_radioButtons.columnconfigure(0, weight=1)
frm_radioButtons.columnconfigure(1, weight=1)
#global rbtn_create_delete
#global rbtn_move
rbtn_move.grid(row=0, column=0)
rbtn_create_delete.grid(row=0, column=1)
btn_download.grid(row=1, column=0)
frm_radioButtons.pack(padx=10, anchor='w')
And here is the generate_template function when the 'Download' button is clicked. Note though, that the "Move items" radiobutton is pre-selected when I run the program even if I set(None).
It doesn't print anything.
def generate_template():
type = template.get()
print(type)
Tried a pretty straightforward code below and still did not work. It returns empty string. Switched to IntVar() with 1 & 2 as values, but only returns 0.
import tkinter as tk
def download():
print(btnVar.get())
root = tk.Tk()
btnVar = tk.StringVar()
rbtn1 = tk.Radiobutton(root, text="Button1", variable="bntVar", value="b1")
rbtn2 = tk.Radiobutton(root, text="Button1", variable="bntVar", value="b2")
rbtn1.pack()
rbtn2.pack()
btn_dl = tk.Button(root, text="Download", command=download)
btn_dl.pack()
root.mainloop()
Been reading here for the same issues but I haven't got the correct solution. Appreciate any help. tnx in advance..
Expected result: get() function return
The value passed to the variable option needs to be a tkinter variable. You're passing it a string.
In the bottom example it needs to be like this:
rbtn1 = tk.Radiobutton(root, text="Button1", variable=btnVar, value="b1")
rbtn2 = tk.Radiobutton(root, text="Button1", variable=btnVar, value="b2")
# ^^^^^^
I am new to tkinter and learning to use the widget "CheckButton".
I have encountered a problem, whatever I select, the code prints 0.
Wanted:
print 1 if selected
print 0 if not selected
MWE
import tkinter as tk
win = tk.Tk()
win.title('My Window')
win.geometry('100x100')
l = tk.Label(win, width=20, text='MultipleReplace')
l.pack()
var_cb1 = tk.IntVar()
var_cb1.set(0)
cb1 = tk.Checkbutton(win, text='Yes',variable=var_cb1,onvalue=1,offvalue=0)
cb1.pack(side=tk.TOP)
var_cb1_val = var_cb1.get()
print('The selected value is : ', var_cb1_val)
win.mainloop()
You're calling get on var_cb1 pretty much immediately after setting it to 0, and then printing that value. You're not waiting for the checkbutton to change states and then printing the value. Define a function that gets called when the CheckButton changes state, then get the value there
import tkinter as tk
def on_update(var):
print('The selected value is: ', var.get()) # get the new value
win = tk.Tk()
win.title('My Window')
win.geometry('100x100')
l = tk.Label(win, width=20, text='MultipleReplace')
l.pack()
var_cb1 = tk.IntVar()
var_cb1.set(0)
cb1 = tk.Checkbutton(
win,
text='Yes',
variable=var_cb1,
onvalue=1,
offvalue=0,
# call 'on_update', using a lambda to pass in the 'var_cb1' variable
command=lambda var=var_cb1: on_update(var)
)
cb1.pack(side=tk.TOP)
win.mainloop()
There's an example of my code below.
I am trying to make a GUI with tkinter, in python. I want an app that has a variable, let's say var_list, that is introduced into a function as a parameter.I run this function using a button with command=lambda: analize(var_list)
I want to be able to modify the variable by pressing buttons (buttons to add strings to the list). And I have a function for that aswell:
def button_clicked(e):
if ((e["text"]).lower()) in var_list:
var_list.pop(var_list.index((e["text"]).lower())) #this adds a string to the list
else:
var_list.append((e["text"]).lower()) #this deletes the string from the list if it was already there
The function works, I tried printing the var_list and it gets updated everytime I press a button.
The problem is that I have to create the var_list as an empty list before, and when I run the function analize(var_list), it uses the empty list instead of the updated one.
Any idea on how to update the global var everytime I add/delete something from the list?
from tkinter import *
from PIL import ImageTk
def show_frame(frame):
frame.tkraise()
def button_clicked(e):
if ((e["text"]).lower()) in var_list:
var_list.pop(var_list.index((e["text"]).lower()))
else:
var_list.append((e["text"]).lower())
def analize(x):
#does stuff with the list
window = Tk()
frame1 = Frame(window)
frame2 = Frame(window)
canvas1 = Canvas(frame1,width = 1280, height = 720)
canvas1.pack(expand=YES, fill=BOTH)
image = ImageTk.PhotoImage(file="background.png")
var_list = []
button1 = Button(canvas1, text="Analize",font=("Arial"),justify=CENTER, width=10, command=lambda: [show_frame(frame2),analize(x=var_list)])
button1.place(x=(1280/2)-42, y=400)
button2 = Button(canvas1, text="String1",font=("Arial"),justify=CENTER, width=10, command=lambda: button_clicked(button2))
button2.place(x=(1280/2)-42, y=450)
button3 = Button(canvas1, text="String2",font=("Arial"),justify=CENTER, width=10, command=lambda: button_clicked(button3))
button3.place(x=(1280/2)-42, y=500)
Thank you
you can make a global variable eg:-global var
Now you can access it within other defination to manipulate the variable like this
global var
var = 0 # if you want to set a default value to the variable before calling the
function
def change_var():
global var
var = 1
USE OF GLOBAL
using global is highly recommended and is quite necessary if you are working with functions that contain or has the need to manipulate the variable
If global is not given inside the function, the variable will live inside the function and it cannot be accessed outside the function.
Hope this answer was helpful, btw, I am not sure if this the answer you are looking for as your question is not clear, maybe give a situation where you might think it might be necessary to change or update the variable
Sorry, I did not understand you but I guess this example will help you -
import tkinter as tk
root = tk.Tk()
var_list = []
def change_val(n):
var_list.append(n)
label1.config(text=var_list)
def remove():
try:
var_list.pop()
label1.config(text=var_list)
except:
pass
label1 = tk.Label(root,text=var_list)
label1.pack()
button1 = tk.Button(root,text='1',command=lambda:change_val(1))
button1.pack()
button2 = tk.Button(root,text='2',command=lambda:change_val(2))
button2.pack()
button3 = tk.Button(root,text='3',command=lambda:change_val(3))
button3.pack()
button4 = tk.Button(root,text='Pop Element',command=remove)
button4.pack()
root.mainloop()
I am working on a relatively large project, but have managed to recreate my problem in just a few lines:
import tkinter as tk
root = tk.Tk()
root.geometry('200x200')
def doStuff():
pass
sv = tk.StringVar()
def callback():
print(E.get())
doStuff()
return True
E = tk.Entry(root, bg="white", fg="black", width=24, textvariable=sv, validate="key",validatecommand=callback)
E.grid(row=0, column=0, padx=30, pady=5, sticky=tk.E)
root.mainloop()
The desired output would be that every time the user changes the entry in this Entrywidget, a function is called.
This works just fine, but using E.get() returns the 'previous' entry, for example:
-entry is 'boo'
-E.get() is 'bo'
Python seems to run Callback() before the Entry Widget has been changed.
Validation by design happens before the text has been inserted or deleted. For validation to work, it must be able to prevent the data from being changed.
If you aren't doing validation, but instead just want to call a function when the value changes, the best way to do that is to put a trace on the associated variable.
def callback(*args):
print(E.get())
doStuff()
return True
sv = tk.StringVar()
sv.trace_add("write", callback)
In the program I made, the user presses enter and the text typed is then shown as a label in the program. So the label keeps getting updated and then written on the next line. The problem is that in the textbox the previous line the user typed stays there, which means u have to keep manually deleting the string in the textbox to write a new line. How can I make it so that you start out with a cleared textbox? Also, the enter button works but it seems that when i click on the "Return" button it gives me an error:
TypeError: evaluate() missing 1 required positional argument: 'event'
Here's the code:
from tkinter import *
window = Tk()
window.geometry("200x300")
def evaluate(event):
thetext = StringVar()
labeloutput = Label(app, textvariable = thetext)
n = e.get()
thetext.set(n)
labeloutput.grid()
app = Frame(window)
app.pack()
e = Entry(window)
e.pack()
b= Button(window, text="Return", command=evaluate)
b.pack()
window.bind("<Return>", evaluate)
mainloop()
Since you bind evaluate as a callback and you use it as a button command, when you use it in the button you have to use a lambda and pass None to the event. event argument is needed because of the binding, but there is no event when you call it from button click, so just pass None to get rid of the error. You can delete by doing entry.delete(0, 'end').
from tkinter import *
window = Tk()
window.geometry("200x300")
def evaluate(event):
thetext = StringVar()
labeloutput = Label(app, textvariable = thetext)
n = e.get()
thetext.set(n)
labeloutput.grid()
e.delete(0, 'end') # Here we remove text inside the entry
app = Frame(window)
app.pack()
e = Entry(window)
e.pack()
b = Button(window, text="Return", command=lambda: evaluate(None)) # Here we have a lambda to pass None to the event
b.pack()
window.bind("<Return>", evaluate)
mainloop()
Of course, if you want to prevent the lambda from being used, you would have to create a function to handle the key binding, and a separate one for the button click.