I am new to tkinter. I want to write two numbers in two different entries in GUI and see their updated subtraction result on the display. here is my code:
from tkinter import *
window = Tk()
lb1 = Label(window,text="variable 1")
lb1.pack()
name1=IntVar()
en1=Entry(window, textvariable=name1)
en1.pack()
lb2 = Label(window,text="variable 2")
lb2.pack()
name2=IntVar()
en2=Entry(window, textvariable=name2)
en2.pack()
subt=IntVar()
subt=name1.get()-name2.get()
label_subt=Label(window, text=subt).pack()
how can I update label_subt?
You change the subt variable to the result of the subtraction before actually setting it to the label. Don't do that! Also, you set it as the text, not as the textvariable.
subt = IntVar()
Label(window, textvariable=subt).pack()
(Note that the result of pack() is not the Label, but None, so either move it to a separate line, as you did before, or just don't bind it to a variable that you never need anyway.)
Next, you can define a callback function for updating the value of the subt variable using the set method and bind that callback to any key press. You might want to narrow this down a bit, though.
def update(event):
subt.set(name1.get() - name2.get())
window.bind_all("<Key>", update)
You could try calling the config method on the label after every subtraction. You’ll have to use the entry.get() method to get the string of each entry. And don’t forget to use int() to convert it to an integer so you can do your subtraction otherwise you’ll get an error
label_subt.config(text=result)
Related
def openCipher():
cipher = Toplevel()
cipher.title("decryptt - CIPHER")
cipherLabel = Label(cipher, text="cipher").pack()
cipherEntry = Entry(cipher, width=20, borderwidth=5) #separating pack now allows you to use get() on this
cipherEntry.pack()
cipherChoices = [
("Binary","bcipher"),
("Caesar","ccipher"),
("Hexadecimal","hcipher"),
("Atbash","acipher"),
("Letter-to-Number","lcipher")
]
cipherType = StringVar()
cipherType.set("Binary")
for text, cipherChoice in cipherChoices:
Radiobutton(cipher, text=text, variable=cipherType, value=cipherChoice).pack()
cipherButton = Button(cipher, text="Cipher", padx=10, pady=5, command=lambda:[ciphering(cipherEntry.get()), ciphering(cipherChoice.get())]).pack() #lambda allows you to pass arguments to functions
quitButton = Button(cipher, text="Exit Cipher", padx=10, pady=5, command=cipher.destroy).pack()
# This is the function that is suppose to split the input from cipherEntry into individual characters in an array.
def ciphering(entry,choice):
ciphering = Toplevel() #needed to add new label to
cipherLabeling = Label(ciphering, text = "You have inputted " + entry).pack() #couldn’t add a list to string like that, nor use get() on a list, changed to just use the string
seperatedWord = list(entry)
cipherLabeling = Label(ciphering, text = seperatedWord[2]).pack()
seperatedWordLength = len(seperatedWord)
cipherLabeling = Label(ciphering, text = seperatedWordLength).pack()
selection = Label(ciphering, text = choice).pack()
Above is part of the code I have for my ciphering app I am making in Tkinter. Took out the less important parts.
Basically, what is being created in OpenCipher() functions is an entry box that is named cipherEntry. Then there are radio buttons with different names of different ciphers and the value and variable of each radio button is the same as each other for that radio button. Then there is another button that takes whatever cipherEntry is and brings it to another window using the ciphering() function.
What I need to know is how do I also get whatever the value and/or variable of whatever radio button they have selected to that window using the same button they pressed to get to that window ( cipherButton ). Because I want to then use their selection and input to know what cipher type they want their input to be changed to. I already have the function for it sorted.
I have tried using cipherType, cipherChoice, cipherChoices but have no idea how to get them both in there. With the current code above. It works as if there was no second command. It totally disregards whatever selection I put in and the 'selection' label widget doesn't display their choice. I have also made each variable a global to see if that did anything but no luck.
I would really appreciate any assistance :)
First of all, the code should give an error because def ciphering(entry,choice) expects two positional arguments to be passed at the same time. Even after fixing that, it should give another error because cipherChoice is a string(from the list of tuples) and does not have a get attribute.
The thing to focus on here is:
command=lambda: [ciphering(cipherEntry.get()), ciphering(cipherChoice.get())]
When you say something like lambda: [func1(arg1),func1(arg2)] you are set to executing the function func1 and again func1 one after the other(so twice). What you want is to pass multiple arguments to the same function just using a normal lambda without any list, like:
command=lambda: ciphering(cipherEntry.get(), cipherType.get())
Also notice how I changed cipherChoice.get() to cipherType.get(), it is because cipherChoice is a string and also does not have a get attribute, but the value of the radiobutton should be acquired from the associated tkinter variable(StringVar) only. So you have to use cipherType.get()
I am trying to make a label appear if the condition of my entry (textbox) is met. Unfortunately I cannot see anything when I am pressing the button on the testing. Here is what I have:
from tkinter import *
main= Tk()
firstname=Entry(main).place(x=30, y=50)
def register():
if any(i.isdigit() for i in firstname.get())== True:
print (Label(main,text='no numbers please').place(x=30, y=180))
else:
print(Label(main, text='pass').place(x=40, y=170))
register=Button(main,text='REGISTER', command= lambda :register).place(x=300, y=200)
There are at least three problems with your code. The first is in how you define the button's command:
register=Button(main,text='REGISTER', command= lambda :register)
When you do command=lambda: register, you're telling the button "when you're clicked run the code register". register all by itself does nothing. Since register is (supposed to be) a function, you need to call it like register() inside the lambda.
Since you aren't passing any values to the function, the lambda is completely unnecessary. Instead, just directly reference the function: command=register without the parenthesis.
The second problem is that you've used the name register to be two different things: a function and a reference to a widget. Because of the ordering of the code, command=register or command=lambda: register() will try to call the button rather than the function.
The third problem is a very, very common mistake. In python, when you do x = y().z(), x is given the value of z(). Thus, register = Button(...).pack(...) returns the value of pack(...) and pack (and grid and place) always returns None.
Therefore, you've set register to None, and when you try to call it you get NoneType object is not callable.
In addition to fixing the command, you need to pick a different name for either the function or the button. And you should not be calling place (or pack or grid) in-line with creating the widget. They should be separate steps.
So, putting that all together, you need to define firstname like this so that firstname is not None:
firstname=Entry(main)
firstname.place(x=30, y=50)
And then you need to define the button like this:
register_button = Button(main,text='REGISTER', command= register)
register_button.place(x=300, y=200)
first of all I'm new to Python and coding overall.
I wanna ask, I'm using IDLE and Tkinter together. I'm making a simple calculator.
def getInput():
i1 = Input1_Box.get()
i2 = Input2_Box.get()
i3 = Input3_Box.get()
calculate = float(i1) * float(i3) - float(i2) * float(i3)
print(calculate)
Here I use define tag getInput to fetch data from Entry widget and use the string(I think so), calculate to put a simple equation to calculate all the data fetch.
But I don't know how to display the result of "calculate" into and Entry widget or display as a text.
To quote Bryan Oakley from this question and BuvinJ from this question:
For an entry widget you have two choices. One, if you have a textvariable associated, you can call set on the textvariable. This will cause any widgets associated with the textvariable to be updated. Second, without a textvariable you can use the insert and delete methods to replace what is in the widget.
Here's an example of the latter:
calculateEntry.delete(0, "end")
calculateEntry.insert(0, calculate)
And for the former:
If you use a "text variable" tk.StringVar(), you can just set() that.
No need to use the Entry delete and insert. Moreover, those functions don't work when the Entry is disabled or readonly! The text variable method, however, does work under those conditions as well.
calculateVar = tk.StringVar()
calculateEntry = tk.Entry( master, textvariable=calculateVar )
calculateVar.set( calculate )
I'm writing a simple code for a GUI using tkinter. My problem is that I want to have a number, printed in the Label named t1, always updated as the sum of the two entries given. Of course I cannot use the .get method on the entries, since I would fix the values when calling the method, but I don't know hot to build a new (always updated) IntVar using other Intvar.
from tkinter import *
window=Tk()
p1_in=StringVar()
p1=Entry(window,textvariable=p1_in)
p2_in=StringVar()
p2=Entry(window,textvariable=p2_in)
t1=Label(window,textvariable=(p1_in+p2_in)) # of course this doesn't work
t1.grid(row=7,column=2)
window.mainloop()
How can I make the label t1 being always updated with the sum of p1_in+p2_in?
I know that they are StringVar, but the output is nicer for my intents this way, plus I don't think this is the main issue
You can use trace method of StringVar. It is called right after the value changes.
from tkinter import *
window=Tk()
def calculate(*args):
if p1_in.get() and p2_in.get(): #checks if both are not empty
try:
ans = int(p1_in.get()) + int(p2_in.get())
t1_out.set(str(ans))
except ValueError:
t1_out.set("Enter integers!")
p1_in=StringVar()
p1=Entry(window,textvariable=p1_in)
p1_in.trace("w", calculate)
p2_in=StringVar()
p2=Entry(window,textvariable=p2_in)
p2_in.trace("w", calculate)
t1_out=StringVar()
t1=Label(window,textvariable=t1_out) #also note that used another variable for output
t1.grid(row=7,column=2)
p1.grid(row=5,column=2)
p2.grid(row=6,column=2)
window.mainloop()
I'm trying to associate a variable with a Tkinter entry widget, in a way that:
Whenever I change the value (the "content") of the entry, mainly by typing something into it, the variable automatically gets assigned the value of what I've typed. Without me having to push a button "Update value " or something like that first.
Whenever the variable gets changed (by some other part of the programm), I want the entry value displayed to be adjusted automatically. I believe that this could work via the textvariable.
I read the example on http://effbot.org/tkinterbook/entry.htm, but it is not exactly helping me for what I have in mind. I have a feeling that there is a way of ensuring the first condition with using entry's "validate". Any ideas?
I think you want something like this. In the example below, I created a variable myvar and assigned it to be textvariable of both a Label and Entry widgets. This way both are coupled and changes in the Entry widget will reflect automatically in Label.
You can also set trace on variables, e.g. to write to stdout.
from tkinter import *
root = Tk()
root.title("MyApp")
myvar = StringVar()
def mywarWritten(*args):
print "mywarWritten",myvar.get()
myvar.trace("w", mywarWritten)
label = Label(root, textvariable=myvar)
label.pack()
text_entry = Entry(root, textvariable=myvar)
text_entry.pack()
root.mainloop()