This project started with me wanting to learn a way to make an app in Python with a Graphic User Interface (GUI). GUI is what people are used to seeing when working with a computer. The previous scripts I have done in Python have all been command line interface where you have to type what you want the computer to do.
I found two ways of creating a GUI in Python, Tkinter and QT. I went with Tkinter to try first, it looked like a simpler one to start with and I ran across a great training video from Free Code Camp/Codemy YouTube video seen here: https://www.youtube.com/watch?v=YXPyB4XeYLA
In the training we build various little apps; one of them is a very basic calculator. After the training I focused on this to learn more with Tkinker and to play with more Python coding. I’ve added decimal and positive/negative buttons. Then I fixed the calculation results issue that sometimes shows up in Python, when float points are involved. Added the 0 to display to start. I’ll just explain the add-ons I did to the calculator, you can view the video to see how it’s built.
With Tkinter you build your projects using frames and grids. This is a lot like HTML tables, if you’ve worked with them you’ll pick this up quickly.
Fixing Pythons float calculations:
I’ll start with the fix to the calculation results first, other parts will be using this library. When a number is using a float, a decimal number, it doesn’t always calculate correctly in Python. If we take 0.1 + 0.2 we should get 0.3 but in Python we might get 0.3000000000000004. As I’ve read in several posts, this is about the computer processing and not the programming language, if you try on different OSes you could get different results. To get around this issue we import the decimal library, which will round/fix the results:
from decimal import *
This will calculate the number correctly, to use it we will wrap it like we would a float, int, etc:
Decimal(f_num)
This was added around all the calculations in the button_equal function.
With that 0.1 + 0.2 now equals 0.3.
The positive-negative button:
Added a negative/positive button in case you need a negative number or convert a number to a positive or negative value we’ll have this button setup. Also having this extra button helped to balance the design.
I created a button like the others and put in ‘+/-‘ like you would see on a regular calculator. Created a function named ‘button_posNeg’.
In this function I’m getting what is shown in the display assigning it to ‘current’. Then checking if ‘-‘ is in the current number, if it is then replace it with nothing ‘’ assign it to f_num. If there is no ‘-‘ then add the ‘-‘ to the beginning of f_num. Then in the end delete what’s in the display and display what the value in f_num, the one we assigned a ‘-‘ or removed.
def button_posNeg():
current = e.get()
#checks if number is already negative if so removes it
if '-' in current:
f_num = current.replace('-', '')
#if not adds the negative
else:
f_num= '-'+current
e.delete(0, END)
e.insert(0, str(f_num))
Decimal point:
Next, we’ll work on the decimal point in the calculation:
Created a button like the others and displayed it as ‘.‘ gave it the class of ‘button_dot’. Since I’ve imported the decimal library, I wanted to keep the naming different. Button_decimal would have worked to.
In the function I grab a copy of what is in the display. I check if ‘.’ Is in the current number, we END it, so it won’t add another decimal. If it’s not there then it will add a ‘.’ To the button_click function, which will add it to the end of the number in the display:
def button_dot():
current = e.get()
#Checks if there is already a decimal in the number if so END and it won't add another
if '.' in current:
END
else:
button_click('.')
0 to start:
Added ‘0’ to get the decimal in the display when no number. I added this to the click function, I added the insert ‘0’ to the beginning of app and after clear and the calculation buttons.
def button_click(number):
current = e.get()
e.delete(0, END)
print(current)
#This checks if the number coming in is. and that there is either a 0 or nothing, then add the 0 before
if number == '.' and (current == '0' or current == None):
e.insert(0, '0.')
#if it's just a 0 before this will remove so you won't get a 03 for your number
elif current == '0':
e.insert(0, str(number))
#normal function delete what was in display concatanate the 2 numbers.
else:
e.insert(0, str(current) + str(number))
Design:
This is a very basic look for a calculator.
Sketch out your program first of where you want elements to sit, since tkinker uses a table setup mark out the rows and columns then when you assemble the program you can put it together quicker. If not, you might find that you’re having to look to see where it’s located and figure where to move items around.
When I mentioned added the +/- would help balance the design. Balancing the design by having the clear button, top left, is 2 cols across and the ‘=’ button in the bottom right is 2 cols across. Having these equal size large elements opposite each other like this helps balance each other in the look of the display. If both were on one side it would make the display look a bit uneven.
Tips:
- Sketch out your layout before you start, this will save you a lot of time.
- The top left is position is 0,0
- Same code does not have the same size buttons on Windows and Mac.
- You can extend our code where you define then place it to the grid, example:
button_1 = Button(root, text=”1″, padx=40, pady=20, command=lambda: button_click(1)).grid(row=4, column=0) - If I keep using tkinter I’ll probably do it this way when moving the buttons around for the new design and changing sizes I think it would be easier for them all together, also harder to forget to connect it to the design.
- Make sure to have this line at bottom or you won’t see your app, this will keep it displaying till you close the app:
root.mainloop()
Next post will be about creating a stand-alone app for the calculator to run on Mac and Windows machines.