python+tkinter+nuitka 打包单个可执行exe文件(PyInstaller比nuitka更稳定)

1.使用py+tk完成 简单图形化脚本

# coding = utf-8
import tkinter as tk
from tkinter.scrolledtext import *
import tkinter.messagebox
import requests
import time
import json

clickCount = 0

# 清理结果集数据
def clearRes():
    # 清理数据
    resText.delete(1.0, "end")

def httpGet(url):
    response = requests.request("get", url)
    return response


# 获取文本空中内容
def getSourceText():
    source = sourceText.get(1.0, "end")
    nameList = source.split('\n')
    res = []
    for name in nameList:
        # 去首尾空格
        s = name.strip()
        if s:
            res.append(s)
    return res

# 获取文本空中内容
def getSourceText2():
    source = sourceText2.get(1.0, "end")
    nameList = source.split('\n')
    res = []
    for name in nameList:
        # 去首尾空格
        s = name.strip()
        if s:
            res.append(s)
    return res



#  判断 多数据中 重复名称
def getRepeat():
    clearRes()
    # 读取文本框数据
    nameList = getSourceText()
    if len(nameList) < 1:
        contentVar.set('无数据')
        return
    distinct = []
    repeat = []
    for i in nameList:
        if i in distinct:
            # print(i)
            repeat.append(i)
            # 在文本框内容最后接着插入输入内容
            resText.insert('end', i + "\n")
        else :
            distinct.append(i)
    contentVar.set('总数:%s' %(len(repeat)))



#  左边比右边多的
def compareGT():
    clearRes()
    # 读取文本框数据
    nameList = getSourceText()
    nameList2 = getSourceText2()
    if len(nameList) < 1:
        contentVar.set('无数据')
        # if len(nameList2) < 1:
        #     contentVar.set('无数据')
        # else:
        #     contentVar.set('总数:%s' %(len(nameList2)))
    else:
        if len(nameList2) < 1:
            contentVar.set('总数:%s' %(len(nameList)))
        else:
            # 都有数据  判断 左边不存在右边的
            gtList = []
            for i in nameList:
                if i not in nameList2:
                    gtList.append(i)
                    resText.insert('end',i)
            contentVar.set('完成:%s' %(len(gtList)))


def clickNoneButton():
    clearRes()
    global clickCount
    clickCount = clickCount +1
    res = '您点击了%s次空白按钮' % clickCount
    resText.insert('end',res)
    contentVar.set('完成')

def msgBoxTest():
    tk.messagebox.showinfo(title='弹窗标题', message='弹了个窗')


# 显示当前时间
def getime(master):
    def getTime():
        global time1
        time1 = ''
        time2 = time.strftime('%Y-%m-%d %H:%M:%S')
        # 能动态显示系统时间
        if time2 != time1:
            time1 = time2
            timeVar.set("当前时间:"+time2)
            master.after(200,getTime)
    getTime()

def sortList():
    clearRes()
    nameList = getSourceText()
    if len(nameList) < 1:
        contentVar.set('无数据')
        return
    nameList.sort()
    for i in nameList:
        resText.insert('end',i + "\n")
    contentVar.set('已生成')
    return nameList

root = tk.Tk()
root.title("xxxxx小工具 v1.0")
root.geometry("560x500+250+80")

# # 创建一个菜单容器   -------------------------------
# menubar = tk.Menu(root)
# # 创建菜单按钮
# filemenu = tk.Menu(menubar, tearoff=0)
# # 将上面定义的空菜单命名为菜单,放在菜单栏中,就是装入那个容器中
# menubar.add_cascade(label='菜单', menu=filemenu)
# # 在File中加入New、Open、Save等小菜单,即我们平时看到的下拉菜单,每一个小菜单对应命令操作。
# filemenu.add_command(label='计数', command=clickNoneButton)
# # 创建二级
# submenu = tk.Menu(filemenu)
# filemenu.add_cascade(label='里面有二级菜单', menu=submenu, underline=0) # 给放入的菜单submenu命名为Import
# submenu.add_command(label='弹窗', command=msgBoxTest)   # 这里和上面创建原理也一样,在Import菜单项中加入一个小菜单命令Submenu_1
# # 第11步,创建菜单栏完成后,配置让菜单栏menubar显示出来
# root.config(menu=menubar)


