5

py2exeでexeを作成しようとしています。プログラムは、Tkinterを使用してポップアップのようなウィンドウを表示しています。問題は、次のようなセットアップを実行すると、すべてが正常に機能することです。

setup(windows = [{'script': "msg.py"}], zipfile = None)

しかし、1ファイルのexeを作成しようとすると失敗します。

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

実際、最終的なexeは問題なく実行されますが、ウィンドウは表示されません。Windows7では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()

何か案は?Tkinterにはいくつか問題があると読みましたが、コンパイルについては問題がありました。私のスクリプトはコンパイルされており、例外はスローされませんが、ウィンドウは表示されません...

4

3 に答える 3

9

私はこれと同じ問題に遭遇することになりました、私の解決策は以下を行うことを含みました:

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

あなたの中でoptions = {...}

次に、これら2つのDLLを手動でコピーします。

PYTHON_PATH\DLLs\(私の場合C:\Python27\DLLs

exeの場所に移動し、実行してみてください。

于 2013-01-28T16:34:26.797 に答える
5

dll_excludesと手動コピーの代わりに、py2exeにパッチを適用して、これらのファイルをdistディレクトリに直接配置する必要があることを確認することもできます。

build_exe.pyの中には、そこに行かなければならないdllpy2exeのリストを含むというクラスがあります。dlls_in_exedirこのリストは、という名前の関数で設定され、plat_preparetclXX.dllファイルとtkXX.dllファイルを追加して、正しくコピーされていることを確認できます。

もちろん、これをビルドするのがあなただけでない限り、バンドルする必要のあるTclとTkのバージョンが必ずしもわかりません。誰かが自分でPythonをビルドしたか、古いDLLで古いPythonを使用している可能性があります。したがって、システムが実際に使用しているバージョンを確認する必要があります。py2exeは、実際にはすでに別の場所でこれを行っています。内部_tkinterモジュール(実際のTkインターフェイス、通常はDLL)をインポートし、にアクセスTK_VERSIONしてTCL_VERSION、正しいファイル名を生成および追加するために使用できます。

他の人があなたのアプリケーションを構築することになっている場合、おそらく彼らに彼らのpy2exeインストールを変更させたくないので、setup.pyからモンキーパッチを適用する方法は次のとおりです。

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

これbundle_files=1はWindows7でも機能します。

于 2013-08-01T16:20:33.483 に答える
1

バージョンが1つしかない場合は、data_fileを介してファイルをコピーできます。完全な例の下:

  • WinXP
  • Python2.7.6
  • tk8.5
  • tcl8.5
  • tix8.4.3
  • py2exe 0.6.9

foo.py:

# -*- coding: iso-8859-1 -*-
import Tkinter
"""
sets TCL_LIBRARY, TIX_LIBRARY and TK_LIBRARY - see installation Lib\lib-tk\FixTk.py
"""
Tkinter._test()

Setup.py:

# -*- coding: iso-8859-1 -*-
from distutils.core import setup
import py2exe
import sys
import os
import os.path
sys.argv.append ('py2exe')
setup (
    options    = 
        {'py2exe': 
            { "bundle_files" : 1    # 3 = don't bundle (default) 
                                     # 2 = bundle everything but the Python interpreter 
                                     # 1 = bundle everything, including the Python interpreter
            , "compressed"   : False  # (boolean) create a compressed zipfile
            , "unbuffered"   : False  # if true, use unbuffered binary stdout and stderr
            , "includes"     : 
                [ "Tkinter", "Tkconstants"

                ]
            , "excludes"      : ["tcl", ]
            , "optimize"     : 0  #-O
            , "packages"     : 
                [ 
                ]
            , "dist_dir"     : "foo"
            , "dll_excludes": ["tcl85.dll", "tk85.dll"]
            ,               
            }
        }
    , windows    = 
        ["foo.py"
        ]
    , zipfile    = None
    # the syntax for data files is a list of tuples with (dest_dir, [sourcefiles])
    # if only [sourcefiles] then they are copied to dist_dir 
    , data_files = [   os.path.join (sys.prefix, "DLLs", f) 
                   for f in os.listdir (os.path.join (sys.prefix, "DLLs")) 
                   if  (   f.lower ().startswith (("tcl", "tk")) 
                       and f.lower ().endswith ((".dll", ))
                       )
                    ] 

    , 
)
于 2014-05-27T20:10:24.733 に答える