Kivy 弹出窗口在单独的线程中运行

2024-04-23

我正在 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(使用前将#替换为@)

Kivy 弹出窗口在单独的线程中运行 的相关文章

随机推荐