Kivy > 穿线和使用 Spinner

Kivy > Threading and using the Spinner

我正在努力理解如何在 运行 一个漫长的过程之前激活微调器,然后将其停用。

下面是一个例子。我在 KV 文件中尝试 运行 运行 切换微调器的方法,然后 运行 线程进程,然后停用它,但这没有用。然后我将主线程装饰器添加到切换微调器方法和 运行 在线程进程之前,但那也不起作用。

from kivy.clock import mainthread
from kivy.lang import Builder
import threading

from kivymd.app import MDApp

KV = '''
#: import threading threading
Screen:
    BoxLayout:
        MDSpinner:
            id: spinner
            size_hint: None, None
            size: dp(46), dp(46)
            pos_hint: {'center_x': .5, 'center_y': .5}
            active: True if check.active else False
    
        MDCheckbox:
            id: check
            size_hint: None, None
            size: dp(48), dp(48)
            pos_hint: {'center_x': .5, 'center_y': .4}
            active: True
        
        Button:
            text: 'Spinner On/Off'
            size_hint: None, None
            size: dp(150), dp(150)
            on_release: app.spinner_toggle()
        
        Button:
            text: 'Run Long Process'
            size_hint: None, None
            size: dp(150), dp(150)
            on_release: 
                app.spinner_toggle()
                app.long_process_thread()
                app.spinner_toggle()
'''


class Test(MDApp):
    def build(self):
        return Builder.load_string(KV)

    @mainthread
    def spinner_toggle(self):
        print('Spinner Toggle')
        app = self.get_running_app()
        if app.root.ids.spinner.active == False:
            app.root.ids.spinner.active = True
        else:
            app.root.ids.spinner.active = False


    def long_process(self):
        for x in range(1000000):
            print(x)

    def long_process_thread(self):
        self.spinner_toggle()
        threading.Thread(target=(self.long_process())).start()
        self.spinner_toggle()



Test().run()

几个问题。第一个是你的台词:

threading.Thread(target=(self.long_process())).start()

在那调用代码self.long_process()实际上是在启动线程之前运行long_process()。你真的想做:

threading.Thread(target=(self.long_process)).start()

注意缺少 ()

第二个问题是您在启动线程后立即调用 self.spinner_toggle(),因此 Spinner 在线程结束之前很久就再次切换。要解决此问题,您可以在线程末尾调用 self.spinner_toggle()。因此,这是您的代码的一部分,其中包含这些修改:

def long_process(self):
    for x in range(1000000):
        print(x)
    self.spinner_toggle()

def long_process_thread(self):
    self.spinner_toggle()
    threading.Thread(target=(self.long_process)).start()

顺便说一句,在你的 kv 中你可以替换:

active: True if check.active else False

更简单的:

active: check.active