Python cx_freeze 后 suprocess 不工作

Python suprocess not working after cx_freeze

这是我在 stack-overflow 上的第一个问题!
我目前正在编写一个 Python 脚本(嗯,实际上是一些脚本)来管理书籍 collections,我现在想冻结和分发它(这是我的第一个 'big' 项目)。 在查看了许多选项后,我决定尝试使用 Cx_Freeze。 (我正在使用 Python 3.6 和 Cx_Freeze 5.1.1)。

在这个项目中,我经常使用 'subprocess' 从一个脚本移动到另一个脚本。 在解释器中它工作得很好,如果我让 Cx_Freeze 使用

创建构建文件夹
python setup.py build

它也能正常工作,但是当我尝试使用

创建可分发文件时
python setup.py bdist_msi

安装后它会启动并运行到第一次调用子进程,然后仅此而已。

这里是setup.py

from cx_Freeze import setup, Executable
import os.path

PYTHON_INSTALL_DIR = os.path.dirname(os.path.dirname(os.__file__))
os.environ['TCL_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR, 'tcl', 'tcl8.6')
os.environ['TK_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR, 'tcl', 'tk8.6')
setup(
    name = "Libro",
    version = "1.0.0",
    options = {"build_exe": {
        'packages': ["tkinter", "subprocess", ],
        'include_files': [os.path.join(PYTHON_INSTALL_DIR, 'DLLs','tk86t.dll'), \
         os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tcl86t.dll'), \
        'logo50x50.gif', 'check_1.txt', 'check_2.txt', 'start.py', \ 
         'createdb.py', *and_a_few_more_files*],
    'include_msvcr': True,
    }},
executables = [Executable("Libro.py",base="Win32GUI")]

这是成为可执行文件的 Libro.py 脚本。

#This script checks the documents check_1 and check_2 and then launches
# createdb.py or start.py

import subprocess
from tkinter import *
import tkinter.messagebox as box

root= Tk()
root.withdraw()

with open('check_1.txt', 'r') as check_1:
    for line in check_1:
    line = line.strip()
    value_1 = int(line)

with open('check_2.txt', 'r') as check_2:
    for line in check_2:
    line = line.strip()
    value_2 = int(line)

if value_1 == 0 and value_2 == 0:
    box.showinfo('Libro 1.0', '''
    Welcome to the installation of Libro.
    I am now creating the database for your catalogue.
    This may take a moment.''')
    subprocess.call("createdb.py", shell=True)

else:
    subprocess.call("start.py", shell=True)
    root.mainloop()

它开始,它寻找 check_1 和 check_2,显示 tkinter showinfo window 然后...就是这样。 如果有任何建议,我将不胜感激!!谢谢:)

您需要冻结所有脚本,而不仅仅是顶级脚本! (创建多个 Executable() 条目)。然后调用 subprocess 到 运行 冻结的可执行文件。如果你不这样做,你最终会要求在目标机器上安装 Python——然后为什么要冻结其中的任何一个!当然,解释为什么您需要 运行 在子进程中而不是直接编写代码也可能会有所帮助。

最后看来,将我的脚本视为模块然后在需要时导入它们会更容易、更经济。 我尝试了一些简化的操作,它们似乎有效。 例如:

main.py

from tkinter import *
from modules import from_file

root = Tk()
root.title('Trial window')
btn_1 = Button(root, text='Read from file', command=from_file)
btn_1.grid(row=1, column=1)

正在modules.py

from tkinter import *

def from_file():
    ft = open('text.txt', 'r')
    string = ''
    for line in ft:
        line = line.strip()
        string = string+line
    ft.close()

    root2 = Tk()
    result = Label(root2, text=string)
    result.grid(row=1, column=1)
    root2.mainloop()

脚本在新 windows 中读取并可视化 'text.txt' 的内容,它在被 cx_freeze 冻结后也会打开。

PS我用的setup.py是

from cx_Freeze import setup, Executable
import os.path

PYTHON_INSTALL_DIR = os.path.dirname(os.path.dirname(os.__file__))
os.environ['TCL_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR, 'tcl', 'tcl8.6')
os.environ['TK_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR, 'tcl', 'tk8.6')

setup(
    name = "Prova",
    version = "1.0.0",
    options = {"build_exe": {
            'packages': ["tkinter"],
            'include_files' : [os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tk86t.dll'), \
            os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tcl86t.dll'), 'text.txt'],
            'include_msvcr': True,
            }},
        executables = [Executable("main.py", base="Win32GUI")]
        )