Author: Feng Xiaodao
WeChat search [Python and Excel] pay attention to my official account for more information.
Recently, I read some articles about the visual packaging tool auto py to exe sent by some big guys. Auto py to exe is based on pyinstaller, but it has more GUI interface than pyinstaller. I also tried it myself. I feel it's really easy to use and convenient. I can package the program with my fingers.
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 operate them again. Therefore, for a programmer, this is an intolerable thing. Based on this, I wrote a small batch packaging program based on pyinstaller.
Program calls cmd command
The pyinstaller packer needs to use the cmd command. Here is a brief description of the common methods to call the cmd command.
os.system()
system() is a built-in function of the os module, which can convert a string into a command and execute it on the terminal:
def system(*args, **kwargs): # real signature unknown """ Execute the command in a subshell. """ pass
This method is very simple. You only need to put the command to be executed into the function as a string:
import os os.system(f'pyinstaller -F -w D:\program.py')
The cmd window will not appear when executing the command. It is displayed in the IDE by default, and the generated files are in the same directory by default:
os.popen()
The popen() method is also a built-in function of the os module. It is implemented through a pipeline. The return value is a file object that can be read and written. The default is' r 'read. Call the read() or readlines() method of the object to read the output. 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)
The usage only needs to pass in the necessary parameters, which can be executed by reading or writing:
os.popen(f'pyinstaller -F -w D:\program.py').read()
The result of execution is the same as os.system(), and the generated files are in the same directory.
subprocess.run()
The subprocess module is officially used to replace some old module methods. It contains a lot of content methods, which are more perfect than os.system(), os.popen(). The subprocess module has multiple methods to call cmd commands, namely Popen, call, run, getstatusoutput. Here is a brief explanation of the run() method.
The subprocess.run() function executes the specified command and returns an instance of the CompletedProcess class containing the execution results after the command is executed.
The usage is the same as os.system() and os.popen(). The string command is passed in, but there are many more parameters than os.system() and os.popen()
subprocess.run(f'pyinstaller -F -w D:\program.py')
By default, this method will not return output, but only command and execution status.
Program implementation
We already know the method of calling cmd command by multiple programs. This paper uses os.system() method, which is very simple. If more complex requirements are required, we can conduct in-depth research.
The library used to build the GUI is PySimpleGUI:
import os import PySimpleGUI as sg
You can use the pip command to install those that have not been installed:
pip intsall Library name
GUI interface design
Because there are no special requirements for functions, it only needs to be able to package multiple programs with only one operation. The final design code is as follows:
# Theme settings sg.theme('LightBrown3') # Layout settings layout = [ [sg.Frame(layout=[ [ sg.InputText(key='please_select_file', size=(24, 1), font=("Microsoft YaHei ", 10), enable_events=True), # FileBrowse can only select a single file. FilesBrowse can select multiple files sg.FilesBrowse('get files', file_types=(("Text Files", "*.py"),), font=("Microsoft YaHei ", 10)), ], ], title='Select file', title_color='blue', font=("Microsoft YaHei ", 10), relief=sg.RELIEF_SUNKEN, )], [sg.Button('Start packing', font=("Microsoft YaHei ", 10)), sg.Text('', font=("Microsoft YaHei ", 10), size=(16, 0)), sg.Button('Exit program', font=("Microsoft YaHei ", 10), button_color='red')] # button_color blue red ] # create a window window = sg.Window('Packaging tools', layout, font=("Microsoft YaHei ", 12), default_element_size=(30, 1))
The interface is as follows:
logic design
The file paths obtained through the interface are separated by ";, which needs to be divided later:
valuelist = [] # event loop while True: # Exit button event, values = window.read() if event in (None, 'Exit program'): break # Open file button if event == 'please_select_file': fileName = values['please_select_file'] # The obtained file paths are separated by ";" and are passed into the list valuelist.append(fileName) if event == 'Start packing': if len(valuelist) != 0: # Pass in packing function pyinstaller_(valuelist) else: sg.popup('File not selected!')
Packing function
The function receives a list and needs to be read through a loop; the path divided by split generates a list and still needs to be read through a loop; the program packaging effect is relatively single, - F and - w are to generate a single executable file and cancel the display of the command line window respectively:
def pyinstaller_(valuelist): for i in valuelist: a = i.split(';') for x in a: os.system(f'pyinstaller -F -w {x}')
The resulting. exe executable files are saved in the dist file:
Advantages and disadvantages of Gadgets:
- Advantages: the effect of gadgets is not significant for people with other needs, but it still works for people who need to package multiple programs. After all, repeat operations should be rejected.
- Disadvantages: the disadvantages of gadgets are obvious. They can't operate packaged program icons, and they can only execute one by one when executing commands, which greatly reduces the efficiency and needs to cooperate with threads and processes.
So far, we have successfully solved the need of how to package programs in batch by using Python, and realized the liberation of both hands.
The data and code used in this article can be obtained by paying attention to the "intersection between Python and Excel" and replying to "20211011" in the background. If you operate it yourself, you will have better results!
The above is all today's content. It's not easy to be original. Welcome to like and share, and support me to continue writing!