cxFreeze使用sc2reader库和多处理来打破Python应用程序

时间:2022-01-28 18:03:09

I'm working on porting an early version of a project to Windows and distributing it as a binary. The project so far has been developed in Arch Linux with Python 3.3, but I want to package it as a standalone binary in Windows order to reach a larger test audience. I've confirmed that the code runs as expected in Windows with Python 3.3.

我正在努力将项目的早期版本移植到Windows并将其作为二进制文件分发。到目前为止,该项目已在Arch Linux中使用Python 3.3开发,但我希望将其打包为Windows中的独立二进制文件,以便覆盖更大的测试受众。我已经确认代码在Windows中使用Python 3.3按预期运行。

Upon trying to compile it with cxfreeze, I run into some issues. First, the main library I use (sc2reader), contains data in the form of .csv files. In Windows, these files are located in \Python33\Lib\site-packages\sc2reader, but cxfreeze neglects to include them while including most of the .py files associated with sc2reader. Initially, the generated executable would crash immediately, complaining about these missing data files. After manually adding them (I couldn't get setup.py to include these files--cxfreeze wouldn't complain about any syntax errors, but it wouldn't include the files either), I got rid of these errors.

在尝试使用cxfreeze编译它时,我遇到了一些问题。首先,我使用的主库(sc2reader)包含.csv文件形式的数据。在Windows中,这些文件位于\ Python33 \ Lib \ site-packages \ sc2reader中,但是cxfreeze忽略了包含它们,同时包含与sc2reader关联的大多数.py文件。最初,生成的可执行文件会立即崩溃,抱怨这些丢失的数据文件。手动添加它们之后(我无法获得setup.py来包含这些文件--cxfreeze不会抱怨任何语法错误,但它也不会包含这些文件),我摆脱了这些错误。

My setup.py looks like this:

我的setup.py看起来像这样:

import sys

from cx_Freeze import setup, Executable

build_exe_options = {"include_files": ['C:\Python33\Lib\site-packages\sc2reader\data\']}

setup(
    name = "vroMAD",
    version = "0.1.0",
    executables = [Executable("__main__.py", base = "base")]

After manually copying files over, I at least got the binary to start. It draws the window correctly, but some of the behaviors are incorrect. Basic functions such file browsing and file selection work, but that's about it. There's a button in the window that executes a long task and paints a progress bar. Because this long task would block the GUI from updating, a second process is spawned whenever the user pushes this button. However, instead of proceeding with the task and updating the progress bar, the program creates a duplicate window. In fact, Task Manager shows an additional, identical process. The new window behaves exactly like the old one: it handles basic events correctly, but when the button is pushed, it spawns yet another window... which behaves in the same way.

手动复制文件后,我至少启动了二进制文件。它正确绘制窗口,但有些行为不正确。文件浏览和文件选择等基本功能,但就是这样。窗口中有一个按钮,用于执行长任务并绘制进度条。因为这个长任务会阻止GUI更新,所以每当用户按下此按钮时,就会产生第二个进程。但是,程序不是继续执行任务并更新进度条,而是创建一个重复的窗口。事实上,任务管理器显示了一个额外的,相同的过程。新窗口的行为与旧窗口完全相同:它正确处理基本事件,但是当按下按钮时,它会产生另一个窗口......其行为方式相同。

Does multiprocessing not work with cxfreeze?

多处理不适用于cxfreeze吗?

1 个解决方案

#1


1  

Are you calling multiprocessing.freeze_support?

你在调用multiprocessing.freeze_support吗?

Add support for when a program which uses multiprocessing has been frozen to produce a Windows executable. (Has been tested with py2exe, PyInstaller and cx_Freeze.)

添加对何时冻结使用多处理的程序以生成Windows可执行文件的支持。 (已经使用py2exe,PyInstaller和cx_Freeze进行了测试。)

One needs to call this function straight after the if __name__ == '__main__' line of the main module. For example:

需要在主模块的if __name__ =='__ main__'行之后直接调用此函数。例如:

from multiprocessing import Process, freeze_support

def f():
    print 'hello world!'

if __name__ == '__main__':
    freeze_support()
    Process(target=f).start()

If the freeze_support() line is omitted then trying to run the frozen executable will raise RuntimeError.

如果省略freeze_support()行,则尝试运行冻结的可执行文件将引发RuntimeError。

If the module is being run normally by the Python interpreter then freeze_support() has no effect.

如果Python解释器正常运行该模块,则freeze_support()无效。

Also, you are wrapping all the executing code in if __name__ == '__main__', right? multiprocessing behaves differently in that way on Windows vs Unix (because of the lack of fork()).

另外,如果__name__ =='__ main__',你将所有正在执行的代码包装好,对吧?多处理在Windows与Unix上的行为方式不同(因为缺少fork())。

#1


1  

Are you calling multiprocessing.freeze_support?

你在调用multiprocessing.freeze_support吗?

Add support for when a program which uses multiprocessing has been frozen to produce a Windows executable. (Has been tested with py2exe, PyInstaller and cx_Freeze.)

添加对何时冻结使用多处理的程序以生成Windows可执行文件的支持。 (已经使用py2exe,PyInstaller和cx_Freeze进行了测试。)

One needs to call this function straight after the if __name__ == '__main__' line of the main module. For example:

需要在主模块的if __name__ =='__ main__'行之后直接调用此函数。例如:

from multiprocessing import Process, freeze_support

def f():
    print 'hello world!'

if __name__ == '__main__':
    freeze_support()
    Process(target=f).start()

If the freeze_support() line is omitted then trying to run the frozen executable will raise RuntimeError.

如果省略freeze_support()行,则尝试运行冻结的可执行文件将引发RuntimeError。

If the module is being run normally by the Python interpreter then freeze_support() has no effect.

如果Python解释器正常运行该模块,则freeze_support()无效。

Also, you are wrapping all the executing code in if __name__ == '__main__', right? multiprocessing behaves differently in that way on Windows vs Unix (because of the lack of fork()).

另外,如果__name__ =='__ main__',你将所有正在执行的代码包装好,对吧?多处理在Windows与Unix上的行为方式不同(因为缺少fork())。