【问题标题】:Convert tkinter to EXE将 tkinter 转换为 EXE
【发布时间】:2018-06-26 05:35:27
【问题描述】:

目前,我正在尝试使用 cx_freeze 将我的 tkinter Python 脚本转换为 EXE 文件。当我尝试添加另一个文件时,它以某种方式不起作用。您可以在下面我使用的最小示例中看到我使用的方法。

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() 

第二个脚本:

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) 

当我尝试构建 EXE 文件时不添加图标时,它可以工作。但是,当我尝试添加图标时,EXE 不再打开。此外,当我尝试添加数据库 Excel 文件时,我收到这样的文件不存在的消息。所有文件都在正确的文件夹中。这不是问题。

【问题讨论】:

  • 您的 EXE 文件是自解压 ZIP 文件 - 当您启动程序时,系统会将其解压缩到随机文件夹,它不必在此文件夹中运行它,而是使用完整路径从不同的文件夹 - 然后程序可以搜索错误文件夹中的其他文件。有问题/答案如何使用sys.argv[0] 获取带有脚本的文件夹的完整路径 - 然后您可以使用os.path.join() 创建其他文件的完整路径。
  • 在控制台/终端/cmd.exe 中运行 exe 文件,您应该会看到有用的错误消息,您应该提出问题(作为文本,而不是屏幕截图)

标签: python python-3.x tkinter cx-freeze


【解决方案1】:

正如标题所说,Converting tkinter to exe 我相信 pyinstaller 在这种情况下值得一提。

在 Internet 上存在一些关于 pyinstaller or cx_Freeze 哪个更好的争论,但我发现 pyinstaller 更简单,而且它对我来说是开箱即用的 tkinter。 cmd中的单行:

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

--onefile 选项生成一个输出文件,而不是多个。

--icon 将连接您选择的图标。

main.py 是带有main 函数的主文件。

【讨论】:

  • 我尝试了 pyinstaller,它会创建 .exe,但是当我运行它时,什么也没有发生。看不到我的 GUI 可能是什么原因?
  • @Naazneen 可能您应该发布另一个问题,其中包含一些代码示例以及更多相关信息(例如您使用的软件包、您的操作系统、Python 版本等),因为很难说出什么是现在错了。
  • 我尝试从已经打开的命令提示符运行它,它显示了错误。在这种情况下,错误可能是 .py 而不是 .exe 所以从 cmd 运行会显示错误并且可以解决。
  • 小心使用 --onefile 选项,根据这个答案,它会使程序启动很慢:stackoverflow.com/a/9470393/4942149
  • 使用标志--windowed,这样黑色的控制台窗口就不会出现了。
【解决方案2】:

缺少 tkinter 运行时和库。要包括那些我建议使用os.environ() 并使用include_files 参数的运行时,因为他们(简要地)描述了here

使用os.environ() 很容易。例如,可以这样做:

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

接下来在包含文件争论中包含运行时 (DLL):

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

现在您的整个设置脚本应该如下所示:

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) 

您不需要在设置脚本中使用的所有导入,cx_Freeze 会自动检测它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多