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.