在Python Tkinter中,我可以通过按钮运行任何exe文件吗?
我一直在研究如何使用Tkinter从一个Tkinter软件打开exe文件。最终我做出来的产品是一个可以在Windows 7上运行的exe文件,它能从这个Tkinter软件中运行所有的exe文件,而这个Tkinter软件也被转换成了exe文件。
接下来我会从上到下解释我的代码。这是我的Tkinter模板。
from Tkinter import *
from PIL import Image, ImageTk
import os
class App:
def __init__(self, master):
self.frame = Frame(master)
我添加了一张图片,目的是给用户提供如何使用这个软件的信息。
img = Image.open("data.gif")
intro = ImageTk.PhotoImage(img)
right = Label(None, image=intro)
right.grid(row=0, column=0, columnspan=4)
right.image=intro
然后我在网格中添加了按钮,每个按钮都叫做self.b,这让Stack Overflow上的一些人感到很困惑。你很快就会看到评论。
self.b = Button(self.frame, bg="red", fg="white", font=("Helvetica", 14), text = ' \n confilextracter \n ', command = self.openFile1)
self.b.grid(row = 1, column=0)
self.b = Button(self.frame, bg="red", fg="white", font=("Helvetica", 14), text = ' \n confileditor \n ', command = self.openFile2)
self.b.grid(row = 1, column=1)
self.b = Button(self.frame, bg="red", fg="white", font=("Helvetica", 14), text = ' \n confilerehasher \n ', command = self.openFile3)
self.b.grid(row = 1, column=2)
self.b = Button(self.frame, bg="red", fg="white", font=("Helvetica", 14), text = ' \n Turn off the Shed \n ', command = self.openFile4)
self.b.grid(row = 1, column=3)
self.frame.grid()
接下来,我需要给这些按钮分配任务,重命名exe文件让Stack Overflow上的一些人感到困惑,真抱歉。
def openFile1(self):
os.startfile("confilextracter.exe")
def openFile2(self):
os.startfile("confileditor.exe")
def openFile3(self):
os.startfile("confilerehasher.exe")
我真的想修正最后一个按钮的代码,我自己找到了答案,因为其他人都忙着处理代码的其他部分,稍后你会看到。此时这个按钮的代码是有错误的。
def openFile4(self):
self.b.configure(command = self.b.destroy)
然后我关闭了文件。
root = Tk()
app = App(root)
mainloop()
2 个回答
这是我让事情运作起来的方法, 我参考了f3ar3dlegend的示例代码(向上滚动查看),并开始在此基础上进行修改,因为它运行得相当不错。我们先从代码的顶部开始讲解,然后逐步深入,进行全面分析。
from Tkinter import *
from PIL import Image, ImageTk
import os
首先,使用“from Tkinter import”这行代码是告诉Python加载图形用户界面(GUI)的驱动程序。“from PIL import Image, ImageTk”则是告诉Python加载图像库,这样我们就可以使用彩色照片了。“import os”这行代码是我理解的,用来加载驱动程序,让Python能够从应用程序外部调用其他程序。
我做的第一件事就是在f3ar3dlegend的代码中添加了一张图片,以便为用户提供一个信息页面,使用了这段代码,
class App:
def __init__(self, master):
self.frame = Frame(master)
img = Image.open("data.gif")
intro = ImageTk.PhotoImage(img)
right = Label(None, image=intro)
right.grid(row=0, column=0, columnspan=4)
right.image=intro
有一行代码让我花了整整24小时才让我的图片显示出来,原因只是因为缺少了一段代码。
right.image=intro
这一行代码的作用是防止你的图片被垃圾回收(虽然我不太明白这是什么意思),但我知道我添加了它后,放在一个函数里面的照片就能显示出来了。
接下来,我花了很多时间在按钮的格式上,比如宽度、大小、颜色和字体。使用self.frame完全是靠猜,我不断尝试不同的想法,直到其中一个成功了。我还把整个界面放在了Python Tkinter的网格布局中,所以图片放在了第0行,跨越了4或5列,为更多的按钮留出空间。这些按钮都放在了第1行,而不是第0行。我发现只要命令指向不同的函数,我就可以把所有按钮命名为self.b,这样代码就没有错误了。
self.b = Button(self.frame, bg="darkred", width=18, fg="white", font=("Arial", 14), text = ' \n confilextracter \n ', command = self.openFile1)
self.b.grid(row = 1, column=0)
self.b = Button(self.frame, bg="red", width=17, fg="white", font=("Arial", 14), text = ' \n confileditor \n ', command = self.openFile2)
self.b.grid(row = 1, column=1)
接下来我做的是定义函数,因为按钮没有这些是无法工作的。让我在Stack Overflow上被误认为上传病毒的原因是我把程序的名称改了,以便更好地理解我的编程。
def openFile1(self):
os.startfile("confilextracter.exe")
def openFile2(self):
os.startfile("confileditor.exe")
它的工作原理是这样的:openFile1是一个按钮的调用。当你按下按钮时,它会发出一个调用,匹配的函数会响应这个调用。os.startfile对我来说是个新名词,但它的意思很简单,就是操作系统启动文件。("confileditor.exe")是说你需要的文件名在(" ")之间,把这两部分结合起来,文件就会在自己的窗口中运行。
我把这个软件的最后部分拼凑在一起,然后意识到我可以做更多的事情。我又开始使用f3ar3dlegend的示例代码。
root = Tk()
app = App(root)
mainloop()
这基本上是关闭所有东西,让Python知道是时候显示内容了,而mainloop则是告诉Tkinter等待我进行操作。问题是软件有时会在页面的一半打开,有时又会在屏幕的其他地方,所以我添加了这段代码,把软件放在屏幕的左上角。
app = App(root)
root.geometry('+0+0')
mainloop()
我做的最后一件事是添加一个按钮,可以在点击时退出软件。经过5或6次尝试,我终于让Tkinter在按下按钮时关闭软件窗口。代码是。
self.b = Button(self.frame, bg="red", width=18, fg="white", font= ("Arial", 14), text = ' \n Turn off the Shed \n ', command = self.openFile4)
self.b.grid(row = 1, column=3)
def openFile4(self):
root.destroy()
我在Stack Overflow上看到无数人错误使用root.destroy,难怪我花了一个小时才把它调整到位。 我学到的一个非常重要的教训是,如果你想把程序放到网上让别人下载,你需要联系你主机的客户支持,要求他们提供服务条款(TOS)的链接,因为如果你不理解这些条款,你可能会违反与发布相关的国际法律。谢谢。
使用 os
模块:
from Tkinter import *
import os
class App:
def __init__(self, master):
self.frame = Frame(master)
self.b = Button(self.frame, text = 'Open', command = self.openFile)
self.b.grid(row = 1)
self.frame.grid()
def openFile(self):
os.startfile(_filepath_)
root = Tk()
app = App(root)
root.mainloop()