web-dev-qa-db-fra.com

Conversion de tkinter en exe

Actuellement, j'essaie de convertir mon script tkinter python en un fichier exe. J'utilise cx_freeze pour ce faire. Lorsque j'essaie d'ajouter un fichier supplémentaire, il ne fonctionne plus. Dans l'exemple minimum que j'utilise ci-dessous, vous pouvez voir la méthode que j'ai utilisée.

import tkinter as tk

import numpy.core._methods, numpy.lib.format 

class Main(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)

        self.geometry("700x400")
        self.wm_iconbitmap('test.ico')

        container = tk.Frame(self)

        container.pack(side="top", fill="both", expand = True)

        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.frames = {}

        for F in (StartPage, PageOne):

            frame = F(container, self)
            self.frames[F] = frame
            frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame(StartPage)

    def show_frame(self, cont):
        frame = self.frames[cont]
        frame.tkraise()        
        frame.update_page() # <-- update data on page when you click button

    def get_page(self, page_class):
        return self.frames[page_class]


class StartPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller 

        label1 = tk.Label(self, text="What are the sizes?")
        label1.pack()

        L1 = tk.Label(self, text="Length :")
        L1.pack()

        self.E1 = tk.Entry(self)
        self.E1.pack()

        button = tk.Button(self, text="Next", command=lambda: controller.show_frame(PageOne))
        button.pack()

    def update_page(self): # empty method but I need it
        pass   

class PageOne(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller

        label1 = tk.Label(self, text="You have insert")
        label1.pack()

        # create empty label at start
        self.label2 = tk.Label(self, text="")
        self.label2.pack()

        button = tk.Button(self, text="Back", command=lambda: controller.show_frame(StartPage))
        button.pack()

    def update_page(self):
        # update label when page is changed
        page1 = self.controller.get_page(StartPage) 
        var = page1.E1.get()
        self.label2['text'] = var


app = Main()
app.mainloop() 

Le deuxième script:

import cx_Freeze
import sys
import matplotlib 
import os 
import numpy.core._methods
import numpy.lib.format

base = None 

if sys.platform=='win32':
    base = "Win32GUI"


executables = [cx_Freeze.Executable("Show_file.py")]    

cx_Freeze.setup(
        name = "Name",
        options = {"build_exe":{"packages":["tkinter","matplotlib"],"include_files":["test.ico"]}},
        version="0.01",
        executables=executables) 

Lorsque j'essaie de créer le fichier exe, cela fonctionne lorsque je n'ajoute pas d'icône. Cependant, si j'essaye d'ajouter une icône, l'exe ne s'ouvre plus. De plus, lorsque j'essaie d'ajouter un fichier Excel de base de données, je reçois le message qu'un tel fichier n'existe pas. Allo les fichiers sont dans le bon dossier. Ce n'est pas le problème.

Quelqu'un pourrait-il m'aider avec ce problème?

Merci d'avance.

5
Beertje

Comme le titre l'indique Converting tkinter to exe Je crois pyinstaller mérite d'être mentionné dans ce cas.

Il y a des débats sur ce qui est mieux pyinstaller ou cx_Freeze sur Internet, mais j'ai trouvé pyinstaller plus simple et cela a fonctionné pour moi avec tkinter. Une doublure en cmd:

pyinstaller.exe --onefile --icon=myicon.ico main.py

L'option --onefile Produit un fichier de sortie au lieu de plusieurs.

--icon Connectera une icône de votre choix.

main.py Est votre fichier principal avec la fonction main.

10
akarilimano

Les runtimes et les bibliothèques tkinter sont manquants. Pour inclure ceux que je suggérerais d'utiliser os.environ() et d'inclure les runtimes en utilisant l'argument include_files Comme ils ont (brièvement) décrit ici .

L'utilisation de os.environ() est simple. Par exemple, cela peut être fait comme ceci:

os.environ["TCL_LIBRARY"] = "<PathToPython>\\Python\\Python36-32\\tcl\\tcl8.6"
os.environ["TK_LIBRARY"] = "<PathToPython>\\Python\\Python36-32\\tcl\\tk8.6"

Incluez ensuite les runtimes (DLL) dans l'argument des fichiers include:

    options = {"build_exe":{"packages":["tkinter","matplotlib"],"include_files":["test.ico", "<PathToPython>\\Python\\Python36-32\\DLLs\\tcl86t.dll", "<PathToPython>\\Python\\Python36-32\\DLLs\\tk86t.dll"]}},

Maintenant, tout votre script d'installation devrait ressembler à ceci:

import sys # Imports are automatically detected (normally) in the script to freeze
import os 

base = None 

os.environ["TCL_LIBRARY"] = "<PathToPython>\\Python\\Python36-32\\tcl\\tcl8.6"
os.environ["TK_LIBRARY"] = "<PathToPython>\\Python\\Python36-32\\tcl\\tk8.6"

if sys.platform=='win32':
    base = "Win32GUI"


executables = [cx_Freeze.Executable("Show_file.py")]    

cx_Freeze.setup(
        name = "Name",
        options = {"build_exe":{"packages":["tkinter","matplotlib"],"include_files":["test.ico", "<PathToPython>\\\\Python\\Python36-32\\DLLs\\tcl86t.dll", "<PathToPython>\\\\Python\\Python36-32\\DLLs\\tk86t.dll"]}},
        version="0.01",
        executables=executables) 

Vous n'avez pas besoin de toutes les importations que vous allez utiliser dans le script de configuration, cx_Freeze les détecte automatiquement.

1
Simon