enter specific widget with numpad tkinter - python

Hello I am preparing a GUI for a project, but unfortunately I cant enter a specific widget with my numpad at once. If I click a number on my touchscreen numpad, the digit appears in both widgets. How can I change it, that I can only enter a digit in a widget at once? I wanted to try it with the focus method but it didnt really work out...
Thanks for your help.
Here is my code:
# globally declare the expression variable
expression = ""
# Function to update expression
# in the text entry box
def press(num):
# point out the global expression variable
global expression
# concatenation of string
expression = expression + str(num)
# update the expression by using set method
equation1.set(expression)
equation2.set(expression)
# Function to clear the contents
# of text entry box
def clear():
global expression
expression = ""
equation1.set("")
equation2.set("")
#create GUI
# Driver code
if __name__ == "__main__":
# create a GUI window
gui = Tk()
gui.title("GUI")
equation1 = StringVar()
equation2 = StringVar()
equation1.set("")
equation2.set("")
#Label 1
label1 = tkinter.Label(text ="Pumpenhöhe 1 [cm]")
label1.grid (row =0 , column =0 , padx = xdis , pady = ydis )
#Eingabefeld 1 definieren
eingabe1 = tkinter.Entry(gui, textvariable=equation1, width=4, bg ='#ffffff')
eingabe1.grid(row=0, column=1, padx=xdis, pady = ydis)
#Label 2
label2 = tkinter.Label (text ="Pumpenhöhe 2 [cm]")
label2.grid(row=1,column =0 , padx = xdis ,pady = ydis)
#Eingabefeld 2
eingabe2 = tkinter.Entry(gui, textvariable=equation2, width=4, bg ='#ffffff')
eingabe2.grid(row=1, column=1, padx=xdis, pady = ydis)
#button obj on framework to send values
set_setpoints = tkinter.Button(text ="Send", command = set_setpoints)
set_setpoints.grid(row=2, column=2, padx= xdis, pady = ydis)
#create exit button
ex_bt = tkinter.Button(gui, text='Exit', command=gui.destroy)
ex_bt.grid(row=7, column=2, sticky=tkinter.W, padx=xdis, pady=ydis)
#buttons for numpad
button1 = Button(gui, text=' 1 ',
command=lambda: press(1), height=1, width=7)
button1.grid(row=3, column=0)
button2 = Button(gui, text=' 2 ',
command=lambda: press(2), height=1, width=7)
button2.grid(row=3, column=1)
button3 = Button(gui, text=' 3 ',
command=lambda: press(3), height=1, width=7)
button3.grid(row=3, column=2)
button4 = Button(gui, text=' 4 ',
command=lambda: press(4), height=1, width=7)
button4.grid(row=4, column=0)
button5 = Button(gui, text=' 5 ',
command=lambda: press(5), height=1, width=7)
button5.grid(row=4, column=1)
button6 = Button(gui, text=' 6 ',
command=lambda: press(6), height=1, width=7)
button6.grid(row=4, column=2)
button7 = Button(gui, text=' 7 ',
command=lambda: press(7), height=1, width=7)
button7.grid(row=5, column=0)
button8 = Button(gui, text=' 8 ',
command=lambda: press(8), height=1, width=7)
button8.grid(row=5, column=1)
button9 = Button(gui, text=' 9 ',
command=lambda: press(9), height=1, width=7)
button9.grid(row=5, column=2)
button0 = Button(gui, text=' 0 ',
command=lambda: press(0), height=1, width=7)
button0.grid(row=6, column=0)
clear = Button(gui, text='Clear',
command=clear, height=1, width=7)
clear.grid(row=6, column='1')
Decimal= Button(gui, text='.',
command=lambda: press('.'), height=1, width=7)
Decimal.grid(row=6, column=2)
gui.mainloop()

