Python py2exe窗口显示(tkinter)

mop*_*iok 5 python tkinter py2exe

我正在尝试用py2exe创建一个exe.该程序使用Tkinter显示一个类似弹出窗口.问题是,当我像这样运行设置时一切正常:

setup(windows = [{'script': "msg.py"}], zipfile = None)
Run Code Online (Sandbox Code Playgroud)

但是当我尝试制作一个单文件时它失败了:

setup(windows = [{'script': "msg.py"}], zipfile = None, options = {'py2exe': {'bundle_files': 1, 'compressed': True}})
Run Code Online (Sandbox Code Playgroud)

实际上最终的exe运行没有问题,但它没有显示任何窗口.我已经读过在Windows 7上可能存在bundle_files = 1的问题,但我也尝试了bundle_files = 2具有相同的效果.这是我的msg.py脚本:

from win32gui import FindWindow, SetForegroundWindow
from Image import open as iopen
from ImageTk import PhotoImage
from Tkinter import Tk, Label
from threading import Timer
from subprocess import Popen
import os

def Thread(t, fun, arg=None):
    if arg<>None: x = Timer(t, fun, arg)
    else: x = Timer(t, fun)
    x.daemon = True
    x.start()

def NewMessage():
    global root
    if not os.path.exists('dane/MSG'):
        open('dane/MSG', 'w').write('')
        root = Tk()
        img = PhotoImage(iopen("incl/nowa.png"))
        label = Label(root, image=img)
        label.image = img
        label.bind("<Button-1>", Click)
        label.pack()
        root.geometry('-0-40')
        root.wm_attributes("-topmost", 1)
        root.overrideredirect(1)
        root.mainloop()

def Click(event):
    global root, exit
    root.destroy()
    os.remove('dane/MSG')
    OpenApp()
    exit = True

def OpenApp():
    hwnd = FindWindow(None, 'My program name')
    if hwnd: SetForegroundWindow(hwnd)
    else: Popen('app.exe')

root, exit = None, False
NewMessage()
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?我已经读过Tkinter有一些问题,但是有关于编译的问题.我的脚本已编译,它不会抛出任何异常,但不会显示窗口...

smo*_*ont 9

我最终遇到了同样的问题,我的解决方案包括执行以下操作:

"dll_excludes": ["tcl85.dll", "tk85.dll"],

在你的 options = {...}

然后手动复制这两个DLL

PYTHON_PATH\DLLs\(在我的情况下C:\Python27\DLLs)

到exe的位置并尝试运行它.


Mic*_*sen 5

dll_excludes和手动复制的替代方法是修补py2exe,以便知道这些文件必须直接放在dist目录中.

在build_exe.py中,有一个名为的类py2exe,其中包含dlls_in_exedir必须去的dll 列表.此列表在名为的函数期间设置plat_prepare,您可以将tclXX.dll和tkXX.dll文件添加到其中以确保正确复制它们.

当然,除非你是唯一一个能够构建它的人,否则你不一定知道需要捆绑哪个Tcl和Tk版本 - 有些人可能自己构建了Python,或者使用较旧的Python和较旧的DLL.因此,您需要检查系统实际​​使用的版本.py2exe实际上已经这样做了在不同的地方:通过导入内部_tkinter模块(实际Tk的接口,通常是一个DLL)和访问TK_VERSIONTCL_VERSION,然后你就可以用它来生成并添加正确的文件名.

如果其他人应该构建你的应用程序,你可能不想让他们修改他们的py2exe安装,所以这里是你如何从你的setup.py monkeypatch它:

import py2exe
py2exe.build_exe.py2exe.old_prepare = py2exe.build_exe.py2exe.plat_prepare
def new_prep(self):
  self.old_prepare()
  from _tkinter import TK_VERSION, TCL_VERSION
  self.dlls_in_exedir.append('tcl{0}.dll'.format(TCL_VERSION.replace('.','')))
  self.dlls_in_exedir.append('tk{0}.dll'.format(TK_VERSION.replace('.','')))
py2exe.build_exe.py2exe.plat_prepare = new_prep
Run Code Online (Sandbox Code Playgroud)

这甚至适用bundle_files=1于Windows 7.