tkinter实现python转exe小工具

tkinter系列日常传送门:

        tkinter python2exe小工具

        tkinter2048

        tkinter桌面时钟

有时我们写了个python程序, 想分(zhuang)享(bi)给别人,问题是别人电脑上没装python,这时我们就回去考虑把python编译成exe。比较常见的是pyinstaller 和 py2exe(只支持python2,不建议)(这里就不详细介绍了)

pyinstaller安装方法:pip install pyinstaller(需要先安装pywin32)

这种方法有个很大的弊端:要么调整环境变量,要么每次都要找路径

于是我就写了一个tkinter app 来实现文件转移和图形化界面的功能

本软件还有很多不足,包括添加图标等等,欢迎评论(本人业余爱好,大神请勿吐槽)

上图片:

 制作过程:

首先初始化,包括4个按钮

#需要安装tkinter, pywin32, pyinstaller
#里面注释打*的需要自行调整路径

from tkinter import ttk
import threading
import tkinter,time
import glob
import shutil
from tkinter import *
from tkinter import filedialog
from tkinter import messagebox
import os,pywintypes,pythoncom

#文件路径
#pyinstaller默认放在scripts文件夹而不是site-packages下面
#编译时默认编译到运行位置
#在cmd里运行时在pyinstaller.exe的文件夹下面

PATH,nameq=os.path.split(__file__)
root=Tk()
root.title="Python to exe v2.0.0"
root.geometry("500x500")
sh=[]

if not "C:\\Users\\gino\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python39\\Scripts\\" in os.environ["PATH"]:
    #设置环境变量
    ### *路径自行调整
    os.system(f"PATH={os.environ['PATH']};C:\\Users\\gino\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python39\\Scripts")


btn2=Button(root,text="Compile All to",anchor="center",state="disabled",width=20)
btn4=Button(root,text="Delete last",anchor="center",state="disabled",width=20)
btn3=Button(root,text="Delete All",anchor="center",state="disabled",width=20)
tmp=[]

按钮,菜单和函数设置

#函数
def q(event=""):  #退出
    root.quit()

def cfile():   #选择文件
    #cav.delete(a)
    
    tmpw=filedialog.askopenfilename(parent=root,filetypes=[('Python File', '*.py'),("Python File (No Console)", "*.pyw"),("All Files","*.*")],initialdir="C:/",title='Choose a python file')
    
    if tmp.count(tmpw)>0:
        messagebox.showwarning("ERROR","filesys.repeatedfileerror: Repeated File")
    elif len(tmpw)!=0 and tmpw!=None:
        tmp.append(tmpw)
        w=cav.create_text(len(tmp[len(tmp)-1])*2.5+60,20*len(tmp),text=tmp[len(tmp)-1],fill="black")
        sh.append(w)
    
    if len(tmp)>0:
        btn3.config(state="active")
        btn2.config(state="active")
        btn4.config(state="active")



def reset():       #删除所有文件
    
    if (len(sh)==0):
        messagebox.showerror("ERROR","compiler.fileerror: empty file list")
        return 0    
    t=len(sh)
    for i in range(0,t):
        cav.delete(sh[i])
    tmp.clear()
    sh.clear()
    if len(tmp)<=0:
        btn3.config(state="disabled")
        btn2.config(state="disabled")
        btn4.config(state="disabled")
        
        
         
def delast():      #删除最后一个文件
    
    if (len(sh)==0):
        messagebox.showerror("ERROR","compiler.fileerror: empty file list")
        return 0
    cav.delete(sh[len(sh)-1])
    if len(sh):
        sh.pop()
        tmp.pop()
    if len(sh)<=0:
        btn3.config(state="disabled")
        btn2.config(state="disabled")
        btn4.config(state="disabled") 
    
    
    
def cato():      #编译所有文件
    if (len(sh)==0):
        messagebox.showerror("ERROR","compiler.fileerror: empty file list")
        return 0    
    #os.system("cd C:\\Users\\gino\\")
    tmpw=filedialog.askdirectory()
    progressbarOne = ttk.Progressbar(root, length=200, mode='indeterminate', orient=tkinter.HORIZONTAL)
    progressbarOne.pack(padx=5,pady=5)    
    def wr(tmpw):
        t1=time.time()
        for i in tmp:
            if " " in i:
                messagebox.showerror("ERROR","filesys.readfileerror: Space in filename")
                continue
            os.system(f"C:\\Users\\gino\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python39\\Scripts\\pyinstaller.exe -F -w {i}") 
            ###  *路径自行调整,默认只需调整用户名"gino"
        filelist=glob.glob(f"{PATH}\\dist\*")
        dflist=glob.glob(f"{PATH}\\*.spec")
        for f in filelist:
            fpath,fname=os.path.split(f)
            shutil.move(f,tmpw+"\\"+fname)
        for f in dflist:
            os.remove(f)
        t2=time.time()
        progressbarOne.stop()
        messagebox.showinfo("INFO",f"EXE build of total {len(sh)} finished in {t2-t1} sec")
        progressbarOne.destroy()
    
    tw1=threading.Thread(target=progressbarOne.start,args=())
    tw2=threading.Thread(target=wr,args=(tmpw,))
    tw1.setDaemon(daemonic=tw2)
    tw1.start()
    tw2.start()
    
