What if the written program is sent to others for use, but the other party does not install the python environment or PyQt5 library? The best solution is to package the program into executable files, so that it can be used even on a computer without Python environment and PyQt5 library. It is very convenient.
Note: after reading this chapter, if you want to know more about PyInstaller, you can go to the writer's PyInstaller packaging Practice Guide
25.1 download Pyinstaller
Download on windows:
pip install pyinstaller
Download on Linux:
pip3 install pyinstaller
Download on MacOS:
pip3 install pyinstaller
After downloading, we open the terminal and enter pyinstaller. If the display is as follows, the installation is successful:
25.2 understand pyuninstaller command parameters
Here we only need to know a few common commands. Please refer to for detailed usage Pyinstaller manual:
25.3 Packaging example
Let's take the login box applet in Chapter 5 and package it as an example. The code of the program is as follows:
import sys from PyQt5.QtWidgets import QApplication, QWidget, QDialog, QLabel, QLineEdit, QPushButton, \ QGridLayout, QVBoxLayout, QHBoxLayout, QMessageBox USER_PWD = { 'la_vie': 'password' } class Demo(QWidget): def __init__(self): super(Demo, self).__init__() self.resize(300, 100) self.user_label = QLabel('Username:', self) self.pwd_label = QLabel('Password:', self) self.user_line = QLineEdit(self) self.pwd_line = QLineEdit(self) self.login_button = QPushButton('Log in', self) self.signin_button = QPushButton('Sign in', self) self.grid_layout = QGridLayout() self.h_layout = QHBoxLayout() self.v_layout = QVBoxLayout() self.lineedit_init() self.pushbutton_init() self.layout_init() self.signin_page = SigninPage() # Instantiate SigninPage() def layout_init(self): self.grid_layout.addWidget(self.user_label, 0, 0, 1, 1) self.grid_layout.addWidget(self.user_line, 0, 1, 1, 1) self.grid_layout.addWidget(self.pwd_label, 1, 0, 1, 1) self.grid_layout.addWidget(self.pwd_line, 1, 1, 1, 1) self.h_layout.addWidget(self.login_button) self.h_layout.addWidget(self.signin_button) self.v_layout.addLayout(self.grid_layout) self.v_layout.addLayout(self.h_layout) self.setLayout(self.v_layout) def lineedit_init(self): self.user_line.setPlaceholderText('Please enter your username') self.pwd_line.setPlaceholderText('Please enter your password') self.pwd_line.setEchoMode(QLineEdit.Password) self.user_line.textChanged.connect(self.check_input_func) self.pwd_line.textChanged.connect(self.check_input_func) def pushbutton_init(self): self.login_button.setEnabled(False) self.login_button.clicked.connect(self.check_login_func) self.signin_button.clicked.connect(self.show_signin_page_func) def check_login_func(self): if USER_PWD.get(self.user_line.text()) == self.pwd_line.text(): QMessageBox.information(self, 'Information', 'Log in Successfully!') else: QMessageBox.critical(self, 'Wrong', 'Wrong Username or Password!') self.user_line.clear() self.pwd_line.clear() def show_signin_page_func(self): self.signin_page.exec_() def check_input_func(self): if self.user_line.text() and self.pwd_line.text(): self.login_button.setEnabled(True) else: self.login_button.setEnabled(False) class SigninPage(QDialog): def __init__(self): super(SigninPage, self).__init__() self.signin_user_label = QLabel('Username:') self.signin_pwd_label = QLabel('Password:') self.signin_pwd2_label = QLabel('Password:') self.signin_user_line = QLineEdit() self.signin_pwd_line = QLineEdit() self.signin_pwd2_line = QLineEdit() self.signin_button = QPushButton('Sign in') self.user_h_layout = QHBoxLayout() self.pwd_h_layout = QHBoxLayout() self.pwd2_h_layout = QHBoxLayout() self.all_v_layout = QVBoxLayout() self.lineedit_init() self.pushbutton_init() self.layout_init() def layout_init(self): self.user_h_layout.addWidget(self.signin_user_label) self.user_h_layout.addWidget(self.signin_user_line) self.pwd_h_layout.addWidget(self.signin_pwd_label) self.pwd_h_layout.addWidget(self.signin_pwd_line) self.pwd2_h_layout.addWidget(self.signin_pwd2_label) self.pwd2_h_layout.addWidget(self.signin_pwd2_line) self.all_v_layout.addLayout(self.user_h_layout) self.all_v_layout.addLayout(self.pwd_h_layout) self.all_v_layout.addLayout(self.pwd2_h_layout) self.all_v_layout.addWidget(self.signin_button) self.setLayout(self.all_v_layout) def lineedit_init(self): self.signin_pwd_line.setEchoMode(QLineEdit.Password) self.signin_pwd2_line.setEchoMode(QLineEdit.Password) self.signin_user_line.textChanged.connect(self.check_input_func) self.signin_pwd_line.textChanged.connect(self.check_input_func) self.signin_pwd2_line.textChanged.connect(self.check_input_func) def pushbutton_init(self): self.signin_button.setEnabled(False) self.signin_button.clicked.connect(self.check_signin_func) def check_input_func(self): if self.signin_user_line.text() and self.signin_pwd_line.text() and self.signin_pwd2_line.text(): self.signin_button.setEnabled(True) else: self.signin_button.setEnabled(False) def check_signin_func(self): if self.signin_pwd_line.text() != self.signin_pwd2_line.text(): QMessageBox.critical(self, 'Wrong', 'Two Passwords Typed Are Not Same!') elif self.signin_user_line.text() not in USER_PWD: USER_PWD[self.signin_user_line.text()] = self.signin_pwd_line.text() QMessageBox.information(self, 'Information', 'Register Successfully') self.close() else: QMessageBox.critical(self, 'Wrong', 'This Username Has Been Registered!') self.signin_user_line.clear() self.signin_pwd_line.clear() self.signin_pwd2_line.clear() if __name__ == '__main__': app = QApplication(sys.argv) demo = Demo() demo.show() sys.exit(app.exec_())
We will name this py file test Py and put the file on the desktop, then open the command line window, cd to the desktop directory, and enter pyinstaller - F - W test py
Click enter to start packing:
After that, we will find two more folders and a spec file on the desktop:
The executable program we want is in the dist folder. Double click to open it:
Now you can put the test executable file on another computer to run.
The executable file packaged above uses the default icon. Next, we add the - i parameter to add an icon to the program when packaging (please note that this usage is only valid for Windows systems):
[update] is not only valid for windows system. If you want to set the icon on the mac, the icon file should be in icns format
Icon download: https://www.easyicon.net/download/ico/1210123/64/
Name the icon login ICO and put it on the desktop, with test Py same path. Similarly, open the command line window, cd to the desktop, and enter pyinstaller - F - W - I login ico test.py press enter to start packing:
Then we can find the packaged executable file in dist folder:
25.4 summary
-
There may be various problems when packing, but most of the problems can be solved as long as you read the error report carefully. Don't panic;
-
The author summarizes some problems when packaging with Pyinstaller. For details, see: Solution summary of Pyinstaller packaging problem.