I could solve it like this:
#add text inside widget
def set_text(text):
widget = gui.focus_get()
if widget in [entry1, entry2]:
widget.insert("insert", text)
def backspace():#Delete one digit at a time into perticular entry field
pass
def clear():#Clear text in perticular entry field
entry1.delete(0,END)
entry2.delete(0,END)
#create GUI
# Driver code
if __name__ == "__main__":
# create a GUI window
gui = Tk()
gui.title("GUI")
#Label 1
label1 = tkinter.Label(text ="Pumpenhöhe 1 [cm]")
label1.grid (row =0 , column =0 , padx = xdis , pady = ydis )
#Eingabefeld 1 definieren
entry1 = tkinter.Entry(gui, textvariable=StringVar(), width=4, bg ='#ffffff')
entry1.grid(row=0, column=1, padx=xdis, pady = ydis)
#Label 2
label2 = tkinter.Label (text ="Pumpenhöhe 2 [cm]")
label2.grid(row=1,column =0 , padx = xdis ,pady = ydis)
#Eingabefeld 2
entry2 = tkinter.Entry(gui, textvariable=StringVar(), width=4, bg ='#ffffff')
entry2.grid(row=1, column=1, padx=xdis, pady = ydis)
#create exit button
ex_bt = tkinter.Button(gui, text='Exit', command=gui.destroy)
ex_bt.grid(row=4, column=2, sticky=tkinter.W, padx=xdis, pady=ydis)
#button obj to start thread
#start_thread = tkinter.Button(text ="start thread(main loop)", command=start_thread)
#start_thread.grid(row=2, column=1, padx=xdis, pady = ydis)
#button obj to stop thread
#stop_thread = tkinter.Button(text ="Stop", command=stop_thread)
#stop_thread.grid(row=2, column=3, padx=xdis, pady = ydis)
#button obj on framework to send values
set_setpoints = tkinter.Button(text ="Send", command = set_setpoints)
set_setpoints.grid(row=2, column=2, padx= xdis, pady = ydis)
#buttons for numpad
tkinter.Button(gui, text="7", command=lambda: set_text("7"),height=1, width=7).grid(row=5, column=0)
tkinter.Button(gui, text="8", command=lambda: set_text("8"),height=1, width=7).grid(row=5, column=1)
tkinter.Button(gui, text="9", command=lambda: set_text("9"),height=1, width=7).grid(row=5, column=2)
tkinter.Button(gui, text="4", command=lambda: set_text("4"),height=1, width=7).grid(row=6, column=0)
tkinter.Button(gui, text="5", command=lambda: set_text("5"),height=1, width=7).grid(row=6, column=1)
tkinter.Button(gui, text="6", command=lambda: set_text("6"),height=1, width=7).grid(row=6, column=2)
tkinter.Button(gui, text="1", command=lambda: set_text("1"),height=1, width=7).grid(row=7, column=0)
tkinter.Button(gui, text="2", command=lambda: set_text("2"),height=1, width=7).grid(row=7, column=1)
tkinter.Button(gui, text="3", command=lambda: set_text("3"),height=1, width=7).grid(row=7, column=2)
tkinter.Button(gui, text="0", command=lambda: set_text("0"),height=1, width=7).grid(row=7, column=1)
backspace = tkinter.Button(gui, text='<-', command = lambda:backspace())
backspace.grid(row=3,column=1, padx=xdis, pady=ydis)
clear_btn = Button(gui, text='C', command = lambda:clear())
clear_btn.grid(row=3,column=2, padx=xdis, pady=ydis)
gui.mainloop()

Related

Non-repetitive way of passing a large set of parameters as a single object?

I'm learning how to use tkinter, and some example code to create a bunch of buttons for a calculator is used. It seems very bulky and repetitive, so I was wondering if there was a way to assign some or all of the parameters to a single object and just modify and pass that each time?
button1 = Button(gui, text=' 1 ', fg='black', bg='red',
command=lambda: press(1), height=1, width=7)
button1.grid(row=2, column=0)
button2 = Button(gui, text=' 2 ', fg='black', bg='red',
command=lambda: press(2), height=1, width=7)
button2.grid(row=2, column=1)
button3 = Button(gui, text=' 3 ', fg='black', bg='red',
command=lambda: press(3), height=1, width=7)
button3.grid(row=2, column=2)
button4 = Button(gui, text=' 4 ', fg='black', bg='red',
command=lambda: press(4), height=1, width=7)
button4.grid(row=3, column=0)
button5 = Button(gui, text=' 5 ', fg='black', bg='red',
command=lambda: press(5), height=1, width=7)
button5.grid(row=3, column=1)
button6 = Button(gui, text=' 6 ', fg='black', bg='red',
command=lambda: press(6), height=1, width=7)
button6.grid(row=3, column=2)
button7 = Button(gui, text=' 7 ', fg='black', bg='red',
command=lambda: press(7), height=1, width=7)
button7.grid(row=4, column=0)
button8 = Button(gui, text=' 8 ', fg='black', bg='red',
command=lambda: press(8), height=1, width=7)
button8.grid(row=4, column=1)
button9 = Button(gui, text=' 9 ', fg='black', bg='red',
command=lambda: press(9), height=1, width=7)
button9.grid(row=4, column=2)
button0 = Button(gui, text=' 0 ', fg='black', bg='red',
command=lambda: press(0), height=1, width=7)
button0.grid(row=5, column=0)
In order to to keep your code DRY and avoid repeating yourself— which is essentially what you're asking I think — you need to create the Buttons in a loop. However dynamically creating Python variables is generally not a good idea, so they should instead be put in some kind of container, like a list, rather than trying to give each of them individual names.
I'm not sure exactly if that is what you meant by "assign some or all of the parameters to a single object" because tkinter it could also mean grouping the widget together in some kind of GUI container. tkinter has something called a Frame widget for that sort of thing which allows them to be treated as a group.
The sample code below does both — it creates a buttons list and a button_frame:
import tkinter as tk # PEP 8 suggests avoiding `import *`.
NUM_BUTTONS = 10
BUTTONS_PER_ROW = 3
gui = tk.Tk()
def press(digit):
gui.bell()
button_frame = tk.Frame(gui) # Parent frame to hold all button widgets.
button_frame.pack()
buttons = [] # List of button widgets.
start_row = 2
for i in range(NUM_BUTTONS):
row, col = divmod(i, BUTTONS_PER_ROW)
value = (i+1) % NUM_BUTTONS
button = tk.Button(button_frame, text=f'{value}', fg='black', bg='red',
command=lambda digit=value: press(digit), height=1, width=7)
button.grid(row=start_row+row, column=col)
buttons.append(button) # Add widget to list.
gui.mainloop()
Here's the on-screen result:

