Python Tkinter StringVar issues - python

I am trying to make a simple calculator for a game I play as a random project. I found myself very confused on how to go about doing this; I want the user to enter a number in the textbox and it will multiply that number by 64000 and display it in a label above. But, I cannot find out anywhere how to do this. This is just a small practice thing and im amazed I cannot figure it out. Please help meh! Here is my code:
from Tkinter import *
####The GUI#####
root = Tk()
#Title#
root.wm_title("TMF Coin Calculator")
####The Widgets####
a = StringVar()
b = StringVar()
def multiply_a():
d = (int(a) * 64000)
e = str(d)
b.set(e)
b.trace("w", multiply_a)
#Top Label#
top_label = Label(root, fg="red", text="Type the ammount of Coin Stacks you have.")
top_label.grid(row=0, column=0)
#The Output Label#
output_label = Label(root, textvariable=b, width = 20)
output_label.grid(row = 1, column=0)
#User Entry Box#
user_input_box = Entry(root, textvariable=a, width=30)
user_input_box.grid(row=2, column=0)
root.mainloop()

You need to trace the variable that changes: a. Then you need to define multiply_a() to handle an arbitrary number of arguments with *args (happens to be 3 arguments in this case, but *args is fine here).
Go from:
def multiply_a():
d = (int(a) * 64000)
e = str(d)
b.set(e)
b.trace("w", multiply_a)
to:
def multiply_a(*args):
try:
myvar = int(a.get())
except ValueError:
myvar = 0
b.set(myvar * 64000)
a.trace("w", multiply_a)
This will additionally use 0 if the entered value can't be turned into an int.

Related

I'm unable to get a string out of tkinter entrybox

import random
import tkinter as tk
frame = tk.Tk()
frame.title("koeweils baldadige encyptor")
frame.geometry('400x200')
printButton = tk.Button(frame,text = "Print", command = lambda: zandkasteel())
printButton.pack()
freek = tk.Text(frame,height = 5, width = 20)
freek.pack()
input_a = freek.get(1.0, "end-1c")
print(input_a)
fruit = 0
fad = input_a[fruit:fruit+1]
print(fad)
schepje = len(input_a.strip("\n"))
print(schepje)
def zandkasteel():
lbl.config(text = "Ingevulde string: "+input_a)
with open("luchtballon.txt", "w") as chocoladeletter:
for i in range(schepje):
n = random.randint()
print(n)
leuk_woord = ord(fad)*n
print(leuk_woord)
chocoladeletter.write(str(leuk_woord))
chocoladeletter.write(str(n))
chocoladeletter.write('\n')
lbl = tk.Label(frame, text = "")
lbl.pack()
frame.mainloop()
I need to get the string that was entered into the text entry field freek. I have tried to assign that string to input_a, but the string doesn't show up.
Right now, input_a doesn't get anything assigned to it and seems to stay blank. I had the same function working before implementing a GUI, so the problem shouldn't lie with the def zandkasteel.
To be honest I really don't know what to try at this point, if you happen to have any insights, please do share and help out this newbie programmer in need.
Here are some simple modifications to your code that shows how to get the string in the Text widget when it's needed — specifically when the zandkasteel() function gets called in response to the user clicking on the Print button.
import random
import tkinter as tk
frame = tk.Tk()
frame.title("koeweils baldadige encyptor")
frame.geometry('400x200')
printButton = tk.Button(frame, text="Print", command=lambda: zandkasteel())
printButton.pack()
freek = tk.Text(frame, height=5, width=20)
freek.pack()
def zandkasteel():
input_a = freek.get(1.0, "end-1c")
print(f'{input_a=}')
fruit = 0
fad = input_a[fruit:fruit+1]
print(f'{fad=}')
schepje = len(input_a.strip("\n"))
print(f'{schepje=}')
lbl.config(text="Ingevulde string: " + input_a)
with open("luchtballon.txt", "w") as chocoladeletter:
for i in range(schepje):
n = random.randint(1, 3)
print(n)
leuk_woord = ord(fad)*n
print(leuk_woord)
chocoladeletter.write(str(leuk_woord))
chocoladeletter.write(str(n))
chocoladeletter.write('\n')
lbl = tk.Label(frame, text="")
lbl.pack()
frame.mainloop()

Change (update) text in Python Tkinter widgets