#菜单
menubar = Menu(root,activeborderwidth=3,tearoff=False)
menubar.add_command(label="Choose...",command=cfile)
menubar.add_command(label="Delete All",command=reset)
menubar.add_command(label="Delete Last file",command=delast)
menubar.add_command(label="Compile All...",command=cato)
menubar.add_command(label="Quit",command=q)

def xShowMenu(event):
    menubar.post(event.x_root, event.y_root)   

root.bind("<Button-3>", xShowMenu)
root.bind("<Control-Q>",q)
root.bind("<Control-q>",q)

btn3.config(command=reset)
btn4.config(command=delast)
btn2.config(command=cato)
btn=Button(root,text="Choose a python file",anchor="center",command=cfile,width=20)

文件显示区代码:

#文件显示区
frame = Frame(root, bd=4, relief=SUNKEN,background="white")
frame.grid_rowconfigure(0, weight=1)
frame.grid_columnconfigure(0, weight=1)
yscroll = Scrollbar(frame)
yscroll.grid(row=0, column=1, sticky=N+S)
cav = Canvas(frame, bd=0, yscrollcommand=yscroll.set,cursor="circle")
cav.grid(row=0, column=0, sticky=N+S+E+W)
yscroll.config(command=cav.yview)
frame.pack(fill=BOTH,expand=1)

启动!!!

#启动
cav.pack
btn.pack()
btn4.pack()
btn3.pack()
btn2.pack()   
root.mainloop()

总代码:

#需要安装tkinter, pywin32, pyinstaller
#里面注释打*的需要自行调整路径

from tkinter import ttk
import threading
import tkinter,time
import glob
import shutil
from tkinter import *
from tkinter import filedialog
from tkinter import messagebox
import os,pywintypes,pythoncom

#文件路径
#pyinstaller默认放在scripts文件夹而不是site-packages下面
#编译时默认编译到运行位置
#在cmd里运行时在pyinstaller.exe的文件夹下面

PATH,nameq=os.path.split(__file__)
root=Tk()
root.title="Python to exe v2.0.0"
root.geometry("500x500")
sh=[]

if not "C:\\Users\\gino\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python39\\Scripts\\" in os.environ["PATH"]:
    #设置环境变量
    ### *路径自行调整
    os.system(f"PATH={os.environ['PATH']};C:\\Users\\gino\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python39\\Scripts")


btn2=Button(root,text="Compile All to",anchor="center",state="disabled",width=20)
btn4=Button(root,text="Delete last",anchor="center",state="disabled",width=20)
btn3=Button(root,text="Delete All",anchor="center",state="disabled",width=20)
tmp=[]

#函数
def q(event=""):  #退出
    root.quit()

def cfile():   #选择文件
    #cav.delete(a)
    
    tmpw=filedialog.askopenfilename(parent=root,filetypes=[('Python File', '*.py'),("Python File (No Console)", "*.pyw"),("All Files","*.*")],initialdir="C:/",title='Choose a python file')
    
    if tmp.count(tmpw)>0:
        messagebox.showwarning("ERROR","filesys.repeatedfileerror: Repeated File")
    elif len(tmpw)!=0 and tmpw!=None:
        tmp.append(tmpw)
        w=cav.create_text(len(tmp[len(tmp)-1])*2.5+60,20*len(tmp),text=tmp[len(tmp)-1],fill="black")
        sh.append(w)
    
    if len(tmp)>0:
        btn3.config(state="active")
        btn2.config(state="active")
        btn4.config(state="active")



def reset():       #删除所有文件
    
    if (len(sh)==0):
        messagebox.showerror("ERROR","compiler.fileerror: empty file list")
        return 0    
    t=len(sh)
    for i in range(0,t):
        cav.delete(sh[i])
    tmp.clear()
    sh.clear()
    if len(tmp)<=0:
        btn3.config(state="disabled")
        btn2.config(state="disabled")
        btn4.config(state="disabled")
        
        
         
def delast():      #删除最后一个文件
    
    if (len(sh)==0):
        messagebox.showerror("ERROR","compiler.fileerror: empty file list")
        return 0
    cav.delete(sh[len(sh)-1])
    if len(sh):
        sh.pop()
        tmp.pop()
    if len(sh)<=0:
        btn3.config(state="disabled")
        btn2.config(state="disabled")
        btn4.config(state="disabled") 
    
    
    
