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
我正在努力理解如何在 运行 一个漫长的过程之前激活微调器,然后将其停用。
下面是一个例子。我在 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