sourceDest = tk.Label(text='选择环境:')
sourceDest.place(x=20, y=10)
# 选择环境  单选框
hj = tk.IntVar()
hj.set(1) # 默认选中测试环境
tk.Radiobutton(root,text='测试环境',variable=hj,value=1,).place(x=90, y=10)
tk.Radiobutton(root,text='生产环境',variable=hj,value=2,).place(x=170, y=10)


# 标题
sourceDest = tk.Label(text='入参列表:')
sourceDest.place(x=20, y=45)
sourceText = ScrolledText(root, width=25, height=8,font=("微软雅黑",11))  #滚动文本框(宽,高(这里的高应该是以行数为单位),字体样式)
sourceText.place(x=20, y=65)

# 标题
sourceDest2 = tk.Label(text='入参列表2:')
sourceDest2.place(x=300, y=40)
sourceText2 = ScrolledText(root, width=25, height=8,font=("微软雅黑",11))  #滚动文本框(宽,高(这里的高应该是以行数为单位),字体样式)
sourceText2.place(x=300, y=60)


# # 查重
buttontRepeat = tk.Button( text = '查重',width=13,command = getRepeat,fg = 'green')
buttontRepeat.place(x=300, y=270)

buttontRepeat = tk.Button( text = '空白按钮',width=13,command = clickNoneButton,fg = 'green')
buttontRepeat.place(x=420, y=270)

# 左边比右边多
buttonCheckReport = tk.Button( text = '左边比右多的',width=13,command = compareGT,fg = 'green')
buttonCheckReport.place(x=300, y=310)

# 无操作
buttonCheckReport = tk.Button( text = '无操作',width=13,command = None,fg = 'green')
buttonCheckReport.place(x=420, y=310)

# buttontRepeat = tk.Button( text = '查重',width=15,command = getRepeat,fg = 'green')
buttontRepeat = tk.Button( text = '弹窗',width=13,command = msgBoxTest,fg = 'green')
buttontRepeat.place(x=420, y=310)

# 功能未实现
buttonGetIdSQL = tk.Button( text = '功能未实现',width=13,command = None,fg = 'green')
# buttonGetIdSQL.place(x=265, y=140)
buttonGetIdSQL.place(x=300, y=350)

# 功能未实现
buttonCheckReport = tk.Button( text = '功能未实现',width=13,command = None,fg = 'green')
# buttonCheckReport.place(x=265, y=180)
buttonCheckReport.place(x=300, y=390)

# 排序
buttonCheckReport = tk.Button( text = '排序',width=13,command = sortList,fg = 'green')
buttonCheckReport.place(x=300, y=430)


# 标题   ---------------------------------------------------结果
resDest = tk.Label(text='结果:')
resDest.place(x=20, y=245)

# 结果展示
resText = ScrolledText(root, width=25, height=10,font=("微软雅黑",11))  #滚动文本框(宽,高(这里的高应该是以行数为单位),字体样式)
resText.place(x=20, y=265)

# 执行说明  结果
contentVar = tk.StringVar()
countDest = tk.Label(textvariable=contentVar)
countDest.place(x=20, y=473)

# 动态时间展示
timeVar = tk.StringVar()
cTime = tk.Label(textvariable=timeVar)
cTime.place(x=360, y=473)
# 执行说明  结果
getime(cTime)


root.mainloop()

2.使用nuitka打包成exe文件

nuitka:速度很快!  可编译 Python 代码到 C++ 程序,执行肯定快啊,   而且后续优化空间很大,未来可期。

    2.1安装nuitka

 pip install nuitka

    2.2 打包py脚本

 python -m nuitka --standalone --windows-disable-console --show-progress --plugin-enable=tk-inter --windows-icon-from-ico=.\myIco.ico  .\myTools.PY

第一次打包会下载C++编译器,命令行中下载超时,所以我自己下载了,放到对应的文件夹下

ccache-3.7.12-windows-32.zip  https://download.csdn.net/download/IT_Yl/15076363

depends22_x86.zip  https://download.csdn.net/download/IT_Yl/15077494

winlibs-i686-posix-dwarf-gcc-10.2.0-llvm-11.0.0-mingw-w64-8.0.0-r5.zip   https://download.csdn.net/download/IT_Yl/15076316

 

以下是常用命令,仅限入门使用

 --mingw64 #默认为已经安装的vs2017去编译,否则就按指定的比如mingw(官方建议)

--standalone 独立环境,这是必须的(否则拷给别人无法使用)

