将 tkinter 转换为 EXE
Convert tkinter to EXE
目前,我正在尝试使用 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 文件时,我得到这样的文件不存在的消息。所有文件都在正确的文件夹中。那不是问题。
缺少 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 会自动检测它们。
正如标题所说Converting tkinter to exe
我认为pyinstaller在这种情况下值得一提。
Internet 上存在一些关于哪个 pyinstaller or cx_Freeze 更好的争论,但我发现 pyinstaller
更简单并且它对我来说开箱即用 tkinter
。 One-liner 在命令中:
pyinstaller.exe --onefile --icon=myicon.ico main.py
--onefile
选项生成一个输出文件,而不是多个。
--icon
将连接您选择的图标。
main.py
是具有 main
功能的主文件。
目前,我正在尝试使用 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 文件时,我得到这样的文件不存在的消息。所有文件都在正确的文件夹中。那不是问题。
缺少 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 会自动检测它们。
正如标题所说Converting tkinter to exe
我认为pyinstaller在这种情况下值得一提。
Internet 上存在一些关于哪个 pyinstaller or cx_Freeze 更好的争论,但我发现 pyinstaller
更简单并且它对我来说开箱即用 tkinter
。 One-liner 在命令中:
pyinstaller.exe --onefile --icon=myicon.ico main.py
--onefile
选项生成一个输出文件,而不是多个。
--icon
将连接您选择的图标。
main.py
是具有 main
功能的主文件。