it seems like i can't open a frame in python

i want to open the menu_frame by clicking the login_button but the frame won't come up and there are no error messages showing up. its my first time and im so lost
ive tried to google how to fix this problem but from what ive read, it seems to me that there are no errors or any reason for this code to not function properly. please help :(
from tkinter import *
window = Tk()
window.title("EL TALLO")
window.geometry("700x490")
window.config(background="#FFF8E5")
#회원가입
def register_frame():
register_frame = Frame(
window,
bd=2,
bg='#FFF8E5',
relief=SOLID,
padx=10,
pady=10
)
Label(
register_frame,
text="ID입력",
bg='#CCCCCC',
).grid(row=0, column=0, sticky=W, pady=10)
Label(
register_frame,
text="비밀번호 입력",
bg='#CCCCCC',
).grid(row=5, column=0, sticky=W, pady=10)
newlyset_id = Entry(
register_frame
)
newlyset_pw = Entry(
register_frame,
show='*'
)
register_btn = Button(
register_frame,
width=15,
text='회원가입',
relief=SOLID,
cursor='hand2',
command=register_frame.destroy
)
newlyset_id.grid(row=0, column=1, pady=10, padx=20)
newlyset_pw.grid(row=5, column=1, pady=10, padx=20)
register_btn.grid(row=7, column=1, pady=10, padx=20)
register_frame.pack()
register_frame.place(x=220, y=150)
def new_id(): #new_id에 newlyset_id에 입력한 값을 저장
new_id = newlyset_id.get()
def new_pw(): #new_pw에 newlyset_pw에 입력한 값을 저장
new_pw = newlyset_pw.get()
#메뉴화면
def menu_frame():
menu_frame = Frame(
window,
bd=2,
bg='#FFF8E5',
relief=SOLID,
padx=10,
pady=10
)
label1 = Label(menu_frame, text = "EL TALLO", bg="lightgreen",width=10, height=1, font=(15))
label1.pack()
btn1 = Button(menu_frame, text = "play game", bg="gray", width=15, height=1)
btn1.pack()
btn2 = Button(menu_frame, text = "How to play", bg="gray", width=15, height=1)
btn2.pack()
btn3 = Button(menu_frame, text = "Settings", bg="gray", width=15, height=1)
btn3.pack()
def btncmd():
print("게임이 종료되었습니다")
btn4 = Button(menu_frame, text = "END GAME", command=btncmd, bg="lightgreen", width=15, height=1)
btn4.pack()
label1.place(x=50, y=50)
btn1.place(x=50, y=100)
btn2.place(x=50, y=150)
btn3.place(x=50, y=200)
btn4.place(x=50, y=250)
#로그인
Label(
window,
text="아이디 입력",
bg='#CCCCCC',
).place(x=230, y=170)
id_tf = Entry(
window,
).place(x=330, y=170)
def id(): #id에 id_tf에 입력한 값을 저장
id = id_tf.get()
Label(
window,
text="비밀번호 입력",
bg='#CCCCCC',
).place(x=230, y=220)
pw_tf = Entry(
window,
).place(x=330, y=220)
def pw(): #pw에 pw_tf에 입력한 값을 저장
pw = pw_tf.get()
#회원가입 버튼
registerbutton = Button(
window,
width=15,
text="회원가입",
bg="#CCCCCC",
cursor='hand2',
command=register_frame
)
registerbutton.place(x=360, y=270)
#로그인 버튼
loginbutton = Button(
window,
width=15,
text="로그인",
bg="#CCCCCC",
cursor='hand2',
command=menu_frame
)
loginbutton.place(x=230, y=270)
window.mainloop()
You didn't pack the menu_frame and the indentation of def btncmd() was wrong.
That is:
btn3 = Button(menu_frame, text = "Settings", bg="gray", width=15, height=1)
btn3.pack()
menu_frame.pack()
def btncmd():
print("게임이 종료되었습니다")

TypeError: clickButton() missing 1 required positional argument: 'number'

I'm making a calculator in Python using Tkinter, and I'm getting an error:
TypeError: clickButton() missing 1 required positional argument: 'number'
Here's the code I've written:
from tkinter import *
root = Tk()
root.title("Calculator")
ent = Entry(root, width=35, borderwidth=5)
ent.grid(row=0, column=0, columnspan=3, padx=10, pady=10)
def clickButton(number):
current = ent.get()
ent.delete(0, END)
ent.insert(0, str(current) + str(number))
def clearButton():
ent.delete(0, END)
def button_add():
first_number = ent.get()
global f_num
global math
math = "addition"
f_num = int(first_number)
ent.delete(0, END)
def equalButton():
secondNum = ent.get()
ent.delete(0,END)
ent.insert(0, f_num + int(secondNum))
# this defines the buttons
button1 = Button(root, text="1", padx=40, pady=20, command=lambda: clickButton(1)) # the first button of the calculator
button2 = Button(root, text="2", padx=40, pady=20, command=lambda: clickButton(2)) # the second button of the calculator
button3 = Button(root, text="3", padx=40, pady=20, command=lambda: clickButton(3)) # the third button of the calculator
button4 = Button(root, text="4", padx=40, pady=20, command=lambda: clickButton(4)) # the fourth button of the calculator
button5 = Button(root, text="5", padx=40, pady=20, command=lambda: clickButton(5)) # the fifth button of the calculator
button6 = Button(root, text="6", padx=40, pady=20, command=lambda: clickButton(6)) # the sixth button of the calculator
button7 = Button(root, text="7", padx=40, pady=20, command=lambda: clickButton(7)) # the seventh button of the calculator
button8 = Button(root, text="8", padx=40, pady=20, command=lambda: clickButton(8)) # the eighth button of the calculator
button9 = Button(root, text="9", padx=40, pady=20, command=lambda: clickButton(9)) # the ninth button of the calculator
button0 = Button(root, text="0", padx=40, pady=20, command=lambda: clickButton(0)) # the tenth button of the calculator
button_addition = Button(root, text="+", padx=40, pady=20, command=clickButton) # addition button
button_equalSign = Button(root, text="=", padx=91, pady=20, command=equalButton) # button for the equal sign
button_clr = Button(root, text="C", padx=91, pady=20, command=lambda: clearButton()) #button for clearing whatever is written
# this puts the buttons on the screen
#row 3
button1.grid(row=3, column=0)
button2.grid(row=3, column=1)
button3.grid(row=3, column=2)
# row 2
button4.grid(row=2, column=0)
button5.grid(row=2, column=1)
button6.grid(row=2, column=2)
# row 1
button7.grid(row=1, column=0)
button8.grid(row=1, column=1)
button9.grid(row=1, column=2)
# sign buttons
button0.grid(row=4, column=0)
button_clr.grid(row=4, column=1, columnspan=2)
button_addition.grid(row=5, column=0)
button_equalSign.grid(row=5, column=1, columnspan=2)
root.mainloop()
I've been trying to fix this error for many hours.
P.S. I don't actually know which line the error is on, because it's saying that the error is on line 1705, even though the code is only 101 lines
In this line:
button_addition = Button(root, text="+", padx=40, pady=20, command=clickButton) # addition button
You are calling clickButton with no arguments, and in your function, you are requiring a number. You should use lambda, as you did with the other numbers (lines above), or call another function. By the look of your code, it should be button_add.
I fixed it this way:
myButtonSum = Button(root, text="+", padx=10, pady=5, command=lambda: buttonAdd("+"))

Simple Calculator with Tkinter GUI

I was wondering if you can help me with my Python coding if you have a chance. I am a complete noob at Python so I am trying to learn the basics for my class (and our teacher doesn't teach well at all). We are currently working on a tkinter GUI.
I am currently tasked with coding a pretty simple calculator for my class that involves with all numbers 0 - 9, square root, square root of addition of squares of two given values (sqrt(A2 + B2)), sin, cos, and tan) function as well as lastly sin-1, cos-1, and tan-1.
Now, I have completed the majority of this task as it can be seen here in the pastebin link below:
However, the only thing I can't figure out for the life of me is being able to have my "INV" button working in the sense so that when I would click the button INV, it would replace the three trig functions buttons on the calculator (sin, cos, tan) and replace it with inverse buttons(sin-1, cos-1, tan-1). Then, once I completed calculating said inverse trig function, the inverse buttons(sin-1, cos-1, tan-1) would then be replaced back again to normal trig (sin, cos, tan).
I am able to toggle between the trig and inverse trigs. However, after toggling the INV button twice, it stops calculating trig and inverse trig numbers after that (though continues to toggle just fine).
Is there any way I could make that function loop infinitely, so it calculated every time I toggle or something along the lines of that? I am very stuck lol.
from tkinter import *
import tkinter as tk
import math
expression = ""
inverted = False
def press(num):
global expression
expression = expression + str(num)
equation.set(expression)
def equalpress():
try:
global expression
total = eval(expression)
equation.set(total)
expression = str(total)
except:
equation.set(" Error ")
expression = ""
def clear():
global expression
expression = ""
equation.set("")
return
def sqrt():
global expression
expression = math.sqrt(float(expression))
equation.set(float(expression))
expression = str(expression)
def sin():
global expression
expression = float(expression)
expression = round(math.sin(math.radians(expression)), 5)
equation.set(float(expression))
expression = str(expression)
def cos():
global expression
expression = float(expression)
expression = round(math.cos(math.radians(expression)), 5)
equation.set(float(expression))
expression = str(expression)
def tan():
global expression
expression = float(expression)
expression = round(math.tan(math.radians(expression)), 5)
equation.set(float(expression))
expression = str(expression)
def asin():
global expression
expression = float(expression)
expression = round((math.asin(expression)) * (180 / math.pi), 3)
equation.set(float(expression))
expression = str(expression)
def acos():
global expression
expression = float(expression)
expression = round((math.acos(expression)) * (180 / math.pi), 3)
equation.set(float(expression))
expression = str(expression)
def atan():
global expression
expression = float(expression)
expression = round((math.atan(expression)) * (180 / math.pi), 3)
equation.set(float(expression))
expression = str(expression)
def retrieve_input():
try:
global expression
inputValue1 = InputA.get()
inputValue2 = InputB.get()
inputValue1 = float(inputValue1)
inputValue2 = float(inputValue2)
expression = float(math.sqrt(inputValue1 * inputValue1 + inputValue2 * inputValue2))
equation.set(float(expression))
expression = str(expression)
except:
equation.set(" Error ")
expression = ""
def inv():
global inverted
inverted = not inverted
if __name__ == "__main__":
gui = Tk()
gui.configure(background="light blue")
gui.title("Calculator")
gui.geometry("500x220")
equation = StringVar()
A = StringVar()
B = StringVar()
expression_field = Entry(gui, textvariable=equation)
expression_field.grid(columnspan=45, ipadx=200)
equation.set('Enter Your Expression')
lbl1 = Label(gui, text="Enter A value:", font=("Arial Bold", 10),
bg="light blue")
lbl1.grid(column=0, row=13, sticky=W)
InputA = Entry(gui, width=12, textvariable=A)
InputA.grid(column=1, row=13)
lbl2 = Label(gui, text="Enter B value:", font=("Arial Bold", 10),
bg="light blue")
lbl2.grid(column=0, row=14, sticky=W)
InputB = Entry(gui, width=12, textvariable=B)
InputB.grid(column=1, row=14)
buttonab = Button(gui, text=' √(A^2 + B^2) ', fg='black', bg='white',
command=lambda: retrieve_input(), height=1,width=11)
buttonab.grid(row=15, column=0, sticky=W + E)
button1 = Button(gui, text=' 1 ', fg='black', bg='pink',
command=lambda: press(1), height=1, width=7)
button1.grid(row=4, column=0)
button2 = Button(gui, text=' 2 ', fg='black', bg='pink',
command=lambda: press(2), height=1, width=7)
button2.grid(row=4, column=1)
button3 = Button(gui, text=' 3 ', fg='black', bg='pink',
command=lambda:
press(3), height=1, width=7)
button3.grid(row=4, column=2)
button4 = Button(gui, text=' 4 ', fg='black', bg='pink',
command=lambda: press(4), height=1, width=7)
button4.grid(row=3, column=0)
button5 = Button(gui, text=' 5 ', fg='black', bg='pink',
command=lambda: press(5), height=1, width=7)
button5.grid(row=3, column=1)
button6 = Button(gui, text=' 6 ', fg='black', bg='pink',
command=lambda: press(6), height=1, width=7)
button6.grid(row=3, column=2)
button7 = Button(gui, text=' 7 ', fg='black', bg='pink',
command=lambda: press(7), height=1, width=7)
button7.grid(row=2, column=0)
button8 = Button(gui, text=' 8 ', fg='black', bg='pink',
command=lambda: press(8), height=1, width=7)
button8.grid(row=2, column=1)
button9 = Button(gui, text=' 9 ', fg='black', bg='pink',
command=lambda: press(9), height=1, width=7)
button9.grid(row=2, column=2)
button0 = Button(gui, text=' 0 ', fg='black', bg='pink',
command=lambda: press(0), height=1, width=7)
button0.grid(row=5, column=1)
plus = Button(gui, text=' + ', fg='black', bg='yellow',
command=lambda: press("+"), height=1, width=7)
plus.grid(row=2, column=3)
minus = Button(gui, text=' - ', fg='black', bg='yellow',
command=lambda:
press("-"), height=1, width=7)
minus.grid(row=3, column=3)
multiply = Button(gui, text=' * ', fg='black', bg='yellow',
command=lambda: press("*"), height=1, width=7)
multiply.grid(row=4, column=3)
divide = Button(gui, text=' / ', fg='black', bg='yellow',
command=lambda: press("/"), height=1, width=7)
divide.grid(row=5, column=3)
equal = Button(gui, text=' = ', fg='black', bg='red',
command=equalpress, height=1, width=7)
equal.grid(row=5, column=2)
clear = Button(gui, text='Clear', fg='black', bg='red', command=clear,
height=1, width=7)
clear.grid(row=2, column=6)
sqrt = Button(gui, text=' √ ', fg='black', bg='yellow', command=sqrt,
height=1, width=7)
sqrt.grid(row=3, column=6)
dec = Button(gui, text=' . ', fg='black', bg='orange', command=lambda:
press("."), height=1, width=7)
dec.grid(row=5, column=0)
sin = Button(gui, text='sin', fg='black', bg='light green',
command=sin, height=1, width=7)
sin.grid(row=2, column=4)
cos = Button(gui, text='cos', fg='black', bg='light green',
command=cos, height=1, width=7)
cos.grid(row=3, column=4)
tan = Button(gui, text='tan', fg='black', bg='light green',
command=tan, height=1, width=7)
tan.grid(row=4, column=4)
inv = Button(gui, text='INV', fg='black', bg='light green',
command=inv, height=1, width=7)
inv.grid(row=6, column=4)
if not inverted:
sin = Button(gui, text='sin', fg='black', bg='light green',
command=sin,
height=1, width=7)
sin.grid(row=2, column=4)
cos = Button(gui, text='cos', fg='black', bg='light green',
command=cos,
height=1, width=7)
cos.grid(row=3, column=4)
tan = Button(gui, text='tan', fg='black', bg='light green',
command=tan,
height=1, width=7)
tan.grid(row=4, column=4)
else:
sin = Button(gui, text='sin^-1', fg='black', bg='light green',
command=asin, height=1, width=7)
sin.grid(row=2, column=4)
cos = Button(gui, text='cos-1', fg='black', bg='light green',
command=acos, height=1, width=7)
cos.grid(row=3, column=4)
tan = Button(gui, text='tan-1', fg='black', bg='light green',
command=atan, height=1, width=7)
tan.grid(row=4, column=4)
gui.mainloop()
you have a little bit of work to do.
Currently, when you click your INV-Button youre replacing your "sin" Button with a "global sin" Button. There is no Crash but TK isnt working properly anymore and struggles with the command parameter. I suggest you create a guiloop which handles all your button designs which is permanently running in the _main_loop.
Then you need to change your Inv-function just to
def inv():
global inverted
inverted = not inverted
after that design your gui-loop like this:
if not inverted:
sin = Button(gui, text='sin', fg='black', bg='light green', command=sin, height=1, width=7)
sin.grid(row=2, column=4)
else:
sin = Button(gui, text='sin^-1', fg='black', bg='light green', command=asin, height=1, width=7)
sin.grid(row=2, column=4)
I just tried it with one button and it worked.
For further gui-programming i recommend using PyQT5. Even it's first not very intuitive i find this more stable and powerful.

Python tkinter, clearing an Entry widget from a class

This is the class I'm calling and the function from a different file
class CalcFunc:
def clearScreen(self):
self.log("CLEAR (CE)")
ent.delete(0, END)
This is the Entry Box
ent = Entry(root, textvariable=clc.getBtn, justify=RIGHT, font=10, relief=RIDGE, bd=2, width=15)
ent.grid(row=0, columnspan=3, pady=10)
This is the button I'm clicking to clear the Entry Box
buttonCC = Button(root, text="CLEAR (CE)", height=1, width=20, bg='orange', command=clc.clearScreen)
I'm not sure what the syntax is to be able to to clear an Entry widget from a class basically. That code worked when I had it in the same file but my project requires it to be in a separate file. It's a class project for a calculator and the "clear" button clears the Entry widget. I can post my entire code if that helps. Thank you.
----EDIT----
My Class
import time
class CalcFunc:
def log(self, val):
myFile = open(r".\log.dat", "a")
myFile.write("%s\n" % val)
myFile.close()
def onScreen(self, iVal):
self.log(iVal)
currentTxt = self.getBtn.get()
updateEnt = self.getBtn.set(currentTxt + iVal)
def clearScreen(self):
self.log("CLEAR (CE)")
ent.delete(0, END)
def evaL(self):
self.log("=")
self.getBtn.set(str(eval(self.getBtn.get())))
self.log(self.getBtn.get())
def logLbl(self):
myFile = open(r".\log.dat", "a")
myFile.write("\n==================================\n")
myFile.write("Date: " + str(time.strftime("%m/%d/%Y")) + " -- Time: " + str(time.strftime("%I:%M:%S")))
myFile.write("\n==================================\n")
myFile.close()
My Program
from tkinter import *
import time
import clcClass
root = Tk()
root.title('skClc v1')
clc = clcClass.CalcFunc()
clc.logLbl()
clc.getBtn = StringVar()
ent = Entry(root, textvariable=clc.getBtn, justify=RIGHT, font=10, relief=RIDGE, bd=2, width=15)
ent.grid(row=0, columnspan=3, pady=10)
button1 = Button(root, text="1", height=1, width=5, bg='light blue', command=lambda:clc.onScreen('1'))
button2 = Button(root, text="2", height=1, width=5, bg='light blue', command=lambda:clc.onScreen('2'))
button3 = Button(root, text="3", height=1, width=5, bg='light blue', command=lambda:clc.onScreen('3'))
button4 = Button(root, text="4", height=1, width=5, bg='light blue', command=lambda:clc.onScreen('4'))
button5 = Button(root, text="5", height=1, width=5, bg='light blue', command=lambda:clc.onScreen('5'))
button6 = Button(root, text="6", height=1, width=5, bg='light blue', command=lambda:clc.onScreen('6'))
button7 = Button(root, text="7", height=1, width=5, bg='light blue', command=lambda:clc.onScreen('7'))
button8 = Button(root, text="8", height=1, width=5, bg='light blue', command=lambda:clc.onScreen('8'))
button9 = Button(root, text="9", height=1, width=5, bg='light blue', command=lambda:clc.onScreen('9'))
button0 = Button(root, text="0", height=1, width=5, bg='light blue', command=lambda:onScreen('0'))
buttonP = Button(root, text="+", height=1, width=5, bg='gray', command=lambda:clc.onScreen('+'))
buttonM = Button(root, text="-", height=1, width=5, bg='gray', command=lambda:clc.onScreen('-'))
buttonMM = Button(root, text="x", height=1, width=5, bg='gray', command=lambda:clc.onScreen('*'))
buttonDD = Button(root, text="÷", height=1, width=5, bg='gray', command=lambda:clc.onScreen('/'))
buttonEE = Button(root, text="=", height=1, width=5, bg='light green', command=clc.evaL)
buttonCC = Button(root, text="CLEAR (CE)", height=1, width=20, bg='orange', command=clc.clearScreen)
button1.grid(row=1, column=0, pady=5)
button2.grid(row=1, column=1, pady=5)
button3.grid(row=1, column=2, pady=5)
button4.grid(row=2, column=0, pady=5)
button5.grid(row=2, column=1, pady=5)
button6.grid(row=2, column=2, pady=5)
button7.grid(row=3, column=0, pady=5)
button8.grid(row=3, column=1, pady=5)
button9.grid(row=3, column=2, pady=5)
button0.grid(row=4, column=0, pady=5)
buttonP.grid(row=4, column=1, pady=5)
buttonM.grid(row=4, column=2, pady=5)
buttonEE.grid(row=5, column=0, pady=5)
buttonDD.grid(row=5, column=1, pady=5)
buttonMM.grid(row=5, column=2, pady=5)
buttonCC.grid(row=6, column=0, pady=5, columnspan=3)
root.maxsize(140,245);
root.minsize(140,245);
root.mainloop()
ent = Entry(root, ....)
clc = clcClass.CalcFunc(ent)
class CalcFunc:
def __init__(self, entry):
self.entry = entry
def clearScreen(self):
self.log("CLEAR (CE)")
self.entry.delete(0, END)
Here's an abbreviated example:
#my_entry.py
from tkinter import END
import time
class EntryWithLogger:
def __init__(self, entry):
self.entry = entry
def log(self, val):
with open("log.dat", "a") as my_file: #Automatically closes the file--even if an exception occurs, which is not the case with my_file.close().
my_file.write("%s\n" % val)
def onScreen(self, i_val):
self.log(i_val)
self.entry.insert(END, i_val)
def clearScreen(self):
self.log("CLEAR (CE)")
self.entry.delete(0, END)
Note that I didn't use a StringVar(), which doesn't appear to be necessary. If you need it, you can always pass it as an argument to __init__(), then store it on self.
import my_entry as me
import tkinter as tk
root = tk.Tk()
root.title("Calculator")
root.geometry("+100+50") #("300x500+200+10") dimension, position
entry = tk.Entry(root, justify=tk.RIGHT, font=10, relief=tk.RIDGE, bd=2, width=15)
entry.grid(row=0, columnspan=3, pady=10)
entry_with_logger = me.EntryWithLogger(entry)
#Create the buttons in a loop:
for i in range(10):
row_num, col_num = divmod(i, 3) #divmod(7, 2) => (3, 1), divmod(0, 3) => (0, 0), divmod(4, 3) => (1, 1)
row_num += 1
button_text = str(i)
tk.Button(root, text=button_text,
height=1,
width=5,
bg='light blue',
command=lambda x=button_text: entry_with_logger.onScreen(x)
).grid(row=row_num, column=col_num, pady=5)
#Put the clear button at the bottom of the grid:
tk.Button(root, text="CLEAR (CE)",
height=1,
width=20,
bg='orange',
command=entry_with_logger.clearScreen
).grid(row=row_num+1, columnspan=3) #columnspan tells grid() to use 3 cells for the button,
#and the button will be centered by default.
root.mainloop()
Or, you could do it like this:
#my_entry.py
from tkinter import Entry, END
import time
class EntryWithLogger(Entry):
#Because __init__() is not implemented, the parent class's __init__() gets
#called, so you create an EntryWithLogger just like you would an Entry.
def log(self, val):
with open("log.dat", "a") as my_file: #Automatically closes the file--even if there is an exception, which is not the case with my_file.close().
my_file.write("%s\n" % val)
def onScreen(self, i_val):
self.log(i_val)
self.insert(END, i_val)
def clearScreen(self):
self.log("CLEAR (CE)")
self.delete(0, END)
import my_entry as me
import tkinter as tk
root = tk.Tk()
root.title("Calculator")
root.geometry("+100+50") #("300x500+200+10") dimension, position
entry = me.EntryWithLogger(root, justify=tk.RIGHT, font=10, relief=tk.RIDGE, bd=2, width=15)
entry.grid(row=0, columnspan=3, pady=10)
#Create the buttons in a loop:
for i in range(10):
row_num, col_num = divmod(i, 3) #divmod(7, 2) => (3, 1), divmod(0, 3) => (0, 0), divmod(4, 3) => (1, 1)
row_num += 1
button_text = str(i)
tk.Button(root, text=button_text,
height=1,
width=5,
bg='LightBlue',
command=lambda x=button_text: entry.onScreen(x)
).grid(row=row_num, column=col_num, pady=5)
#Put the clear button at the bottom of the grid:
tk.Button(root, text="CLEAR (CE)",
height=1,
width=20,
bg='orange',
command=entry.clearScreen
).grid(row=row_num+1, columnspan=3) #columnspan tells grid() to use 3 cells for the button,
#and the button will be centered by default.
root.mainloop()

Categories