--windows-disable-console 没有CMD控制窗口

--output-dir=out 生成exe到out文件夹下面去

--show-progress 显示编译的进度,很直观

--show-memory 显示内存的占用

--include-qt-plugins=sensible,styles 打包后PyQt的样式就不会变了

--plugin-enable=qt-plugins 需要加载的PyQt插件

--plugin-enable=tk-inter 打包tkinter模块的刚需

--plugin-enable=numpy 打包numpy,pandas,matplotlib模块的刚需

--plugin-enable=torch 打包pytorch的刚需

--plugin-enable=tensorflow 打包tensorflow的刚需

--windows-icon-from-ico=你的.ico 软件的图标

--windows-company-name=Windows下软件公司信息

--windows-product-name=Windows下软件名称

--windows-file-version=Windows下软件的信息

--windows-product-version=Windows下软件的产品信息

--windows-file-description=Windows下软件的作用描述

--windows-uac-admin=Windows下用户可以使用管理员权限来安装

--linux-onefile-icon=Linux下的图标位置

--onefile 像pyinstaller一样打包成单个exe文件(2021年我会再出教程来解释)

--include-package=复制比如numpy,PyQt5 这些带文件夹的叫包或者轮子

--include-module=复制比如when.py 这些以.py结尾的叫模块

打包后文件夹样式

保留dist文件夹其他的可以删掉

dist文件夹目录中myTools.PY.exe  就是可以执行的文件了

 

3.将文件夹压缩成单个文件

3.1ctrl+a 选中文件夹中 所有文件

3.2右键添加到压缩文件

3.3勾选创建自解压压缩文件

3.4高级-自解压选型

3.5设置-自解压路径   C:\tmp\myTools

3.6设置-提取后运行  D:\xxxxxxx\xxxx.dict\myTools.PY.exe

3.7模式-全部隐藏

3.8更新-跳过已存在的文件

3.9确定

 

补充:使用Pyinstaller打包exe

使用pip命令安装:pip install PyInstaller

pyinstaller -F -w -i .\xxx.ico .\myTools.PY

-F 表示生成单个可执行文件
-w 表示去掉控制台窗口,这在GUI界面时非常有用。不过如果是命令行程序的话那就把这个选项删除吧!
-p 表示你自己自定义需要加载的类路径,一般情况下用不到
-i 表示可执行文件的图标

 

tk(tkinter)基础参考:

https://www.cnblogs.com/shwee/p/9427975.html

https://www.cnblogs.com/dongxiaodong/p/9971974.html

nuitka基础参考:

https://zhuanlan.zhihu.com/p/133303836?from_voters_page=true

https://www.zhihu.com/people/xuhui112-ben/posts

文件夹打包成单个可执行文件

http://www.zhuyibing.com/?id=91

 

  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
1. 安装pyinstaller ``` pip install pyinstaller ``` 2. 创建.spec文件 在命令行中进入程序根目录,执行以下命令 ``` pyinstaller -w -F main.py ``` - `-w`:表示使用窗口模式,不显示命令行窗口 - `-F`:表示打包单个执行文件 打包完成后会生成一个`main.spec`文件 3. 修改.spec文件 打开`main.spec`文件,修改以下内容: ``` a = Analysis(['main.py'], pathex=['路径'], binaries=[], datas=[('界面文件路径', '界面文件路径'), ('图片文件路径', '图片文件路径')], hiddenimports=[], hookspath=[], runtime_hooks=[], excludes=[], win_no_prefer_redirects=False, win_private_assemblies=False, cipher=block_cipher, noarchive=False) pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) exe = EXE(pyz, a.scripts, a.binaries, a.zipfiles, a.datas, [], name='程序名称', debug=False, bootloader_ignore_signals=False, strip=False, upx=True, upx_exclude=[], upx_include=[], runtime_tmpdir=None, console=True ) ``` - `路径`:为程序的绝对路径 - `界面文件路径`:为程序使用的界面文件的路径 - `图片文件路径`:为程序使用的图片文件的路径 - `程序名称`:为打包后的程序名称 - `console=True`:表示使用命令行模式,如果之前用`-w`表示使用窗口模式,则需要将此行改为`console=False` 4. 生成可执行文件 在命令行中进入程序根目录,执行以下命令 ``` pyinstaller main.spec ``` 打包完成后,可执行文件位于`dist`文件夹下。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值