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.
Related
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))
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.
Every source of documentation I've been able to find for this say that by calling itemconfig without any arguments will return a list of possible attributes that can be edited. I tried to do this with the following code:
import tkinter
from tkinter import *
master = Tk()
w = Canvas(master, width=200, height=100)
w.pack()
print(w.itemconfig('bg'))
...And it only returned an empty dictionary (it throws an error when I put in zero arguments, and no other arguments I could think of have given me results, except for actually using the function as intented)
I find it rather silly that nobody has written down all of the attributes that itemconfig can use (or if they have, I can't find it); being able to actually retrieve attributes would be nice, but far more than that, I'd like a complete list to be written down, since I can't find it anywhere.
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.
After seeing this, PhotoImage not showing up the image associated with it I wondered why omitting the type of option does not throws an error instead of just not showing up the image?
This code does not show the image without throwing any error
import tkinter as tk
root = tk.Tk()
image1 = tk.PhotoImage("ban.gif")
tk.Label(root,image=image1).pack()
tk.Label(root, text="some string here").pack()
root.mainloop()
But this one works fine
import tkinter as tk
root = tk.Tk()
image1 = tk.PhotoImage(file="ban.gif")
tk.Label(root,image=image1).pack()
tk.Label(root, text="some string here").pack()
root.mainloop()
On effbot it doesn't say anything about it so I checked tcl man page for creating photos but still can not find why it behaves like this.
Also, if those two are duplicate ones, let me know so I will delete/close vote this one.
When you specify a function with named arguments in python, those named arguments appear in a specific order. If you do not supply a name when defining these arguments, they are applied in the order that the arguments appear in the function definition.
In the case of PhotoImage, the first keyword argument is for the name of the image, not a path to a file. So, PhotoImage("ban.gif") is the same as doing PhotoImage(name="ban.gif"). It doesn't throw an error because "ban.gif" is a valid name, and there are use cases where you want to create an image without referencing a file.