Executable Python Program in Windows

Last Updated on 14th December 2020 by Li-Wen Wang

quicker_f9cdfe16-734d-462d-a4d8-6083f3dddc79.png

Background

Recently, I have worked on a demo program that works on the Windows OS. However, most of my recent works are based on the python language. I really like the simplicity of the language, and don’t want to go back to use the C++ and MFC. Therefore, in this post, I will present how to use PyInstaller and Python to build an executable python program as the "*.exe" format in Windows.

Environment Preparation

  • OS: Windows (currently, the PyInstaller does not support cross-platform compiling)
  • IDE: PyCharm (optional)
  • Python Virtual Environment Control: Anaconda or Miniconda

The following steps will prepare the required environment for the project. To ensure the compatibility of the program, please be as consistent as possible with my suggested versions.

  • Python: 3.6.5
  • NumPy: 1.16.4
  • OpenCV: 3.4.5.20
  • pillow: 8.0.1
  • PyInstaller: 4.1
  • pypiwin32
# run in the anaconda Prompt
conda create --name py36 python=3.6.5
conda activate py36
pip install numpy==1.16.4 opencv-python==3.4.5.20 pillow==8.0.1 pillow==4.1 pypiwin32

Create a simple GUI with tkinter

tkinter is a build-in Python interface package to build simple GUI of python.
Save the following code as "demo.py" and run it in the prepared python environment.

print("Python Code starting... (it may cost a few seconds)")
import tkinter
from PIL import ImageTk, Image
import cv2
print("Initialized, the program is now started!")

class DemoApp:
    def __init__(self):
        # create a window
        self.window = tkinter.Tk()

        # to rename the title of the window
        self.window.title("Demo Application")

        # add some text to our GUI
        self.label = tkinter.Label(self.window, text="This is our first GUI!")
        self.label.pack()  # pack is used to show the object in the window

        # add a button
        self.button = tkinter.Button(self.window, text="Show Image", command=self.showImg)
        self.button.pack()  # pack is used to show the object in the window

        # add an image area that will display an image
        self.img_canvas = tkinter.Canvas(self.window, width=481, height=193)

        self.img_canvas.pack()

        # mainloop() tells Python to run the Tkinter event loop. This method listens for events, such as button clicks or keypresses
        self.window.mainloop()

    def showImg(self):
        # Load an color image
        img_cv = cv2.imread('img.jpg')
        img_pil = Image.fromarray(cv2.cvtColor(img_cv, cv2.COLOR_BGR2RGB))  # from opencv to PIL image
        self.imgtk = ImageTk.PhotoImage(image=img_pil)  # Convert the Image object into a TkPhoto object, must use self. to ensure the image data does not be removed when leave the function

        # Put it in the display window
        # anchor "nw" means when creating the image for the coordinates (0,0) to represent the upper-left corner of the image
        self.img_Area = self.img_canvas.create_image(0, 0, anchor="nw",image=self.imgtk)
        #self.img_canvas.itemconfig(self.img_Area, image=self.imgtk)

        # change the button text and action
        self.button.config(text = "Close Image", command=self.clearImg)
        return

    def clearImg(self):
        self.img_canvas.delete(self.img_Area) # empty image

        # change the button text and action
        self.button.config(text="Show Image", command=self.showImg)
        return

if __name__ == '__main__':
    # download an image for test
    import urllib.request
    urllib.request.urlretrieve("https://i.loli.net/2020/12/14/3dLYfJFhIlyQ2Vo.png", "img.jpg")

    # start the app
    app = DemoApp()

By running the above code, it can display a simple Demo application as:
quicker_d14f6850-187e-48dc-83bb-bd4a34593768.png

Compile it to "*.exe" format

Simply using the pyinstaller to automatically finds all dependent files.

# ! bash command
pyinstaller main.py

You may use "–noconsole" to hide console window, and "–onefile" to combine all files to a single exe file. However, I strongly suggest you to use default "-D" that creates a one-folder bundle containing an executable exe, which is faster than "–onefile".
For the use of PyInstaller, more information can be obtained at https://pyinstaller.readthedocs.io/en/latest/usage.html

Then you can fin your executable at ".dist" folder!
the files are located at .dist folder

Play with your .exe file

It will open a terminal first to startup your python script. Then, the GUI will be displayed. If you want to hide the console window, just use "–noconsole" command when you compiling your exe file (last step).

To share your program, just share the whole "./dist/demo" folder to others. Then, run the ".exe" file.

paly with your exe file

Leave a Reply