Упакованное кивое приложение открывает новые окна при многопоточности - PullRequest
0 голосов
/ 09 марта 2019

Я что-то сделал с 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 появляются без перерыва.Но это происходит только в том случае, если я упаковываю его в исполняемый файл, теперь, когда скрипт выполняется нормально.Я следовал этому руководству и получил следующий файл спецификации:

# -*- 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, но я не знаю, как это исправить.

Редактировать: Iподтвердили это с помощью:

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

YAY появляется несколько раз после нажатия клавиши.Короче говоря, есть ли способ заставить правильно работать упакованный скрипт?

1 Ответ

0 голосов
/ 09 марта 2019
if __name__ == "__main__":
    multiprocessing.freeze_support()

Это должны быть первые строки, которые запускаются в основном скрипте.Сценарий по-прежнему использует все необходимые потоки, но правильно работает с exe.

...