I am trying to update information in tkinter labels and buttons without redrawing entire screens. I'm using Python 3, a Raspberry Pi, and Idle. I have a trivial example of what I am trying to do. I see comments here that suggest I need to learn to manipulate stringvariable or IntVar, etc. but my book is totally unhelpful in that regard. In this example, I would like the number between the buttons to track the value of the number as it changes with button pushes.
##MoreOrLess.01.py
from tkinter import *
global number
number = 5
root = Tk()
root.title("Test Buttons")
def Less():
global number
number -= 1
print ("The number is now ", number)
def More():
global number
number += 1
print("The number is now ", number)
def MakeLabel(number):
textvariable = number
label1 = Label(root, text = "Pick a button please.").pack(pady=10)
btnL = Button(root, text = "More", command = More).pack(side = LEFT)
btnR = Button(root, text = "Less", command = Less).pack(side = RIGHT)
label2 = Label(root, text = number).pack(pady = 20)
MakeLabel(number)
Not only do you base yourself in a book, check the official documentation of tkinter. in your case you must create a variable of type IntVar with its set() and get() method, and when you want to link that variable through textvariable.
from tkinter import *
root = Tk()
root.title("Test Buttons")
number = IntVar()
number.set(5)
def Less():
number.set(number.get() - 1)
print ("The number is now ", number.get())
def More():
number.set(number.get() + 1)
print("The number is now ", number.get())
def MakeLabel(number):
textvariable = number
label1 = Label(root, text = "Pick a button please.").pack(pady=10)
btnL = Button(root, text = "More", command = More).pack(side = LEFT)
btnR = Button(root, text = "Less", command = Less).pack(side = RIGHT)
label2 = Label(root, textvariable = number).pack(pady = 20)
MakeLabel(number)
root.mainloop()

Issues figuring out how to update labels in Tkinter for my Python program

So I am writing a Python program in class that uses the Caesar cipher to take a users input and output it as cipher-text. Since i had a lot more time for this project I planned on giving it a GUI in Tkinter. But when I assign the resulted cipher-text to a label it won't display it and keeps it blank. I'm a noob to python and even more to Tkinter so I'm not too keen on being able to fix these issues myself. Here's the code:
import string
import collections
import random
import tkinter
from tkinter import *
from tkinter.ttk import *
root = Tk()
root.title("Encoder")
root.geometry("500x400")
def caesar(rotate_string, number_to_rotate_by):
upper = collections.deque(string.ascii_uppercase)
lower = collections.deque(string.ascii_lowercase)
upper.rotate(number_to_rotate_by)
lower.rotate(number_to_rotate_by)
upper = ''.join(list(upper))
lower = ''.join(list(lower))
return rotate_string.translate(str.maketrans(string.ascii_uppercase, upper)).translate(str.maketrans(string.ascii_lowercase, lower))
def callback():
print (code)
b = Button(root, text="get", width=10, command=callback)
b.pack()
var = StringVar()
e = Entry(root, textvariable = var)
e.pack()
our_string = e.get()
random_number = random.randint(1,25)
code = caesar(our_string, random_number)
l = Label(root, textvariable=code, anchor=NW, justify=LEFT, wraplength=398)
l.pack()
l.place(relx=0.5, rely=0.5, anchor=CENTER)
root.mainloop()
There are several issues with the code you've posted. First and foremost, your callback doesn't do anything besides print the code variable. You need to move your call to caesar and the associated code into the callback, like so
def callback():
global code
our_string = e.get()
random_number = random.randint(1, 25)
code.set(caesar(our_string, random_number))
The second issue that I see is that you need to use a StringVar as the textvariable argument in your Label constructor in order to get the label to update automatically. When all is said and done, my version of your code looks like
import string
import collections
import random
from tkinter import *
from tkinter.ttk import *
root = Tk()
root.title("Encoder")
root.geometry("500x400")
code = StringVar()
code.set('Hello')
def caesar(rotate_string, number_to_rotate_by):
upper = collections.deque(string.ascii_uppercase)
lower = collections.deque(string.ascii_lowercase)
upper.rotate(number_to_rotate_by)
lower.rotate(number_to_rotate_by)
upper = ''.join(list(upper))
lower = ''.join(list(lower))
return rotate_string.translate(str.maketrans(string.ascii_uppercase, upper)).translate(str.maketrans(string.ascii_lowercase, lower))
def callback():
global code
our_string = e.get()
random_number = random.randint(1, 25)
code.set(caesar(our_string, random_number))
b = Button(root, text="get", width=10, command=callback)
b.pack()
var = StringVar()
e = Entry(root, textvariable=var)
e.pack()
l = Label(root, textvariable=code, anchor=NW, justify=LEFT, wraplength=398)
l.pack()
l.place(relx=0.5, rely=0.5, anchor=CENTER)
root.mainloop()
This seems to do what you'd expect.

How would I create a reset button for my program relating with the following code?

