In this video we’ll create a standalone .exe file for our Calculator app with Kivy and Python. We’ll be using the free pyinstaller to do all of this work.
Step One: pip install pyinstaller
Step Two: pyinstaller calc.py -w
Step Three: modify our calc.spec file, making several changes shown in the video.
Step Four: pyinstaller calc.spec -y
Step Five: Zip up all the files into one .zip file that you can share!
Python Code: calc.spec
GitHub Code: calc.spec
from kivy_deps import sdl2, glew # -*- mode: python ; coding: utf-8 -*- block_cipher = None a = Analysis(['calc.py'], pathex=['C:\\kivygui\\calc'], binaries=[], datas=[], hiddenimports=[], hookspath=[], runtime_hooks=[], excludes=[], win_no_prefer_redirects=False, win_private_assemblies=False, cipher=block_cipher, noarchive=False) pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) a.datas += [('Code\calc.kv', 'C:\\kivygui\\calc\calc.kv', 'DATA')] exe = EXE(pyz, a.scripts, [], exclude_binaries=True, name='calc', debug=False, bootloader_ignore_signals=False, strip=False, upx=True, console=False ) coll = COLLECT(exe, Tree('C:\\kivygui\\calc\\'), a.binaries, a.zipfiles, a.datas, *[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)], strip=False, upx=True, upx_exclude=[], name='calc')
Python Code: calc.py
GitHub Code: calc.py
from kivy.app import App from kivy.uix.widget import Widget from kivy.properties import ObjectProperty from kivy.lang import Builder from kivy.core.window import Window # Set the app size Window.size = (500,700) # Designate Our .kv design file Builder.load_file('calc.kv') class MyLayout(Widget): def clear(self): self.ids.calc_input.text = '0' # Create a button pressing function def button_press(self, button): # create a variable that contains whatever was in the text box already prior = self.ids.calc_input.text # Test for error first if "Error" in prior: prior = '' # determine if 0 is sitting there if prior == "0": self.ids.calc_input.text = '' self.ids.calc_input.text = f'{button}' else: self.ids.calc_input.text = f'{prior}{button}' # Create Function to remove last character in text box def remove(self): prior = self.ids.calc_input.text # Remove The last item in the textbox prior = prior[:-1] # Output back to the textbox self.ids.calc_input.text = prior # Create function to make text box positive or negative def pos_neg(self): prior = self.ids.calc_input.text # Test to see if there's a - sign already if "-" in prior: self.ids.calc_input.text = f'{prior.replace("-", "")}' else: self.ids.calc_input.text = f'-{prior}' # Create decimal function def dot(self): prior = self.ids.calc_input.text # Split out text box by + num_list = prior.split("+") if "+" in prior and "." not in num_list[-1]: # Add a decimal to the end of the text prior = f'{prior}.' # Output back to the text box self.ids.calc_input.text = prior elif "." in prior: pass else: # Add a decimal to the end of the text prior = f'{prior}.' # Output back to the text box self.ids.calc_input.text = prior # create addition function def math_sign(self, sign): # create a variable that contains whatever was in the text box already prior = self.ids.calc_input.text # slap a plus sign to the text box self.ids.calc_input.text = f'{prior}{sign}' # create equals to function def equals(self): prior = self.ids.calc_input.text # Error Handling try: # Evaluate the math from the text box answer = eval(prior) # Output the answer self.ids.calc_input.text = str(answer) except: self.ids.calc_input.text = "Error" ''' # Addition if "+" in prior: num_list = prior.split("+") answer = 0.0 # loop thru our list for number in num_list: answer = answer + float(number) # print the answer in the text box self.ids.calc_input.text = str(answer) ''' class CalculatorApp(App): def build(self): return MyLayout() if __name__ == '__main__': CalculatorApp().run()
Kivy Design Code: calc.kv
GitHub Code: calc.kv
<MyLayout> BoxLayout: orientation: "vertical" size: root.width, root.height TextInput: id: calc_input text: "0" halign: "right" font_size: 65 size_hint: (1, .15) GridLayout: cols: 4 rows: 5 # Row Button: size_hint: (.2, .2) font_size: 32 text: "%" Button: size_hint: (.2, .2) font_size: 32 text: "C" on_press: root.clear() Button: id: clear size_hint: (.2, .2) font_size: 32 text: u"\u00AB" on_press: root.remove() Button: size_hint: (.2, .2) font_size: 32 text: "/" on_press: root.math_sign("/") # Row Button: size_hint: (.2, .2) font_size: 32 text: "7" background_color: (157/255, 157/255, 157/255, 1) on_press: root.button_press(7) Button: size_hint: (.2, .2) font_size: 32 text: "8" background_color: (157/255, 157/255, 157/255, 1) on_press: root.button_press(8) Button: size_hint: (.2, .2) font_size: 32 text: "9" background_color: (157/255, 157/255, 157/255, 1) on_press: root.button_press(9) Button: size_hint: (.2, .2) font_size: 32 text: "x" on_press: root.math_sign("*") # Row Button: size_hint: (.2, .2) font_size: 32 text: "4" background_color: (157/255, 157/255, 157/255, 1) on_press: root.button_press(4) Button: size_hint: (.2, .2) font_size: 32 text: "5" background_color: (157/255, 157/255, 157/255, 1) on_press: root.button_press(5) Button: size_hint: (.2, .2) font_size: 32 text: "6" background_color: (157/255, 157/255, 157/255, 1) on_press: root.button_press(6) Button: size_hint: (.2, .2) font_size: 32 text: "-" on_press: root.math_sign("-") # Row Button: size_hint: (.2, .2) font_size: 32 text: "1" background_color: (157/255, 157/255, 157/255, 1) on_press: root.button_press(1) Button: size_hint: (.2, .2) font_size: 32 text: "2" background_color: (157/255, 157/255, 157/255, 1) on_press: root.button_press(2) Button: size_hint: (.2, .2) font_size: 32 text: "3" background_color: (157/255, 157/255, 157/255, 1) on_press: root.button_press(3) Button: size_hint: (.2, .2) font_size: 32 text: "+" on_press: root.math_sign("+") # Row Button: size_hint: (.2, .2) font_size: 32 text: "+/-" background_color: (157/255, 157/255, 157/255, 1) on_press: root.pos_neg() Button: size_hint: (.2, .2) font_size: 32 text: "0" background_color: (157/255, 157/255, 157/255, 1) on_press: root.button_press(0) Button: size_hint: (.2, .2) font_size: 32 text: "." background_color: (157/255, 157/255, 157/255, 1) on_press: root.dot() Button: size_hint: (.2, .2) font_size: 32 text: "=" on_press: root.equals()
Add comment