Pode converter um script Python num ficheiro executável (EXE) utilizando a biblioteca PyInstaller. Depois de o seu código Python ter sido testado e validado, pode partilhá-lo como uma aplicação de ambiente de trabalho executável a partir de qualquer computador. Isto é especialmente útil para interfaces gráficas de utilizador (GUIs), como este monitor de série desenvolvido em Python
Estrutura do projeto
Para começar, temos de estruturar corretamente o nosso projeto. Para o fazer, utilizamos a seguinte estrutura em árvore
app/
│
├── resources
| ├── logo.ico
| ├── logo.png
| ├── style.txt
├── app.py
├── LICENSE
├── README.md
├── requirements.txt
├── setup.py
└── tests.py
- app.py contém o código principal
- logo.ico será o ficheiro de ícone utilizado após a compilação
- logo.png é utilizado no software
- style.txt contém a definição do estilo CSS
Neste tutorial, vamos criar uma interface simples usando PySide2 (você também pode usar PyQt) contendo um botão que modificará as mensagens na barra de depuração.
#!/usr/bin/python
# -*-coding:Utf-8 -*
"""
Created on Thu Nov 17 16:59:13 2022
@author: X.Wiedmer
Dummy app
Define a simple app to test PyInstaller
"""
import sys,os
#from PyQt5.QtWidgets import *
#from PyQt5.QtCore import *
#from PyQt5.QtGui import *
from PySide2.QtWidgets import *
from PySide2.QtCore import *
from PySide2.QtGui import *
pyqtSignal=Signal #translate pyqt to Pyside
# Generic app container
def resource_path(relative_path):
""" Get absolute path to resource, works for dev and for PyInstaller """
try:
# PyInstaller creates a temp folder and stores path in _MEIPASS
base_path = sys._MEIPASS
except Exception:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
"""
App configuration
"""
__title__="DummyApp"
__version__="v0.1"
style_path = resource_path("resources\\style.txt")
__icon__=resource_path("resources/logo.png")
class AcApp(QMainWindow):
def __init__(self,title='DummyApp',mainFrame=QFrame):
super().__init__()
self.title=title
self.mainFrame=mainFrame()
self.initUI()
def initUI(self):
#mainframe
self.setCentralWidget(self.mainFrame)
centralLayout=QHBoxLayout(self.mainFrame)
#widgets
self.button = QPushButton("Start")
self.button.clicked.connect(self.clicked)
centralLayout.addWidget(self.button)
#General configuration
self.setWindowTitle(self.title)
self.setGeometry(300, 300, 400, 200)
self.setWindowIcon(QIcon(__icon__))
#Debug bar
self.statusBar()
self.statusBar().showMessage('Display debug messages')
self.show()
def debugMsg(self,val):
self.statusBar().showMessage(val)
def clicked(self):
if self.button.text() == "Start":
self.debugMsg("Process started")
self.button.setText("Stop")
else:
self.debugMsg("Process stopped")
self.button.setText("Start")
def main():
app = QApplication(sys.argv)
app.setQuitOnLastWindowClosed(True)
app.setStyleSheet(open(style_path).read()); #set style according to file
ex = AcApp(__title__+__version__)
app.quit()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
N.B.: Se quiser que ficheiros como o ícone sejam incluídos no .EXE, terá de especificar o caminho absoluto no script Python.
Para gerar caminhos absolutos automaticamente, pode utilizar a seguinte função
def resource_path(relative_path):
""" Get absolute path to resource, works for dev and for PyInstaller """
try:
# PyInstaller creates a temp folder and stores path in _MEIPASS
base_path = sys._MEIPASS
except Exception:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
style_path = resource_path("resources\\ac_style.txt")
Instalando o pacote PyInstaller
Para compilar o projeto, utilizamos a biblioteca PyInstaller, que cria um ficheiro executável contendo todas as dependências necessárias para executar o código.
Antes de instalar o pyinstaller, verifique se C:\Users\ADMIN\AppData\Local\Programs\Python\Python38\Scripts está adicionado ao Path das variáveis de ambiente.
python -m pip install pyinstaller==5.6.2
N.B.: a versão 5.7.0 foi lançada, mas apresenta um erro de permissão
Configurar o ficheiro install_bat
Criamos um ficheiro install_app.bat que irá automatizar o processo de compilação. Nesse arquivo, especificamos o tipo de compilação (onefile, noconsole), as bibliotecas (PySide2) e as pastas a serem incluídas no executável (resources).
python -m PyInstaller --noconfirm --log-level=WARN ^
--onefile --noconsole ^
--hidden-import=PySide2 ^
--hidden-import=shiboken2 ^
--add-data ./resources;resources ^
--icon=./resources/logo_araignee.ico ^
app.py
O PyInstaller irá criar as pastas build, dist e um ficheiro app.spec
O ficheiro app.spec contém as especificações de compilação e a pasta que contém o ficheiro EXE.
Pode agora partilhar este ficheiro executável com qualquer pessoa (que utilize o mesmo sistema operativo) sem qualquer instalação especial da parte dela.
Limitações
O PyInstaller não permite que você compile para diferentes sistemas operacionais a partir da mesma máquina. Para criar uma aplicação Windows, é necessário usar o PyInstaller numa máquina Windows. Será necessário fazer o mesmo para Linux ou MacOS.
O PyInstaller não contém todas as dependências. De facto, algumas dependências estão contidas no SO. Portanto, é possível que algumas pessoas não consigam executar o seu software.
É possível fazer a compilação cruzada para diferentes sistemas operativos utilizando um docker.

