I need to make a temperature converter for a class through tkinter. All the labels and buttons come up, but my button does not do anything when clicked. I have tried multiple different definitions of the command with no luck.
from tkinter import*
root=Tk()
label=Label(root,text="TEMPERATURE CONVERTER")
label.pack(side=TOP)
entry1=Entry(root)
entry1.place(x=300,y=50)
button1=Button(root,text="Convert")
button1.place(x=300,y=100)
label1=Label(root,text="Temperature in Celsius: ")
label1.place(x=100,y=50)
label2=Label(root,text="Temperature in Fahrenheit: ")
label2.place(x=100,y=150)
label3=Label(root)
label3.place(x=300,y=150)
var1=DoubleVar()
entry1=Entry(root,textvariable=var1)
def click1():
label3.config(str(var1.get)+ 32 * 1.8)
button1.bind("<Button-1>", click1)
You have multiple problems with your function. Are you even looking for the error messages? Because I got several when I ran your code.
Button callbacks are passed a parameter. You weren't looking for one, so you get a TypeError.
"var1.get" is a function. To fetch the value, you have to call the it.
You were multiplying the result of str, instead of multiplying the numbers and converting that.
You have to tell config what thing to change. In your case, that's text.
Your formula for converting C to F is wrong.
This works, assuming you add root.mainloop() at the end.
def click1(e):
label3.config(text=str(var1.get() * 1.8 + 32))
Related
def equalizer(entryblock):
x = entryblock.get()
entryblock.delete(0, tk.END)
entryblock.insert('end', int(x))
so here is a function for my tkinter calculator. I am trying to make a function where it takes the entry box and does the operations and gives the result. For example, if I punch in '1+2+3', I want this function to turn it into 6. Whenever I try this, it gives this error:
ValueError: invalid literal for int() with base 10: '1+2+3'
Could I use the math module to fix this problem?
There are 3 ways to solve this problem as far as I can think:
One is to use eval but then you cannot have the user input the values into the entry, as its not safe.
Next is to implement an AST parser suitably, that way you can use user input via Entry and still be safe from the exploits of eval.
The third way would be change your logic and make the app work like how the calculator in windows works, this way you do not need eval or anything. You will have to keep reference to the last item given and then add(or any operation) with the next entered item. Video reference: Build A Simple Calculator App - Python Tkinter GUI Tutorial #6, there is a previous part but only follow the logical part of the code, the other part is quite naïve.
For the first approach, this should give you a bare example:
from tkinter import * # Note: Better to use import tkinter as tk and make changes needingly
root = Tk()
def write(num):
lbl['text'] += num # Add the user inputted number to the end of current text from label
def calc():
out = eval(lbl['text']) # Get the text and do the operations
lbl['text'] = str(out) # Change the text with the output
texts = '123456789' # Digits to loop through
lbl = Label(root,font=(0,15),justify='left')
lbl.grid(row=0,column=0,columnspan=3)
# To create a 3x3 grid of widgets, starting from 1 because 0th row/column is already taken by the label
for i in range(1,4):
for j in range(1,4):
text = texts[3*(i-1)+(j-1)] # Indexing to get the respective texts
Button(root,text=text,command=lambda num=text: write(num),width=15).grid(row=i,column=j-1)
# Some buttons outside the normal gridding behavior and with different function
Button(root,text='+',command=lambda: write('+'),width=15).grid(row=i+1,column=0)
Button(root,text='0',command=lambda: write('0'),width=15).grid(row=i+1,column=1)
Button(root,text='=',command=calc,width=15).grid(row=i+1,column=2)
Button(root,text='C',command=lambda: lbl.config(text=''),width=15).grid(row=i+2,columnspan=3,sticky='news')
root.mainloop()
You can design/place the widgets the way you want, notice how the function handles the input and user cant input any number as they wish either.
For the second approach, you can refer here for a code from Kevin that implements ast and does calculation and you can take user input as well and integrate tkinter with that function by making a few tweaks.
So to answer your question:
Could I use the math module to fix this problem?
Nothing I can think of from math does what you are looking for.
I had started writing a tkinter program when I stumbled across this problem in my code:
elif (xtimes=="" or xtimes=="Optional") and (t!="" or t!="Optional"):
amount
years=0
while years<t:
principle=principle+((interest/100)*(principle))
years+=1
amount=principle
finallabel=Label(root,text="Your Final Amount will be",amount,"at the end of",years,"years")
finallabel.grid(row=13,column=0)
Under the elif statement, I have calculated amount and I want to show the answer using a label, which gives the error: "positional argument follows keyword argument"
I think that I want to send the variable amount through the text, like in normal python, but the code makes it think like I am passing some parameter called amount which doesn't exist.
Please help.
the only positional argument you need to pass is Label(root).
So if you do Label(text='my text', root) it gives this error.
this works:
import tkinter as tk
root = tk.Tk()
lab = tk.Label(root, text='hi')
lab.pack()
root.mainloop()
this not:
import tkinter as tk
root = tk.Tk()
lab = tk.Label(text='hi',root)
lab.pack()
root.mainloop()
After update.. Let's look on this line of your code here:
finallabel=Label(root,text="Your Final Amount will be",amount,"at the end of",years,"years")
What you did here, was to parse arguments through the interface of the Label class to make an instance of it, with the config of given arguments.
the tkinter Label class knows the arguments that can be found here.
So comparing your Label with the available parameters, you will notice that amount and years arent part of them. The only Posistional argument that the Label class of tkinter is expecting is the master, followed by keyword arguments **options. Read this.
What you trying to do is a string with variables and there are several ways to achieve this. My personal favorite is the f'string.
And with a f'string your code will be look like this:
finallabel=Label(root,text=f'Your Final Amount will be {amount},at the end of {years} years')
Let me know if something isnt clear.
ı am new in tkinter. I want to multpily two inputs box. my codes are below. The problem is when i run it runs as x2*x2 but i want to x2*x1 how can ı fix this code it runs only one box
import tkinter as tk
from functools import partial
from tkinter import *
root=tk.Tk()
root.geometry("900x900+100+200")
root.title("Converter")
root.configure(background="grey")
root.resizable(width=False,height=False)
def call_result15(rL,inputn):
x1=inputn.get()
x2=inputn.get()
h=float(float(x1)*float(x2))
rL.config(text="% f " % h)
return
numberInput=tk.StringVar()
var=tk.StringVar()
input_label=tk.Label(root,text="x1",background="white",foreground="black")
input_entry=tk.Entry(root,textvariable=numberInput)
input_label.grid()
input_entry.grid()
numberInput2=tk.StringVar()
var2=tk.StringVar()
input_label=tk.Label(root,text="x2",background="white",foreground="black")
input_entry=tk.Entry(root,textvariable=numberInput2)
input_label.grid()
input_entry.grid()
rlabel=tk.Label(root,text="h1",background="white",foreground="black")
rlabel.grid()
call_result15=partial(call_result15,rlabel,numberInput2)
result_button.grid()
root.mainloop()
def call_result15(rL,inputn):
x1=inputn.get()
x2=inputn.get()
x1 and x2 are both read from the same supplied inputn parameter...
call_result15=partial(call_result15,rlabel,numberInput2)
which is bound here. So of course we multiply the value from numberInput2 by itself.
You need to write the callback so it accepts (and uses) both inputs, and bind both of them in the partial.
I am trying to make a keylogger using Tkinter, but the binds are not working at all. I think the bind isn't calling the subprogram, but it provides no error so that is just an educated guess.
I started this project 3 days ago and expected it to be done yesterday. But this issue kept on cropping up, I am using python 3.6.1.
Here is what I have already tried
Using lambda
Putting "command =" before the function
Changing "def keypress():" to "def keypress(event)"
Making the bind in a frame
Binding each individual button the keyboard
I have even copied someone's keylogger code and came across the same issue (yes it was python-3.x)
It is made even more frustrating by the number of answers on forums that don't work and the days of googling and looking at the documentation.
import tkinter
from tkinter import *
window = Tk()
window.title("Test")
window.config(bg = "white")
frame = Frame(window, width = 1000, height = 1000)
frame.place(x = 0, y = 0)
def keypress(event):
print("pressed", repr(event.char)) #changed repr to str and also tried deleting it
frame.bind("<Key>", lambda: keypress(event)) #other variations of this line include frame.bind("<key>", keypress), frame.bind("<key>", keypress()), frame.bind("<key>", keypress(event))
The expected input is just
>>> Pressed [the key that I pressed]
but the output that you actually get is...
>>>
Nothing.
Any and all help would be wonderful, thanks in advance!
You don't need lambda if you aren't passing any arguments.
frame.bind("<Key>", keypress)
Also, keybindings only work if the widget has the keyboard focus. By default a frame does not get the keyboard focus. If you want to bind to a frame, you must force it to have keyboard focus:
frame.focus_set()
New to GUI. Not quite getting there. I used page and get can get buttons to do something (click on a button and get a response). With Combobox, I can't pass a value. Searched here, tried many things, watched a few hours of youtube tutorials.
What am I doing wrong below? This is the code page generates (basically) then I added what I think I need to do to use the Combobox.
I am just trying to have 1,2,3 in a combo box and print out the value that is chosen. Once I figure that out I think I can actually make a simple GUI that passes variables I can then program what I want to do with these variables being selected.
class New_Toplevel_1:
def __init__(self, top):
self.box_value = StringVar()
self.TCombobox1 = ttk.Combobox(textvariable=self.box_value)
self.TCombobox1.place(relx=0.52, rely=0.38, relheight=0.05, relwidth=0.24)
self.TCombobox1['values']=['1','2','3']
self.TCombobox1.configure(background="#ffff80")
self.TCombobox1.configure(takefocus="")
self.TCombobox1.bind('<<ComboboxSelected>>',func=select_combobox)
def select_combobox(self,top=None):
print 'test combo ' # this prints so the bind works
self.value_of_combo = self.ttk.Combobox.get() # this plus many other attempts does not work
It's hard to know what you're actually asking about, since there is more than one thing wrong with your code. Since you say the print statement is working, I'm assuming the only problem you have with your actual code is with the last line.
To get the value of the combobox, get the value of the associated variable:
self.value_of_combo = self.box_value.get()
Here's a working version where I fixed the other things that were wrong with the program:
from tkinter import *
from tkinter import ttk
class New_Toplevel_1:
def __init__(self, top):
self.box_value = StringVar()
self.TCombobox1 = ttk.Combobox(textvariable=self.box_value)
self.TCombobox1.place(relx=0.52, rely=0.38, relheight=0.05, relwidth=0.24)
self.TCombobox1['values']=['1','2','3']
self.TCombobox1.configure(background="#ffff80")
self.TCombobox1.configure(takefocus="")
self.TCombobox1.bind('<<ComboboxSelected>>',func=self.select_combobox)
def select_combobox(self,top=None):
print('test combo ') # this prints so the bind works
self.value_of_combo = self.box_value.get()
print(self.value_of_combo)
root = Tk()
top = New_Toplevel_1(root)
root.mainloop()
Note: I strongly advise you not to start with place. You should try to learn pack and place first. I know place seems easier, but to get the most responsive and flexible GUI you should leverage the power of pack and grid.