Last Updated on 14th December 2020 by Li-Wen Wang
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.
- 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: 184.108.40.206
- pillow: 8.0.1
- PyInstaller: 4.1
# run in the anaconda Prompt conda create --name py36 python=3.6.5 conda activate py36 pip install numpy==1.16.4 opencv-python==220.127.116.11 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:
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!
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.