Criei um exe de um diretório com pyinstaller a partir do meu código-fonte Python. No meu código, eu uso imagens com o caminho relativo da imagem colocado próximo aos arquivos .py.
Ao ler o documento do pyinstaller, tentei 2 coisas: a forma oficial com o -add data e outro método onde copio as imagens diretamente ao lado do main.exe.
Com os 2 métodos, tento iniciar o main.exe e recebo um erro não encontrado:
não foi possível abrir "bdd_trans.png": esse arquivo ou diretório não existe
Então tentei ver onde estava o diretório de trabalho atual ao iniciar o exe com:
from os import getcwd
path = getcwd()
print(path)
Em seguida, colei todas as imagens no diretório impresso e o aplicativo exe funcionou. O problema é que o diretório em que tenho que colocar as imagens está nos dados dos usuários do Windows, que não estão dentro da pasta de construção. Portanto, não posso enviar meu aplicativo para alguém e fazê-lo funcionar instantaneamente, o que é um grande problema.
Alguém sabe por que os métodos oficiais não funcionaram para mim?
Aqui está o comando pyinstaller que estou executando:
pyinstaller --noconfirm --onedir --windowed --icon "C:/app_final_v8/base-de-donnees.ico" --add-data "C:/app_final_v8/actualiser_trans.png;." --add-data "C:/app_final_v8/ajouter_trans.png;." --add-data "C:/app_final_v8/bdd_trans.png;." --add-data "C:/app_final_v8/client_trans.png;." --add-data "C:/app_final_v8/composant_trans.png;." --add-data "C:/app_final_v8/cyxplus_red.png;." --add-data "C:/app_final_v8/employees_trans.png;." --add-data "C:/app_final_v8/equipement_trans.png;." --add-data "C:/app_final_v8/exporter_trans.png;." --add-data "C:/app_final_v8/modifier_trans.png;." --add-data "C:/app_final_v8/quitter_trans.png;." --add-data "C:/app_final_v8/rechercher_trans.png;." --add-data "C:/app_final_v8/retour_trans.png;." --add-data "C:/app_final_v8/site_trans.png;." --add-data "C:/app_final_v8/supprimer_trans.png;." --add-data "C:/app_final_v8/ticket_trans.png;." --add-data "C:/app_final_v8/trait.png;." "C:/app_final_v8/main.py"
Aqui está a saída tentando executar o exe:
Traceback (most recent call last):
File "main.py", line 7, in <module>
File "app.py", line 98, in __init__
File "page_accueil.py", line 26, in __init__
File "tkinter\__init__.py", line 4061, in __init__
File "tkinter\__init__.py", line 4006, in __init__
_tkinter.TclError: couldn't open "bdd_trans.png": no such file or directory
[11300] Failed to execute script 'main' due to unhandled exception!
Veja como eu uso as imagens de dados:
correspondance_table_icone = {
"activite_client": "trait.png",
"type_anomalie": "trait.png",
"client": "client_trans.png",
"composant": "composant_trans.png",
"contrat_maintenance": "trait.png",
"employe":"employees_trans.png",
"equipement": "equipement_trans.png",
"extension_chrono": "trait.png",
"fabricant_composant": "trait.png",
"fonction_composant": "trait.png",
"pays": "trait.png",
"sous_client": "trait.png",
"ticket": "ticket_trans.png",
"trigramme": "trait.png",
"type_equipement": "trait.png",
"type_ticket": "trait.png",
"site": "site_trans.png",
"ville": "trait.png"
}
for ligne in range(len(controller.base.nom_tables)):
table = controller.base.nom_tables[ligne]
icon_image = PhotoImage(file = correspondance_table_icone[table])
self.dict_bouton_tab[table] = tb.Button(canvas_tab.interior, text = correspondance_table_tab[table][0], image=icon_image, compound="left", style = 'Custom_tab.Outline.TButton', command = lambda _table = table: self.afficher_table(controller.base, _table), bootstyle = INFO)
self.dict_bouton_tab[table].image = icon_image
self.dict_bouton_tab[table].grid(row = correspondance_table_tab[table][1], column = 0, sticky = "nsew")
O Tkinter não sabe a localização do seu bdd_trans.png. Você precisa modificar seu programa para poder detectar os arquivos. Sugiro fazer o seguinte:
sys.path contém diretórios nos quais o Python procura módulos importados e arquivos semelhantes. Ao anexar o caminho da sua subpasta, você permite que o interpretador Python encontre os arquivos movidos. No código acima, sys.path contém o diretório de trabalho atual (getcwd) e o nome da subpasta 'lib', que pode ser ajustado para qualquer nome que você desejar.
Qualquer gancho de tempo de execução fornecido será executado antes do script principal. Você pode simplesmente modificar seu arquivo *.spec ou usar o comando de console correspondente:
Para uma explicação detalhada, consulte o seguinte artigo médio .