我正在 Kivy 中填充一个树视图,这需要一些时间,具体取决于它的大小。
在树很大并且需要一段时间的情况下,我想在填充时显示一个弹出窗口,以便用户知道程序尚未冻结,并在填充树的逻辑完成时关闭此弹出窗口。
这是我通过对该主题的一些研究得出的结论,但弹出窗口似乎仍然只有在树完成填充后才会出现:
def show(self, *args):
self.error_popup.open()
def populate_tree(self, model):
#Clock.schedule_once(self.error_popup.open())
popup_thread = threading.Thread(target=self.show())
popup_thread.start()
# order the dictionary for better user experience
ordered_data = collections.OrderedDict(sorted(model.items()))
# logic to populate tree
for county, value in ordered_data.items():
if county != "model_name":
# set initial county dropdowns in tree
county_label = self.treeview.add_node(TreeViewButton(text=str(county), on_press=self.edit_node))
i = 0 # keep count of rules
# add rules children to county
for rule_obj, rule_list in value.items():
for rule in rule_list:
i += 1
# set rule number in tree
rule_label = self.treeview.add_node(TreeViewButton(text='Rule ' + str(i), on_press=self.edit_node), county_label)
# add conditions children to rule
for condition in rule:
self.treeview.add_node(TreeViewButton(text=condition, on_press=self.edit_node), rule_label)
#Clock.schedule_once(self.error_popup.dismiss())
#somehow close popup_thread
我添加了一个 kivy Clock 尝试,以防它更符合我正在寻找的内容,但目前它只会打开弹出窗口,而不会填充树。我是 GUI 编程和事件回调的新手,因此非常感谢任何帮助。
我尝试保持代码简短,如果需要更多代码,请告诉我。
我构建了一个应用程序,它执行与您正在执行的操作类似的操作(不同的计算,但正如您所说,重点是它很耗时,并且您想要线程显示应用程序没有崩溃的弹出窗口 - 它只是在启动号码)。最终对我有用的是设置一个按钮来执行一个虚拟函数,该函数可以切换弹出窗口和计算。首先运行弹出窗口,然后通过“from threading import Thread”模块对计算进行线程化,以在单独的线程上执行计算。
这是一个工作示例。它只是休眠了 5 秒,但你可以将计算放入该函数中,它应该可以正常工作。它的作用是在计算之前打开弹出窗口,并在计算完成时关闭弹出窗口。另外,您可以将“Loading.gif”文件粘贴到该文件夹中,如果您想使用 kivy 提取的内容以外的其他内容(本质上是用于加载 Loading.gif 的加载 gif),它会将其导入为您的加载 gif它没有加载,因为它不存在......哈哈)。如果您的用户厌倦了等待,还添加了“中止”按钮。
最后,作为旁注,我很难将 .kv 文件构建到 pyinstaller 应用程序捆绑器中,因此请注意,使用 builder.load_string(KV) 函数是一个很好的替代方案。
from threading import Thread
from sys import exit
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.popup import Popup
from kivy.lang import Builder
KV = '''
<Pop>:
id:pop
title: ''
auto_dismiss: False
padding: 10
spacing: 10
BoxLayout:
BoxLayout:
padding: 10
spacing: 10
orientation: 'vertical'
Label:
font_size: 22
size_hint_y: None
text_size: self.width, None
height: self.texture_size[1]
text: "Process is currently running."
Label:
id: error_msg
size_hint_x: 0.3
text: ''
BoxLayout:
orientation: 'vertical'
Button:
background_color: (1,0,0,1)
text: "ABORT"
on_press: root.sysex()
AsyncImage:
source: 'Loading.gif'
<MetaLevel>:
rows: 1
cols: 1
Button:
text: 'RUN'
on_release: root.dummy()
'''
Builder.load_string(KV)
class MetaLevel(GridLayout):
def dummy(self, *args):
App.get_running_app().pop.open()
Thread(target=self.calculate, args=(args,), daemon=True).start()
def calculate(self, *args):
import time
time.sleep(5)
App.get_running_app().pop.dismiss()
class Pop(Popup):
def sysex(self):
exit()
class Cruncher(App):
def build(self):
self.pop = Pop()
return MetaLevel()
if __name__ == "__main__":
Cruncher().run()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)