如何在 运行 命令时让加载 gif 工作

How to get a loading gif to work while running a command

我正在尝试在 运行 另一个 python 脚本时播放加载圈的 gif。

当我点击一个按钮时,我得到一个弹出窗口,其中有一个正在加载的 gif,在后台我想 运行 一个 python 脚本,同时这个 gif 加载。脚本完成后弹出窗口关闭。

到目前为止,除了 gif 在另一个 python 脚本启动后冻结外,所有这些都有效 运行ning。

我试过使用os.system()subprocess.run()和有争议的subprocess.Popen()。我也尝试过使用线程和多处理 python 模块。

线程似乎是可行的方法,但我仍然得到相同的结果(gif 在我启动 运行 另一个 python 脚本后冻结)。

我知道还有许多其他类似的问题,但是我可以向您保证我已经阅读了所有这些问题并尝试了他们的解决方案,但由于某些原因它们对我不起作用。我已经为此工作了好几天,但找不到解决方案,因此非常感谢您的帮助。

对于整体情况,我正在编写一个 python3.7 应用程序,使用 kivy 创建一个 GUI。我 运行 在 Raspberry Pi 4.

上安装此应用程序

以下是我当前相关代码的片段: (“...”表示其他无关代码在哪里)

main.py

class SetttingsWindow(Screen):
    def __init__(self, **kwargs):
        super(SettingsWindow, self).__init__(**kwargs)
        Clock.schedule_interval(self.check, 1)

    def check(self, dt):
        global wset
        if wset:
            self.start_thread()
        else:
            pass

    def start_thread(self):
        t = threading.Thread(target=self.connect)
        t.start()
        time.sleep(1)
        t.join()

    def connect(self):
        global wset
        os.system('sudo python /home/pi/app/connect.py')
        wset = False
        loadingPopup.dissmiss()

    def set(self):
        Popup.open()


class PopUp(FloatLayout):
    def __init__(self, **kwargs):
        super(PopUp, self).__init__(**kwargs)

    def change(self):
        global wset
        if ... :
            PopUp.dismiss()
        else:
            ...
            PopUp.dissmiss()
            wset = True

    def setLoad(self):
        loadingPopup.open()


class LoadingPopUp(FloatLayout):
    pass

main.kv

<SettingsWindow>
    ...
    Button:
        text: "Setup"
        on_release:
            root.set()
    ...
...
<PopUp>
    ...
    Button:
        text: "Set"
        on_release:
            root.change()
            root.setLoad()
    ...
...
<LoadingPopUp>
    Image:
        source: "loading.gif"
        anim_delay: 0.05
        keep_data: True

您的 check() 方法将在主线程中 运行(由 Clock.schedule_interval 调用)。该方法调用 start_thread,它启动一个新线程到 运行 您的 connect 方法。一切都很好,但随后您调用了 t.join(),这会停止主线程,直到您的 connect 方法完成。在等待 connect 线程完成时,您的 GUI 将完全停止。我建议删除以下行:

    time.sleep(1)
    t.join()

允许 GUI 操作。