首页 > 解决方案 > 如何在运行命令时让加载 gif 工作

问题描述

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

当我单击一个按钮时,我会弹出一个包含加载 gif 的弹出窗口,在后台我想在加载此 gif 时运行一个 python 脚本。脚本完成后,弹出窗口关闭。

到目前为止,除了 gif 在其他 python 脚本开始运行时冻结之外,所有这些都有效。

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

线程似乎是要走的路,但是我仍然得到相同的结果(一旦我开始运行其他 python 脚本,gif 就会冻结)。

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

总体而言,我正在使用 kivy 编写一个 python3.7 应用程序来创建 GUI。我在 Raspberry Pi 4 上运行此应用程序。

以下是我当前相关代码的片段:(“...”表示其他不相关代码的位置)

主文件

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

主文件

<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

标签: pythonbashkivypython-multithreadinganimated-gif

解决方案


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

    time.sleep(1)
    t.join()

以允许 GUI 运行。


推荐阅读