【问题标题】:Packaged kivy application opens new windows when multithreading打包的 kivy 应用程序在多线程时打开新窗口
【发布时间】:2019-03-09 15:43:57
【问题描述】:

我用 Kivy 做了一些东西,这里是核心代码:

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.lang import Builder

class UI(Widget):
    pass

class UIApp(App):
    def build(self):
        Window.bind(on_key_down=self.key_action)
        return UI()

    def key_action(self, *args):
        self.process()

    def on_start(self, **kwargs):
        pass

    def on_stop(self):
        raise SystemExit(0)

    def process(self):
        OtherFile.test()

if __name__ == "__main__":
    Builder.load_file('UI.kv')
    from kivy.core.window import Window
    UIApp().run()

如您所见,我需要导入窗口来获取键盘挂钩。

OtherFile.test() 然而使用多线程。当这种情况发生时,新的 Kivy 窗口会不停地弹出。但只有当我将它打包成 exe 时才会发生这种情况,现在脚本正常执行。我已关注this guide 并拥有以下规范文件:

# -*- mode: python -*-

import sys
from os import path
site_packages = next(p for p in sys.path if 'site-packages' in p)
from kivy.deps import sdl2, glew

block_cipher = None


a = Analysis(['Main.py'],
             pathex=['C:\\Users\\GFuel\\PycharmProjects\\proj'],
             binaries=[],
             datas=[],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          [],
          exclude_binaries=True,
          name='AppName',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          console=True )
coll = COLLECT(exe, Tree('C:\\Users\\GFuel\\PycharmProjects\\proj'),
               a.binaries,
               a.zipfiles,
               a.datas,
               *[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)],
               strip=False,
               upx=True,
               name='AppName')

我用PyInstaller AppName.spec -windowed -singlefile 编译。窗口本身工作正常:

[INFO   ] [Window      ] auto add sdl2 input provider
[INFO   ] [Window      ] virtual keyboard not allowed, single mode, not docked
[INFO   ] [Text        ] Provider: sdl2
[INFO   ] [GL          ] NPOT texture support is available
[INFO   ] [Base        ] Start application main loop

但只要我按下一个键,就会打开越来越多的窗口。我的猜测是,出于某种原因,__name____main__,即使由于 PyInstaller 不应该(在多处理期间),但我不知道如何解决它。

编辑:我已经证明了这一点:

if __name__ == "__main__":
    print("YAY")
    from kivy.lang import Builder
    from kivy.core.window import Window
    Builder.load_file('UI.kv')
    UIApp().run()

在我按下一个键后,YAY 出现了好几次。那么简而言之,有没有办法让打包好的脚本正常工作呢?

【问题讨论】:

    标签: python kivy pyinstaller python-pool


    【解决方案1】:
    if __name__ == "__main__":
        multiprocessing.freeze_support()
    

    这些必须是在主脚本中运行的第一行。该脚本仍然使用它应该使用的所有线程,但可以与 exe 一起正常工作。

    【讨论】:

      猜你喜欢
      • 2019-06-25
      • 1970-01-01
      • 2012-10-28
      • 2014-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-27
      • 1970-01-01
      相关资源
      最近更新 更多