def cato():      #编译所有文件
    if (len(sh)==0):
        messagebox.showerror("ERROR","compiler.fileerror: empty file list")
        return 0    
    #os.system("cd C:\\Users\\gino\\")
    tmpw=filedialog.askdirectory()
    progressbarOne = ttk.Progressbar(root, length=200, mode='indeterminate', orient=tkinter.HORIZONTAL)
    progressbarOne.pack(padx=5,pady=5)    
    def wr(tmpw):
        t1=time.time()
        for i in tmp:
            if " " in i:
                messagebox.showerror("ERROR","filesys.readfileerror: Space in filename")
                continue
            os.system(f"C:\\Users\\gino\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python39\\Scripts\\pyinstaller.exe -F -w {i}") 
            ###  *路径自行调整,默认只需调整用户名"gino"
        filelist=glob.glob(f"{PATH}\\dist\*")
        dflist=glob.glob(f"{PATH}\\*.spec")
        for f in filelist:
            fpath,fname=os.path.split(f)
            shutil.move(f,tmpw+"\\"+fname)
        for f in dflist:
            os.remove(f)
        t2=time.time()
        progressbarOne.stop()
        messagebox.showinfo("INFO",f"EXE build of total {len(sh)} finished in {t2-t1} sec")
        progressbarOne.destroy()
    
    tw1=threading.Thread(target=progressbarOne.start,args=())
    tw2=threading.Thread(target=wr,args=(tmpw,))
    tw1.setDaemon(daemonic=tw2)
    tw1.start()
    tw2.start()
    
#菜单
menubar = Menu(root,activeborderwidth=3,tearoff=False)
menubar.add_command(label="Choose...",command=cfile)
menubar.add_command(label="Delete All",command=reset)
menubar.add_command(label="Delete Last file",command=delast)
menubar.add_command(label="Compile All...",command=cato)
menubar.add_command(label="Quit",command=q)

def xShowMenu(event):
    menubar.post(event.x_root, event.y_root)   

root.bind("<Button-3>", xShowMenu)
root.bind("<Control-Q>",q)
root.bind("<Control-q>",q)

btn3.config(command=reset)
btn4.config(command=delast)
btn2.config(command=cato)
btn=Button(root,text="Choose a python file",anchor="center",command=cfile,width=20)

#文件显示区
frame = Frame(root, bd=4, relief=SUNKEN,background="white")
frame.grid_rowconfigure(0, weight=1)
frame.grid_columnconfigure(0, weight=1)
yscroll = Scrollbar(frame)
yscroll.grid(row=0, column=1, sticky=N+S)
cav = Canvas(frame, bd=0, yscrollcommand=yscroll.set,cursor="circle")
cav.grid(row=0, column=0, sticky=N+S+E+W)
yscroll.config(command=cav.yview)
frame.pack(fill=BOTH,expand=1)

#启动
cav.pack
btn.pack()
btn4.pack()
btn3.pack()
btn2.pack()   
root.mainloop()

效果图: 

自己编译自己!

 演示视频

202207091608

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
exe自定义工具箱源码,指的是使用编程语言编写的一个可执行文件,通过运行该程序可以实现各种定制化的工具箱功能。 首先,需要选择编程语言和开发平台。常用的编程语言有Java、C++、Python等,而开发平台可以选择Visual Studio、Eclipse等。根据自己的编程经验和需求选择合适的语言和平台。 接下来,我们需要确定工具箱的功能和界面设计。根据需求,可以包括文件管理、图像处理、文本编辑等各种功能。可以使用各种API和库来实现这些功能,如Python的os模块、Pillow库等。 编写源码时,需要按照设计好的功能和界面逐步实现。首先要进行必要的初始化操作,例如创建主窗口、导入所需的库等。然后,根据需求实现各个功能的函数或类。 如果工具箱需要有用户交互界面,可以使用图形界面库来实现。如PythonTkinter库、Java的Swing库等。可以设计菜单栏、按钮等控件,并设置对应的事件处理函数。 在编写过程中,要注意处理用户输入和异常情况,确保程序的稳定性和可靠性。可以使用条件语句、循环结构来控制程序的流程,并根据具体需求进行调试和优化。 编写完源码后,可以进行编译和打包等操作,生成可执行文件。随后,可以通过运行该exe文件,来体验自定义工具箱的各种功能。 总结来说,编写exe自定义工具箱源码需要选择合适的编程语言和开发平台、确定功能和界面设计,使用相应的API和库来实现功能,编写相应的代码,处理用户输入和异常情况,最后生成可执行文件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值