I am trying to create a program in python 3.4.2 using tkinter. I hope to create a GUI calculator. So far i've been able to code out the buttons and layout (interface) of the program. The only thing that i need help with is the actions that the buttons perform. For example, i need a way to enter the value of the button pressed into my entry bar at the top of the calculator. (e,g: I press button 7 and 7 pops up into my entry bar). I need help coding that because i don't know how. So far my only working button on screen is the clear (ce) button as it clears the whole entry bar in my GUI. Can someone please take a look at my code below to help me establish a way to get this calculator working. (P.S i'm not no genius at tkinter, so basically try to explain it to me as you would to to a 10 year old LOOL).
Summary:
Connect my buttons to my entry bar.
My code:
#Project Name : Calculator ++
#Version : 1.7.2
#Written by : Pamal Mangat.
#Start Date : Monday, July 7th, 2015.
import sys
from tkinter import *
from PIL import Image, ImageTk
def clear():
txtDisplay.delete(0,END);
return;
#Parent Window.
root = Tk();
root.title('Calculator ++ [1.7.2]');
root.geometry('350x450');
#Main entry.
num1 = StringVar();
txtDisplay = Entry(root, textvariable = num1, relief=RIDGE, bd = 10, width=33, insertwidth = 1, font = 40);
txtDisplay.place(x=15, y=10);
txtDisplay.focus();
#Buttons:
zeroButton = Button(root, text='0', width=20, height=3, bg='LightBlue', fg='red').place(x=17,y=382);
oneButton = Button(root, text='1', width=8, height=3, bg='LightBlue', fg='red').place(x=17, y=302);
twoButton = Button(root, text='2', width=8, height=3, bg='LightBlue', fg='red').place(x=100, y=302);
threeButton = Button(root, text='3', width=8, height=3, bg='LightBlue', fg='red').place(x=182, y=302);
fourButton = Button(root, text='4', width=8, height=3, bg='LightBlue', fg='red').place(x=17, y=222);
fiveButton = Button(root, text='5', width=8, height=3, bg='LightBlue', fg='red').place(x=100, y=222);
sixButton = Button(root, text='6', width=8, height=3, bg='LightBlue', fg='red').place(x=182, y=222);
sevenButton = Button(root, text='7', width=8, height=3, bg='LightBlue', fg='red').place(x=17, y=142);
eightButton = Button(root, text='8', width=8, height=3, bg='LightBlue', fg='red').place(x=100, y=142);
ninthButton = Button(root, text='9', width=8, height=3, bg='LightBlue', fg='red').place(x=182, y=142);
decimalButton = Button(root, text='.', width=8, height=3, bg='powder blue').place(x=182, y=382);
equalButton = Button(root, text='=', width=8, height=8, bg='Lightgreen').place(x=264, y=307);
plusButton = Button(root, text='+', width=8, height=3, bg='gray').place(x=264, y=222);
minusButton = Button(root, text='-', width=8, height=3, bg='gray').place(x=264, y=142);
multiplyButton = Button(root, text='x', width=8, height=3, bg='gray').place(x=264, y=66);
divideButton = Button(root, text='÷', width=8, height=3, bg='gray').place(x=182, y=66);
clearButton = Button(root, text='Clear (CE)', width=20, height=3, command = clear, bg='Orange').place(x=17, y=66);
#Locks the parent windows size.
root.maxsize(350,450);
root.minsize(350,450);
#Parent window's background color:
root.configure(background = 'black');
root.mainloop();
Below is an image of what my code executes and looks like once it's runned. The only issue is that it's just a bunch of pushable buttons with no use; except for clear(ce) which i happened to get running. The other buttons need meaning and a function, because i really want to get this program up and running.
As ppl wrote in the comments, you need a function that will respond to button pressed and will update the Entry widget. I modified the code, to show how it can be done:
import sys
from tkinter import *
from PIL import Image, ImageTk
def clear():
txtDisplay.delete(0,END);
return;
#Parent Window.
root = Tk();
root.title('Calculator ++ [1.7.2]');
root.geometry('350x450');
#Main entry.
num1 = StringVar();
txtDisplay = Entry(root, textvariable = num1, relief=RIDGE, bd = 10, width=33, insertwidth = 1, font = 40);
txtDisplay.place(x=15, y=10);
txtDisplay.focus();
def update_entry(v):
current_value = num1.get()
num1.set(current_value + v)
#Buttons:
zeroButton = Button(root, text='0', width=20, height=3, bg='LightBlue', fg='red', command = lambda: update_entry('0')).place(x=17,y=382);
oneButton = Button(root, text='1', width=8, height=3, bg='LightBlue', fg='red', command = lambda: update_entry('1')).place(x=17, y=302);
twoButton = Button(root, text='2', width=8, height=3, bg='LightBlue', fg='red').place(x=100, y=302);
threeButton = Button(root, text='3', width=8, height=3, bg='LightBlue', fg='red').place(x=182, y=302);
fourButton = Button(root, text='4', width=8, height=3, bg='LightBlue', fg='red').place(x=17, y=222);
fiveButton = Button(root, text='5', width=8, height=3, bg='LightBlue', fg='red').place(x=100, y=222);
sixButton = Button(root, text='6', width=8, height=3, bg='LightBlue', fg='red').place(x=182, y=222);
sevenButton = Button(root, text='7', width=8, height=3, bg='LightBlue', fg='red').place(x=17, y=142);
eightButton = Button(root, text='8', width=8, height=3, bg='LightBlue', fg='red').place(x=100, y=142);
ninthButton = Button(root, text='9', width=8, height=3, bg='LightBlue', fg='red').place(x=182, y=142);
decimalButton = Button(root, text='.', width=8, height=3, bg='powder blue').place(x=182, y=382);
equalButton = Button(root, text='=', width=8, height=8, bg='Lightgreen').place(x=264, y=307);
plusButton = Button(root, text='+', width=8, height=3, bg='gray', command = lambda: update_entry('+')).place(x=264, y=222);
minusButton = Button(root, text='-', width=8, height=3, bg='gray').place(x=264, y=142);
multiplyButton = Button(root, text='x', width=8, height=3, bg='gray').place(x=264, y=66);
divideButton = Button(root, text='÷', width=8, height=3, bg='gray').place(x=182, y=66);
clearButton = Button(root, text='Clear (CE)', width=20, height=3, command = clear, bg='Orange').place(x=17, y=66);
#Locks the parent windows size.
root.maxsize(350,450);
root.minsize(350,450);
#Parent window's background color:
root.configure(background = 'black');
root.mainloop();
I added update_entry function that updates the Entry text variable. Also added lambdas to buttons 0 and 1 and + for an instration of use. Other buttons are not done. Also dont use place (or grid) in one line as you have now as all your Button variables will be None.
Related
Python TKinter Mac: Buttons layout strangely and when a button is clicked it looks the same (as if it hadn't been clicked) however I didn't check to see if the button worked.
and the space is a textbook
the Mac version is: a 2017 iMac running Monterey 12.4
import tkinter as tk
window = tk.Tk()
window.geometry("500x500")
window.title("Stock Watchlist & Logger")
label = tk.Label(window, text="Tester", font=('Ariel', 18))
label.pack(padx=20, pady=20)
textbox = tk.Text(window, height=3, font=('Ariel', 16))
textbox.pack(padx=10, pady=10)
numbuttframe = tk.Frame(window)
numbuttframe.columnconfigure(0, weight=1)
yesnobuttframe = tk.Frame(window)
yesnobuttframe.columnconfigure(1, weight=1)
button1 = tk.Button(numbuttframe, text="1", font=('Arial', 18))
button1.grid(row=0, column=0, sticky=tk.W+tk.E)
button2 = tk.Button(numbuttframe, text="2", font=('Arial', 18))
button2.grid(row=0, column=1, sticky=tk.W+tk.E)
button3 = tk.Button(numbuttframe, text="3", font=('Arial', 18))
button3.grid(row=0, column=2, sticky=tk.W+tk.E)
button4 = tk.Button(numbuttframe, text="4", font=('Arial', 18))
button4.grid(row=0, column=3, sticky=tk.W+tk.E)
button5 = tk.Button(numbuttframe, text="5", font=('Arial', 18))
button5.grid(row=0, column=4, sticky=tk.W+tk.E)
button6 = tk.Button(numbuttframe, text="6", font=('Arial', 18))
button6.grid(row=0, column=5, sticky=tk.W+tk.E)
yesbutton = tk.Button(yesnobuttframe, text="Yes", font=('Arial', 18))
yesbutton.grid(row=0, column=0, sticky=tk.W+tk.E)
nobutton = tk.Button(yesnobuttframe, text="No", font=('Arial', 18))
nobutton.grid(row=0, column=1, sticky=tk.W+tk.E)
numbuttframe.pack(fill='x')
yesnobuttframe.pack(fill='x')
if button1:
print("CELEBRATE!")
window.mainloop()
You set the weight to two cells weight=1 , so they expanded, since the rest have a default weight of 0. Since I don’t see your grid - the buttons are placed in frames one after the other, suggest using the pack method. And shortened your code a bit. The buttons won't work yet, because they don't have a command = call. Complex variable names in Python are usually written with an underscore.
import tkinter as tk
FONT = ('Ariel', 18)
window = tk.Tk()
window.geometry("500x500")
window.title("Stock Watchlist & Logger")
lbl = tk.Label(window, text="Tester", font=FONT)
lbl.pack(padx=20, pady=20)
text_box = tk.Text(window, height=3, font=('Ariel', 16))
text_box.pack(padx=10, pady=10)
num_btn = tk.Frame(window)
yes_no_btn = tk.Frame(window)
num_btn.pack(fill='x')
yes_no_btn.pack(fill='x')
buttons = []
for i in range(1, 7):
btn = tk.Button(num_btn, text=f"{i}", font=FONT)
btn.pack(side="left", fill='x', expand=True)
buttons.append(btn)
yes_btn = tk.Button(yes_no_btn, text="Yes", font=FONT)
yes_btn.pack(side="left", fill='x', expand=True)
no_btn = tk.Button(yes_no_btn, text="No", font=FONT)
no_btn.pack(side="left", fill='x', expand=True)
window.mainloop()
I'm getting an indent error in my Eclipse compiler, I have marked the specific line below on for where the error is. Anyone have any idea on the fix? It's for an assignment at school and I have no idea on a fix and I'm at a complete, absolute loss. I would appreciate anyone's tips. "Write a GUI based program that simulates a simple pocket calculator. The GUI displays a single entry field for output (I would suggest to make it a read only field). It should present the user with 10 numeric buttons from 0 to 9 and seven function keys for +, -, *, /, C (C is for clearing the display), . (decimal point) and =. = is to calculate the correct answer. If there is an error like divide by zero the entry field should display ERR or Error. Values in the entry field will build a string that will be converted to a float for calculation." This is the assignment I have to complete.
from tkinter import *
from tkinter import font as tkFont # for convenience
expression = ""
# functions
def input_number(number, equation):
global expression
# concatenation of string
expression = expression + str(number)
equation.set(expression)
def clear_input_field(equation):
global expression
expression = ""
# setting empty string in the input field
equation.set("Enter the expression")
def evaluate(equation):
global expression
# trying to evaluate the expression
try:
result = str(eval(expression))
equation.set(result)
expression = ""
except:
equation.set("Error: Divide by zero")
expression = ""
def main():
# creating main window
tk = Tk()
# setting the title
tk.title("Calculator")
# seting the size of window
tk.geometry("570x500")
# varible class instantiation
equation = StringVar()
# input field for the expression
input_field = Entry(tk, textvariable=equation)
input_field.place(height=100)
input_field.grid(columnspan=4, ipadx=200, ipady=10)
equation.set("Enter the expression")
myFont = tkFont.Font(family='Helvetica', size=12, weight='bold')
input_field['font']=myFont
# creating buttons and placing them at respective positions
_1 = Button(tk, text='1', fg='black', bg='red', bd=2, command=lambda: input_number(1, equation), height=5, width=10) #I'm getting an error on this line
_1['font'] = myFont
_1.grid(row=2, column=0)
_2 = Button(tk, text='2', fg='black', bg='red', bd=2, command=lambda: input_number(2, equation), height=5, width=10)
_2.grid(row=2, column=1)
_3 = Button(tk, text='3', fg='black', bg='red', bd=2, command=lambda: input_number(3, equation), height=5, width=10)
_3.grid(row=2, column=2)
_4 = Button(tk, text='4', fg='black', bg='red', bd=2, command=lambda: input_number(4, equation), height=5, width=10)
_4.grid(row=3, column=0)
_5 = Button(tk, text='5', fg='black', bg='red', bd=2, command=lambda: input_number(5, equation), height=5, width=10)
_5.grid(row=3, column=1)
_6 = Button(tk, text='6', fg='black', bg='red', bd=2, command=lambda: input_number(6, equation), height=5, width=10)
_6.grid(row=3, column=2)
_7 = Button(tk, text='7', fg='black', bg='red', bd=2, command=lambda: input_number(7, equation), height=5, width=10)
_7.grid(row=4, column=0)
_8 = Button(tk, text='8', fg='black', bg='red', bd=2, command=lambda: input_number(8, equation), height=5, width=10)
_8.grid(row=4, column=1)
_9 = Button(tk, text='9', fg='black', bg='red', bd=2, command=lambda: input_number(9, equation), height=5, width=10)
_9.grid(row=4, column=2)
_0 = Button(tk, text='0', fg='black', bg='red', bd=2, command=lambda: input_number(0, equation), height=5, width=10)
_0.grid(row=5, column=0)
plus = Button(tk, text='+', fg='black', bg='red', bd=2, command=lambda: input_number('+', equation), height=5, width=10)
plus.grid(row=2, column=3)
minus = Button(tk, text='-', fg='black', bg='red', bd=2, command=lambda: input_number('-', equation), height=5, width=10)
minus.grid(row=3, column=3)
multiply = Button(tk, text='*', fg='black', bg='red', bd=2, command=lambda: input_number('*', equation), height=5, width=10)
multiply.grid(row=4, column=3)
divide = Button(tk, text='/', fg='black', bg='red', bd=2, command=lambda: input_number('/', equation), height=5, width=10)
divide.grid(row=5, column=3)
equal = Button(tk, text='=', fg='black', bg='red', bd=2, command=lambda: evaluate(equation), height=5, width=10)
equal.grid(row=5, column=2)
_1['font'] = myFont
_2['font'] = myFont
_3['font'] = myFont
_4['font'] = myFont
_5['font'] = myFont
_6['font'] = myFont
_7['font'] = myFont
_8['font'] = myFont
_9['font'] = myFont
_0['font'] = myFont
plus['font'] = myFont
minus['font'] = myFont
multiply['font'] = myFont
divide['font'] = myFont
equal['font'] = myFont
clear = Button(tk, text='Clear', fg='black', bg='red', bd=2, command=lambda: clear_input_field(equation), height=5, width=10)
clear.grid(row=5, column=1)
clear['font']=myFont
# showing the GUI continue
tk.mainloop()
if __name__ == '__main__':
main()```
The line you've highlighted, and the following lines, are indented by an extra step - make sure they line up with the line above, as they aren't inside another block (e.g a function or an if statement)
I am trying to create a TicTacToe game in Tkinter and I am trying to put a label under the buttons of the board but when I am put the label under the buttons the buttons are moving to the sides.
how can I fix it?
this is my code:
from tkinter import *
from tkinter import messagebox
root = Tk()
root.title('TicTacToe')
# X starts
clicked = True
count = 0
#button clicked function
def b_click(b):
global clicked
global count
if b["text"] == " " and clicked == True:
b["text"] = "X"
clicked = False
count += 1
elif b["text"] == " " and clicked == False:
b["text"] = "O"
clicked = True
count += 1
else:
messages["text"] = "you cant do that"
#build the buttons
b1 = Button(root, text=" ", font =("Helvetica", 20), height=3, width=6, bg="SystemButtonFace", command= lambda:b_click(b1))
b2 = Button(root, text=" ", font =("Helvetica", 20), height=3, width=6, bg="SystemButtonFace", command= lambda:b_click(b2))
b3 = Button(root, text=" ", font =("Helvetica", 20), height=3, width=6, bg="SystemButtonFace", command= lambda:b_click(b3))
b4 = Button(root, text=" ", font =("Helvetica", 20), height=3, width=6, bg="SystemButtonFace", command= lambda:b_click(b4))
b5 = Button(root, text=" ", font =("Helvetica", 20), height=3, width=6, bg="SystemButtonFace", command= lambda:b_click(b5))
b6 = Button(root, text=" ", font =("Helvetica", 20), height=3, width=6, bg="SystemButtonFace", command= lambda:b_click(b6))
b7 = Button(root, text=" ", font =("Helvetica", 20), height=3, width=6, bg="SystemButtonFace", command= lambda:b_click(b7))
b8 = Button(root, text=" ", font =("Helvetica", 20), height=3, width=6, bg="SystemButtonFace", command= lambda:b_click(b8))
b9 = Button(root, text=" ", font =("Helvetica", 20), height=3, width=6, bg="SystemButtonFace", command= lambda:b_click(b9))
messages = Label(root, text="", font =("Helvetica", 20), height=1, width=15, relief="sunken")
space = Label(root, text="", font =("Helvetica",))
#display the buttons
b1.grid(row=0, column=0)
b2.grid(row=0, column=1)
b3.grid(row=0, column=2)
b4.grid(row=1, column=0)
b5.grid(row=1, column=1)
b6.grid(row=1, column=2)
b7.grid(row=2, column=0)
b8.grid(row=2, column=1)
b9.grid(row=2, column=2)
space.grid(row=3, column=0)
messages.grid(row=4, column=1)
root.mainloop()
When you try to add the label under the buttons, if you don't specify the columnspan the label will take the whole cell, so what happened is that the label is wider than the buttons, and since it took all the cell the buttons went to the sides, so if you put it like this:
...
space.grid(row=3, column=0)
messages.grid(row=4, column=0, columnspan=3)
root.mainloop()
you are telling tkinter that your label is taking the three columns, and so it does not move the buttons anymore. Here's the result:
So my intention is when the user clicks one of the buttons, for the rest of the other buttons not to perform anything even when clicked, so basically to stop the buttons from performing their commands when the user clicks them ONLY if they have clicked in another button previously, I don't know if I expressed myself well so I am sorry if I dind't but here's my code:
from tkinter import *
import random
screen = Tk()
ticket = random.randint(1,3)
def test():
def test1():
if ticket == button1:
button_1 = Button(screen, text="RIP", fg="white", bg="red", width=15, height=2)
button_1.grid(row=0, column=0, sticky="w")
else:
button_2 = Button(screen, text="+1", fg="white", bg="green", width=15, height=2)
button_2.grid(row=0, column=0, sticky="w")
def test2():
if ticket == button2:
button_3 = Button(screen, text="RIP", fg="white", bg="red", width=15, height=2)
button_3.grid(row=0, column=1, sticky="w")
else:
button_4 = Button(screen, text="+1", fg="white", bg="green", width=15, height=2)
button_4.grid(row=0, column=1, sticky="w")
def test3():
if ticket == button3:
button_5 = Button(screen, text="RIP", fg="white", bg="red", width=15, height=2)
button_5.grid(row=0, column=2, sticky="w")
else:
button_6 = Button(screen, text="+1", fg="white", bg="green", width=15, height=2)
button_6.grid(row=0, column=2, sticky="w")
ticket = random.randint(1,3)
button1 = Button(screen, text="1", fg="white", bg="blue", width=15, height=2, command=test1)
button1.grid(row=0, column=0, sticky="w")
button1 = 1
button2 = Button(screen, text="2", fg="white", bg="blue", width=15, height=2, command=test2)
button2.grid(row=0, column=1, sticky="w"+"e"+"n"+"s")
button2 = 2
button3 = Button(screen, text="3", fg="white", bg="blue", width=15, height=2, command=test3)
button3.grid(row=0, column=2, sticky="e")
button3 = 3
button1 = Button(screen, text="START", fg="black", bg="orange", width=25, height=2, command=test)
button1.grid(row=1, columnspan=3, sticky="w"+"e"+"n"+"s")
screen.mainloop()
You can set the state of the other Buttons to DISABLED to grey them out and prevent clicks. This would be the ideal place to use a subclass that keeps track of its instances.
from tkinter import *
import random
screen = Tk()
class MykoButton(Button):
instances = []
def __init__(self, master=None, **kwargs):
super().__init__(master, command=self.run, **kwargs)
self.instances.append(self)
def run(self):
for button in self.instances:
if button is not self:
button.config(state=DISABLED)
if random.randint(1,3) == 1:
self.config(text="RIP", fg="white", bg="red") # update the button
else:
self.config(text="+1", fg="white", bg="green")
def test():
for i in range(3):
button = MykoButton(screen, text="1", fg="white", bg="blue", width=15, height=2)
button.grid(row=0, column=i)
button1 = Button(screen, text="START", fg="black", bg="orange", width=25, height=2, command=test)
button1.grid(row=1, columnspan=3, sticky="w"+"e"+"n"+"s")
screen.mainloop()
Also, note that I changed your code to update the clicked button, rather than put a new button on top of it.
I have been doing a python app for a calculator with Tkinter. I want to know how access the buttons properties such as their size, height, width and color by the use of strings. So far I have been able to change the background of the lines behind the buttons to red by using style.configure("TButton", background='red',
font="Serif 15",
padding=10 ).
How do I change the buttons themselves? If anyone could help me I would greatly appreciate it.
from tkinter import *
from tkinter.ttk import *
from tkinter import ttk
class Calculator:
calc_value = 0.0
div_trigger = False
mult_trigger = False
add_trigger = False
sub_trigger = False
def __init__(self,root):
self.entry_value = StringVar(root,value="")
root.title("Calculator")
root.geometry("600x500")
root.resizable(width=True, height=True)
style = ttk.Style()
style.configure(self, background='red')
style.configure("TButton", #background='red',
font="Serif 15",
padding=10 )
style.configure("TEntry",
font="Serif 15",
padding=10 )
self.number_entry = ttk.Entry(root,
textvariable=self.entry_value,width=50)
self.number_entry.grid(row=0, columnspan=4)
#-------1st row---------
self.button7 = ttk.Button(root, text="7",
command=lambda: self.button_press('7')).grid(row=1, column=0)
self.button8 = ttk.Button(root, text="8",
command=lambda: self.button_press('8')).grid(row=1, column=1)
self.button9 = ttk.Button(root, text="9",
command=lambda: self.button_press('9')).grid(row=1, column=2)
self.button_div = ttk.Button(root, text="/",
command=lambda: self.button_press('/')).grid(row=1, column=3)
#-------2nd row---------
self.button4 = ttk.Button(root, text="4",
command=lambda: self.button_press('4')).grid(row=2, column=0)
self.button5 = ttk.Button(root, text="5",
command=lambda: self.button_press('5')).grid(row=2, column=1)
self.button6 = ttk.Button(root, text="6",
command=lambda: self.button_press('6')).grid(row=2, column=2)
self.button_mult = ttk.Button(root, text="*",
command=lambda: self.button_press('*')).grid(row=2, column=3)
#-------3rd row---------
self.button1 = ttk.Button(root, text="1",
command=lambda: self.button_press('1')).grid(row=4, column=0)
self.button2 = ttk.Button(root, text="2",
command=lambda: self.button_press('2')).grid(row=4, column=1)
self.button3 = ttk.Button(root, text="3",
command=lambda: self.button_press('3')).grid(row=4, column=2)
self.button_add = ttk.Button(root, text="+",
command=lambda: self.button_press('+')).grid(row=4, column=3)
#-------4th row---------
self.button_clear = ttk.Button(root, text="AC",
command=lambda: self.button_press('AC')).grid(row=5, column=0)
self.button0 = ttk.Button(root, text="0",
command=lambda: self.button_press('0')).grid(row=5, column=1)
self.button_equal = ttk.Button(root, text="=",
command=lambda: self.button_press('=')).grid(row=5, column=2)
self.button_sub = ttk.Button(root, text="-",
command=lambda: self.button_press('-')).grid(row=5, column=3)
root = Tk()
calc = Calculator(root)
root.mainloop()
#button1 = Button(topframe,padx=16, pady=16, bd=8, text="1", fg="black", bg = random.choice(colors))
Here are documentatiopn about that.
http://effbot.org/tkinterbook/button.htm
If you want to change a botton size you can use.
button1.config(height = 100, width = 100)