I am trying to add a reset button but I can't seem to get it to work. I created a main in order to refer back to it when the button is pressed but no luck. Any ideas?
import sys
from tkinter import *
import math
def main():
def closeWin():
myGui.destroy() #Close Window Function
def kiloFunc():
myText = kiloMent.get() #Kilometers to Miles Fuction
convert = 0.62
miles = myText * convert
finalKilo = Label(text = miles,fg='red',justify='center').place(x=200,y=80)
def mileFunc():
myText2 = mileMent.get() #Miles to Kilometers Function
convertTwo = myText2 // 0.62
finalMile = Label(text = convertTwo, fg = 'red',justify='center').place(x=200,y=170)
myGui = Tk()
kiloMent = IntVar()
mileMent = IntVar()
myGui.title("Distance Converter")
myGui.geometry("450x200+500+200")
myLabel = Label(text="Welcome! Please enter your value then choose your option:",fg="blue",justify='center')
myLabel.pack()
kiloEntry = Entry(myGui, textvariable = kiloMent,justify='center').pack()
kilo2milesButton = Button(text = "Kilometers to Miles!", command = kiloFunc).pack()
mileEntry = Entry(myGui, textvariable = mileMent,justify='center').place(x=130,y=105)
miles2kiloButton = Button(text = "Miles to Kilometers!", command = mileFunc).place(x=150,y=135)
reset = Button(text = "Reset Values!", command = main).place(x=10,y=165)
quit = Button(text="Quit", command = closeWin).place(x=385,y=165)
myGui.mainloop()
main()
By calling main() again, you are simply creating another instance of the GUI. What you should do instead is (if I understand correctly), reset the values of the currently existing GUI. You can use the set() method of the GUI objects.
Does
def reset_values():
kiloMent.set(0)
mileMent.set(0)
reset = Button(text="Reset Values!", command=reset_values).place(x=10, y=165)
do the trick?
Looking at your code more thoroughly, however, there are some other problems there, as well. To start with, I would suggest not creating a Label everytime the user tries to convert a value.
This code should work:
from tkinter import *
def main():
def closeWin():
myGui.destroy() # Close Window Function
def kiloFunc():
finalKilo.set(kiloMent.get() * 0.62) # Kilometers to Miles Fuction
def mileFunc():
finalMile.set(mileMent.get() // 0.62) # Miles to Kilometers Function
def clearFunc():
kiloMent.set("0")
mileMent.set("0")
finalKilo.set("")
finalMile.set("")
myGui = Tk()
kiloMent = IntVar()
mileMent = IntVar()
finalKilo = StringVar()
finalMile = StringVar()
myGui.title("Distance Converter")
myGui.geometry("450x200+500+200")
myLabel = Label(text="Welcome! Please enter your value then choose your option:", fg="blue", justify='center')
myLabel.pack()
kiloEntry = Entry(myGui, textvariable=kiloMent, justify='center')
kiloEntry.pack()
kilo2milesButton = Button(text="Kilometers to Miles!", command=kiloFunc)
kilo2milesButton.pack()
mileEntry = Entry(myGui, textvariable=mileMent, justify='center')
mileEntry.place(x=130, y=105)
miles2kiloButton = Button(text="Miles to Kilometers!", command=mileFunc)
miles2kiloButton.place(x=150, y=135)
kiloLabel = Label(textvariable=finalKilo, fg='red', justify='center')
kiloLabel.place(x=200, y=80)
mileLabel = Label(textvariable=finalMile, fg='red', justify='center')
mileLabel.place(x=200, y=170)
reset = Button(text="Reset Values!", command=clearFunc)
reset.place(x=10, y=165)
quit = Button(text="Quit", command=closeWin)
quit.place(x=385, y=165)
myGui.mainloop()
main()
A few notes about your original code besides the ones that Chuck mentioned:
The math and sys imports were unused.
You were setting variables equal to widget.pack() and widget.place(), which are functions that return None.

How to update a label in Tkinter, StringVar() not working

I am working on this short code that compares the single characters of two strings. After the first running, when I change the strings in the entryBoxes,I would like to replace the label created before, instead of creating a new one. I have already tried with StringVar() but it seems not working. (If it can be useful I'm using Python 2.7.6). Could you please give me a hint?
from Tkinter import *
app = Tk()
app.geometry('450x300')
labelTF = Label(app, text="Insert sequence of TF").pack()
eTF = Entry(app, width=50)
eTF.pack()
eTF.focus_set()
labelSpazio = Label(app, text="\n").pack()
labelResultedSequence = Label(app, text="Insert sequence of ResultedSequence").pack()
eResultedSequence = Entry(app, width=50)
eResultedSequence.pack()
eResultedSequence.focus_set()
def prova():
count = 0
uno = eTF.get().lower()
due = eResultedSequence.get().lower()
if len(uno)==len(due):
for i in range(0,len(uno)):
if uno[i] == due[i]:
if uno[i] in ("a", "c","g","t"):
count = count + 1
if uno[i] == "r" and due[i] in ("a", "g"):
count = count + 1
if uno[i] == "y" and due[i] in ("t", "c"):
count = count + 1
percentage = int(float(count)/float(len(uno))*100)
labelSpazio = Label(app, text="\n").pack()
mlabel3=Label(app,text= "The final similarity percentage is: "+(str(percentage) + " %")).pack()
if len(uno)!=len(due):
mlabel2 = Label(app,text="The length of the sequences should be the same").pack()
b = Button(app, text="get", width=10, command=prova)
b.pack()
mainloop()
Create the labels only once outside of the for loop and use a StringVar to modify its value. It would look like this:
# initialization
app = Tk()
label3text = StringVar()
mlabel3 = Label(app, textvariable=label3text, width=100)
mlabel3.pack()
Then in the for loop inside your function:
label3text.set("The final similarity percentage is: "+(str(percentage) + " %"))

Categories