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

标签 python multithreading kivy

我正在 Kivy 中填充一个 TreeView ,这需要一些时间,具体取决于它的大小。

在树很大并且需要一段时间的情况下,我想在填充时显示一个弹出窗口,以便用户知道程序没有卡住,并在填充树的逻辑完成时关闭此弹出窗口。

这是我通过对该主题的一些研究得出的结论,但弹出窗口似乎仍然只有在树完成填充后才会出现:

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 导入没有加载,因为它不在那里......哈哈)。如果您的用户厌倦了等待,还添加了一个“ABORT”按钮。

最后,作为旁注,我很难将 .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()

关于python - Kivy 弹出窗口在单独的线程中运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44936619/

相关文章:

android - Kivy Buildozer : . 所以 lib 文件缺少调试符号

python - 使用 TCP 同时在两个进程之间进行多处理连接

python - 将 pandas 数据框列标签从浮点转换为整数

python - 使用外部定义的函数修改模块全局变量

python - Cython在所有Python脚本上引发相同的运行时错误

python - Kivy,类型错误: 'NoneType' object has no attribute '__getitem__'

python - 使用 Python 的 SSL3 POST

java - 对象锁定和类级别锁定

multithreading - 我的代码中的随机访问违规

java - 来自 kafka 消费者的 InstanceAlreadyExistsException