This is how the calculator that we’ll be
creating in this tutorial will look like. As you can see it is resizable, it can be
used without the mouse by just using the keyboard keys, a proper beep sound is played every
time a key is pressed and the best part is that by the end of this tutorial, you will
be able to create your own GUI calculator in python using the Tkinter module. What’s up Pythoneers, welcome back to my
channel. In this tutorial, I am gonna be showing you
how you can create a GUI calculator in python, from scratch. I am gonna be building the calculator in front
of you and side-by-side be explaining each and every line of code that I write so that
you guys understand the code, rather than just copying the code. So we will start by creating a folder and
opening the folder in visual studio code. I am using vs code for this tutorial, you
can use any IDE or text editor you want. If you wanna know how to setup python and
visual studio code, you can check out this video I made on this topic, With our python and vs code setup completed,
we will create a file by the name main.py, which will have our calculator code in it. We are gonna start off by importing the Tkinter
module. Just to give a quick idea, Tkinter is a built-in
python module specifically designed to create simple GUI applications in python. And since we are building a GUI calculator,
we are going to use this module in python. Now the next step will be to create our GUI
window. In order to do that, we will create an object
of the Tk() class. We can do that by typing tk dot capital t
and then small k followed by round brackets. We are gonna store this object within the
root variable. So whenever we refer to the root variable
within our code, we actually refer to the Tkinter window. In order to run our GUI application, we will
have to call another function of the Tk class, called the main loop function. Basically, it is a function that calls an
infinite loop that checks for events within the Tkinter window and acts accordingly. This function is really necessary, as the
window will not be rendered, or in other words displayed, if we don’t use this function. We will not save this file and just check
once if the script runs properly or not. As you can see here, the script has been executed
properly and a Tkinter window is now created and displayed to us. No for the next step, I want to point out
something. As you can see here, the word ‘tk’ is
written here. We are going to change this text and write
‘Calculator; in place of it, coz obviously, we are creating a calculator. We will just close this program and then write
root.title(“Calculator”). This line of code will set the value of the
title text as Calculator. If I run this script, you can clearly see
here that the ‘tk’ text that we saw earlier is now replaced by “calculator”. You guys can name it whatever you want, just
make sure to pass a string in the title function. For the next step, we will change the dimensions
of this window. To do that, I will call the geometry function
which is used to set the dimensions of the window. I have already thought of the calculator’s
dimensions to be 400 pixels in width by 400 pixels in length, so i am gonna write 400
x 400 here, as a string. The first value represents the width in pixels,
and the second value is the height in pixels. Now if I run this program You guys can see that the window created has
a different size now, which is 400 pixels by 400 pixels to be precise. You can experiment with different sizes like
600 by 600 or maybe 800 by 600. It all depends on you. Now that our window is properly setup, its
time that we start adding textboxes and buttons within it. I have a screenshot of the calculator with
me that we are going to make. As you can see here that the top 1/4th of
the window is occupied by the textbox and the lower 3/4th of the portion is where all
the buttons are located . So we are goona start by creating two frames,
one for our textbox and one for all the buttons. A frame in tkinter is basically like dividing
the window into different portions for the purpose of placement of widgets. To create a frame for textbox, we are goona
write, output_frame = tk.Frame(). Here Frame is the class used to create a frame. We are gonna pass three arguments in it. First will be root as we are mentioning to
tkinter that our frame should be a part of the root window. Next we pass width of the frame. We want our frame to be as wide as the root
window, so the width will be 400 pixels. And since the textbox occupies 1/4th of the
root window’s height, we are gonna mention its height as 100 pixels, which is 1/4t of
the total window height, that is 400 pixels.We are also gonna pass background as red so that
we can see our frame in the window, else the frame would be invisible. Now we are gonna type output_frame.grid to
place our frame within the root window. We are gonna mention row as 0 and column as
0. Grid basically uses a table like format to
place widgets in tkinter window. We are mentioning row and column as 0 as we
want the frame to be at the top. Before we run, we have one more thing to do,
Below the line where we wrote root.geometry, we are gonna write
root.grid_rowconfigure(0, weight=1) root.grid_rowconfigure(1, weight=4)
root.grid_columnconfigire(0, weight=1) Let me explain you these lines. Basically, grid rowconfigure and grid column
configure are used to mention how much portion of the total area will each row and column
will occupy. You can see I have mentioned for row 0 to
have weight 1 and row 1 to have weight 4. It means that row 0 (first row) will occupy
1 of the portion of the total window, and the row 1 (second row) will occupy 4 portions
of the total window, relative to row 0 occupying one portion. Similarly , column 0 (first column) will occupy
1 portion of the total window. Since i have configured only column 0 (first
column), it means that only column 0 will occupy all the portion, compared to any other
column. The best thing about this is that the ratio
remains constant, even if you resize the window while the program is running. The widgets will automatically resize themselves
according to the ratio. Now if I run the program, you can clearly see the red frame occupying
some space of the total window size. The problem is if I try to resize it, the
frame is not resizing. To make it work, we will add within output_frame.grid
a new parameter sticky=tk.NSEW. Basically it will make the frame stick to
all the sides of the area within its grid. Now if I run this program You can see that the frame will now resize
itself if we resize the window. This means that the program is working correctly. Just like the output frame, we will create
a button_frame for all the button we will place. I will just copy the output_frame code and
make a few changes, like changing the variable name to button_frame, here and here. Then we will change the height of the frame
from 100 to 300, as this frame has to occupy 3/4th of the window area. Then we will change background color to green
so that we can see the frame properly. And finally we will change row to 1 as we
want the frame to be below the output frame. Now if I save the code and run the program. You can see that our green button frame is
perfectly placed, and it also resizes as we resize the window. Now for the next video, we will add textbox
and buttons to the code. I hope you liked the video, if you did, don’t
forget to like, share and subscribe and I will see you all in the next video. What’s up Pythoneers, welcome to my YouTube
Channel where we talk all about python. In the previous video of this series, we discussed
creating the Tkinter window, creating an understanding about the design, and accordingly created
output_frame and button_frame to place our output entry and button respectively. So without any further ado, let’s continue
with this tutorial. Now we will add the textbox within our output_frame. To add a textbox, we will type Output_textbox = tk.Entry(). Entry is the class used in Tkinter to create
a textbox widget. We will pass a few parameters in it. First will be output_frame as we want the
textbox to be created within the output_frame. One thing to note here is that only a tk class
object, a frame class object or a top-level class object can be passed within widget classes
like this entry class. We have already seen tk class object which
is the root in this case, and also the frame class object, which is output_frame. I will explain top-level in python in another
tutorial. After passing the root parameter, we will
pass the font parameter. We will keep the font as Calibri with a font
size of 30. Next, we will set the state of the textbox
as disabled, as we don’t want to directly type within the calculator textbox. Instead, we will use buttons to type within
the textbox. This way we can make sure that no alphabets
or special characters are accidentally typed within the text box and the program does not
give any errors. Next, we will set the disabled background
as ‘bisque’ as I want the text box background to be of bisque color when the textbox is
disabled. Then we will write the background as bisque
and foreground as black. Bisque here is actually the name of a color. You can also use hex code here to get the
color of your choice. Then we will write output_textbox.pack(). Here pack is used to place the textbox. We are using pack as we want the textbox to
fit the whole area of the output frame. We will pass two parameters in it, fill= tk.BOTH
and expand as True. fill=tk.BOTH specifies that we want our textbox
to fill both the x and y-axis of its parent, which is the output frame. Expand equals true means that the textbox
will expand and change itself according to the changing screen size. Now we will save the code and let’s see
how it looks As you can see here, that our red-colored
output frame is now replaced with this yellow-colored textbox. Since it is disabled, we cannot type directly
in it, but we will programmatically add text in it as we keep building our calculator. Now is the time we start working on button
widget Below the line where we created our button
frame, we have to write the following lines For
i in range(4) button_frame.grid_rowconfigure(i, weight=1)
button_frame.grid_columnconfigure(i, weight=1) Let’s try to understand what’s happening
here. We know that we are creating a 4 by 4 grid
for all the buttons, as you can see here, in the screenshot. So we need to configure our grid in such a
way that each of the 4 rows occupies 1/4th of height and similarly, each column occupies
1/4th of total height in the button frame. So we are achieving that by giving each row
and column weight 1. And we are using a for loop to do the job
without writing longer code. As you can see here, the loop iterates from
0 to 3, representing each row and column. And as it does that, row configure and column
configure is used to give each row and column weight of 1. I hope that cleared your doubt. Now it’s time that we add buttons to it. We can do that by typing Button_one = tk.Button(), Button is the Tkinter
class used to create a button widget. We will pass a few parameters in it. As always, the first will be to mention which
frame should this button be a part of. We will mention button_frame as we want the
button to be in the button frame. Next, we will set the font as “Calibri”
with a font size of 20. We will also set text as 1, as we want to
display number 1 on the button. Next, we will mention its width to be 6. Here 6 is not the pixel size, but the size
occupied by six letters of font Calibri with font size 20. Now we will mention the background color as
‘pink’ and the foreground color as ‘black’. Now the next line, we will write button_one.grid(). We will pass row as 0 and column as 0, as
we can see in the screenshot that the button is at row 0 and column 0 in the button grid. Also, we will pass sticky=tk>NSEW, so that
the button properly resizes with the Tkinter window. Now we have to make 15 more copies of buttons
like this, to create a total of 16 buttons. All the buttons should name unique variable
names, their row and columns will be unique, their text will be unique, rest all will be
the same. I already have done it here, so that I don’t
waste much of your time doing it here. Let me just quickly explain what I have done
here. As you can see, we have buttons two, three
all up to 9 and 0, and then we have buttons for plus, minus, multiply, divide, dot, and
equal sign. We don’t have a clear button for clearing
the screen, so instead of a button, we will use keyboard keys to clear the screen. I will explain that later in the video. I have also updated the rows and columns,
as per the screenshot that we have where we can calculate the row and column of each button. For example, button 9 will be in row 2 and
column 2 as rows and columns start from 0. Now we will run the code and see how our calculator
looks like. Dn as you can see, we have your button perfectly
placed, and, you gotta admit it looks really good, isn’t it? Now that the GUI portion of our calculator
is complete, it’s time we start working on the calculator logic. Creating the logic won’t be that difficult
to understand, but you’ll have to focus on understanding how to integrate the code
logic with the GUI part. We are gonna start by creating a function
that will be called whenever a button will be clicked which will show the number on the
output textbox. So we are gonna go above the line where we
declared root and then we will write: Def print_number(). Within the round brackets, we will write “number”
as this function will take the number that has to be displayed on the textbox as the
parameter. Since the textbox is disabled from start,
in order to write the number on it, we will first change the textbox state to normal. To do that we will write, output_textbox.configure(state=tk.NORMAL). This will change the textbox state to normal. Now we have to write the number onto the textbox. For that, we will write output_texbox.insert(tk.END, str(number)). Insert function is used to insert value within
the textbox. The first parameter value is tk.END, which
basically means that the text will be added from the end i.e. if there will be any text
within the textbox already present, this text will add from the right side of the already
present text. The second parameter is the text to be added. Since it requires a string argument, I have
passed the value of the number within str to make it a string. And finally, in order to again disable the
textbox, we will write output_textbox.configure(state=tk.DISABLED)
which will again bring back the state of the textbox to disabled. This completes this function Now we want this function to be called every
time a button is clicked, and for that, we’ll have to set this function call on the button
click of each button. Before we do that, we’ll go to the top of
the script, where we had imported Tkinter and type From functools import partial We would be needing the partial function as
this function will allow us to attach any function with parameters to any Tkinter widget. Let me just show you what I mean. We will go to the line in our code where we
declared button one and below the line, we will add a line like this button_one.configure(command=partial(print_number,
1)) What this line will do is attach this function
call with button one. Now every time someone will press this button,
the function will be called with parameter number 1, so the function will display 1 on
the textbox. Since we could not directly call the print_number
function with parameter one the normal way, we had to use the partial function in order
to create a new function which is like print_number function but with parameter number as 1. Let’s save our file and see how our program
works As you can see, if I click on the button with
number 1, numeric 1 is displayed on the textbox. If I click on the button multiple times, the
number 1 keeps adding on the textbox. Now that you are clear with how the button
click can be used to perform any task, all we have to do is to write this same line but
for all buttons in the calculator. So let’s do it Now that the code is updated, let’s run
and check if the number buttons are working properly or not. As you can see here, all the number buttons
are working just fine and that means it's time we move on to other buttons Now the plan for the calculator’s working
is that the add, subtract, multiply, divide and dot button will simply add respective
symbols onto the output textbox and we will simply evaluate the output altogether by analyzing
the text on the output textbox. So I am just gonna use the same print_number
function for add, subtract, multiply and divide function, but I will pass symbols as parameters,
instead of numbers. If I save the file and run it again You can see that on clicking the plus, minus
buttons their respective symbol gets displayed on the screen. And the final button to work on is the equal
sign which will evaluate the expression and give the output. We would need to create a different function
for that. We will go to the line below the line where
print number function ends and write: Def evaluate(). We don’t need to add any parameters to it. Within the function, first we will retrieve
the expression present in the output textbox, We can get it by typing Expression = output_textbox.get() The expression variable will have the string
value present within the output textbox. Now in order to evaluate it, we will use a
great python built-in function called eval(). This function will automatically evaluate
the string expression and give us the output. If you wanna know more about the eval function,
you can check out the blog post on my blog site, link is in the description down below. So we will get the output of expression like
this: Result = eval(expression) And that’s it. The result variable will have the output of
the expression. Next, we will enter the result value in the
output textbox. First, we will enable the textbox like we
did in the print number function by typing output_textbox.configure(state=tk.NORMAL) Then we will clear the textbox by typing output_textbox.delete(0, len(expression)) Basically delete is used to clear a certain
portion of the textbox, by mentioning the start and end index to be deleted. Since we want to clear the whole screen, we
will mention the starting index, the first parameter as 0, and the end index, the second
parameter is the length of the expression. This will clear the whole textbox for us. Then we will type output_textbox.insert(tk.END, result) Like we did in the print number function to
type our output on the textbox. And finally, we will disable the textbox by
typing output_textbox.configure(state=tk.DISABLED) With this, the evaluate function is completed. Now we will simply add this function to work
when the equals button is clicked. To do that, we will go to the equals button
and add button_equal.configure(command=evaluate). Since this function does not require any argument,
we don’t need to use the partial function here. Now if I run the program If I type 2 plus 3 and then click on equals,
the textbox shows me output as 5, indicating the program works just fine. The only issue is that I cannot clear the
textbox from here. So now we will create a function to clear
the textbox. Below the line where the evaluate function
ends, we are gonna write Def clear(). We don’t need to pass any arguments for
this function Within the function, we will write a portion
of the code that we wrote in evaluate the function, we will write output_textbox.configure(state=tk.NORMAL)
output_textbox.delete(0, len(output_textbox.get())) output_textbox.configure(state=tk.DISABLED) These lines are the same as the ones we used
in evaluate the function, the only difference is that within the len function, we used output_textbox
.get to directly get the expression from the output textbox. This saves us a line of code. Now comes the part where we have to perform
an action on the program with the click of a keyboard button. To do that we’ll have to bind keys to certain
functions within our program. Below the line where we set the root window’s
geometry, we’ll have to write root.bind(“<Key-BackSpace>”, clear) Basically, we are binding the backspace key
of our keyboard with the clear function in the program, so whenever we will click on
the backspace button on our keyboard, the clear function will clear the textbox. Before we run our program, we have to do one
more thing that I just remembered. We’ll have to add a parameter to the clear
function. Let’s name it event. Since we are binding this function, it makes
this function an event according to Tkinter. So we need to add this parameter to it. We don’t need to pass any value to it or
to use the parameter anywhere within the function, but writing it is very important, as the code
will not work without it. Now let’s run and see how it works If I type any number on the textbox and then
click backspace, the textbox gets cleared, which means it is working fine. Our calculator is now completed enough to
be used in real life. But to make our calculator even better, we
are going to add a few functionalities So let’s start by adding a beep sound every
time a button is clicked. I have the beep.mp3 sound file with me in
the same folder where main.py is situated. You guys can get it from github where I have
uploaded the entire code. You can get the github link in the description
down below. In order to play this file, we will use a
built-in python module named playsound. We will go to the line where we had imported
tkinter module and write: From playsound import playsound This will import the playsound function from
the playsound module. We’ll also have to import another built
in module called threading. This module is used to run two or more function
concurrently i.e. side by side in python. We will write Import threading To import the module. Now, we will go to the print number function. We know that this function is called when
a button is clicked, except for the equal button. So at the first line within the function,
we will write threading.Thread(playsound(“beep.mp3”)).start(). Basically this line will create a thread that
will perform the function of playing the sound file beep.mp3 using the playsound module. And it will also start the thread immediately
by calling the start function. I will copy this line and also add it to the
evaluate function so that the beep sound comes when the equals button is clicked. I have pasted the code right here. Now if i save the file and run the script you will hear that whenever I click on a button,
a beep sound could be heard. That’s because every time a button is clicked,
the beep.mp3 audio file is played. With that our calculator is now completed. I hope you liked this tutorial if you did,do
like, subscribe and share this tutorial to all your python programmer friends. In case of any doubts, you can comment down
below and I will respond to it as soon as possible. With this, it’s time for me to go. This is vishesh dvivedi, signing off.