Python子进程在cx_freeze之后无法正常工作

问题描述 投票:1回答:2

这是关于堆栈溢出的第一个问题! 我目前正在编写一个Python脚本(实际上是一些脚本)来管理书籍集合,我现在想要冻结和分发(这是我的第一个'大'项目)。在查看了许多选项后,我决定尝试使用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窗口然后......就是这样。我会非常感谢任何建议!!谢谢 :)

python-3.x subprocess cx-freeze
2个回答
0
投票

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


0
投票

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

是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()

该脚本在使用cx_freeze冻结后打开的新窗口中读取并显示“text.txt”的内容。

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")]
        )
© www.soinside.com 2019 - 2024. All rights reserved.