Recently I read some articles about the visual packaging tool auto-py-to-exe posted by some big guys. Auto-py-to-exe is based on pyinstaller, but compared to pyinstaller, It has a GUI interface. I also tried it myself and found it really useful and convenient. You can package the program with just a few clicks.
But I found that neither auto-py-to-exe nor pyinstaller can directly package multiple programs at one time. If you want to package multiple programs, you need to do it again, so for a programmer, this is intolerable. things. Based on this, I wrote a small batch packaging program based on pyinstaller.
The pyinstaller packaging program needs to use the cmd command. Here is a brief introduction to the common methods of calling the cmd command.
system() is a function built into the os module, which can convert strings into commands and execute them on the terminal:
def system(*args, **kwargs): # real signature unknown """ Execute the command in a subshell. """ pass
Using this method is very simple , just put the command to be executed into the function in the form of a string:
import os os.system(f'pyinstaller -F -w D:程序.py')
The cmd window will not appear when executing the command. It will be displayed in the IDE by default. The generated file will be in the same directory by default:
Thepopen() method is also a built-in function of the os module. It is implemented through a pipeline. The return value is a file object. , can be read and written. Defaults to 'r' reading. The output content can be read by calling the read() or readlines() method of the object. The following is the source code:
def popen(cmd, mode="r", buffering=-1): if not isinstance(cmd, str): raise TypeError("invalid cmd type (%s, expected string)" % type(cmd)) if mode not in ("r", "w"): raise ValueError("invalid mode %r" % mode) if buffering == 0 or buffering is None: raise ValueError("popen() does not support unbuffered streams") import subprocess, io if mode == "r": proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, bufsize=buffering) return _wrap_close(io.TextIOWrapper(proc.stdout), proc) else: proc = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, bufsize=buffering) return _wrap_close(io.TextIOWrapper(proc.stdin), proc)
Usage only needs to pass in the necessary parameters and execute by reading or writing:
os.popen(f'pyinstaller -F -w D:程序.py').read()
The execution result is the same as os.system(), and the generated file is in the same directory.
The subprocess module is officially used to replace some old module methods. It contains many content methods and is more advanced than os.system() and os.popen(). To improve some. The subprocess module has multiple methods for calling cmd commands, namely Popen, call, run, and getstatusoutput. Here we only briefly explain the run() method.
The subprocess.run() function executes the specified command, waits for the command to be executed, and returns an instance of the CompletedProcess class containing the execution result.
The usage is the same as the os.system() and os.popen() methods, passing in the string command, but the selection of parameters is much more than that of os.system() and os.popen():
subprocess.run(f'pyinstaller -F -w D:程序.py')
This method does not return output by default, only the command and execution status.
We have already known how multiple programs call cmd commands. This article uses the os.system() method. The usage methods are very simple. If the requirements are more complex, you can Do in-depth research.
The library used to build the GUI is PySimpleGUI:
import os import PySimpleGUI as sg
If it has not been installed yet, you can use the pip command to install it:
pip intsall 库名
Because it is There are no special requirements for the function. It only needs to be able to package multiple programs with just one operation. The final design code is as follows:
# 主题设置 sg.theme('LightBrown3') # 布局设置 layout = [ [sg.Frame(layout=[ [ sg.InputText(key='please_select_file', size=(24, 1), font=("微软雅黑", 10), enable_events=True), # FileBrowse 只能选择单个文件 FilesBrowse加入s可以选择多个文件 sg.FilesBrowse('获取文件', file_types=(("Text Files", "*.py"),), font=("微软雅黑", 10)), ], ], title='选择文件', title_color='blue', font=("微软雅黑", 10), relief=sg.RELIEF_SUNKEN, )], [sg.Button('开始打包', font=("微软雅黑", 10)), sg.Text('', font=("微软雅黑", 10), size=(16, 0)), sg.Button('退出程序', font=("微软雅黑", 10), button_color='red')]# button_color blue red ] # 创建窗口 window = sg.Window('打包工具', layout, font=("微软雅黑", 12), default_element_size=(30, 1))
The interface is as follows:
Widget interface
The file path obtained through the interface is separated by ";", which needs to be divided later:
valuelist = [] # 事件循环 while True: # 退出按钮 event, values = window.read() if event in (None, '退出程序'): break # 打开文件按钮 if event == 'please_select_file': fileName = values['please_select_file'] # 得到的文件路径是以 “;”相分隔的,传入列表 valuelist.append(fileName) if event == '开始打包': if len(valuelist) != 0: # 传入打包函数 pyinstaller_(valuelist) else: sg.popup('文件未选择!')
The function receives a list, which needs to be read through a loop; the path divided by split will generate a list, which still needs to be read through a loop; the program packaging effect is relatively simple, -F and -w respectively To generate a single executable file and cancel the display of the command line window:
def pyinstaller_(valuelist): for i in valuelist: a = i.split(';') for x in a: os.system(f'pyinstaller -F -w {x}')
The final generated .exe executable files are saved in the dist file:
Result.exe file
Advantages and disadvantages of the gadget:
So far, we have successfully used Python to solve the need for batch packaging of programs and freed our hands.
The above is the detailed content of A tool for implementing batch packaging programs using Python~. For more information, please follow other related articles on the PHP Chinese website!