KivyMD // Python如何创建一个加载对话框(弹出窗口),该对话框在后台运行代码的同时显示一个旋转的轮子

埃德玛·科斯塔(Edmar Costa)

我正在使用current.futures,目前看来我的代码可以按需运行两个函数,但是直到两个函数都完成时才会显示第一个弹出窗口(问题是第二个函数首先退出第一个对话框而结束-框,然后打开第二个对话框)。

这是我完整的.py代码:

from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivymd.app import MDApp
from kivymd.uix.dialog import MDDialog
import concurrent.futures

KV = '''
<Content>
    orientation: "vertical"
    spacing: -40
    
    MDSpinner:
        size_hint: None, None
        size: dp(46), dp(46)
        pos_hint: {'center_x': 0.1}
        active: True
    MDLabel:
        text: "Processing..."
        pos_hint: {'center_x': .7}

FloatLayout:

    MDFlatButton:
        text: "ALERT DIALOG"
        pos_hint: {'center_x': .5, 'center_y': .5}
        on_release: app.start()
'''


class Content(BoxLayout):
    pass

class Example(MDApp):
    dialog = None

    def build(self):
        return Builder.load_string(KV)

    def start(self):
        with concurrent.futures.ThreadPoolExecutor() as executor:
            f1 = executor.submit(self.pop_up1())
            f2 = executor.submit(self.test())


    def pop_up1(self):
        '''Displays a pop_up with a spinning wheel'''
        if not self.dialog:
            self.dialog = MDDialog(
                size_hint=(.45, None),
                auto_dismiss=True,
                type="custom",
                content_cls=Content(),
            )
            self.dialog.open()

    def test(self):
        '''Counts to 1000000 and then it closes pop_up1 and opens pop_up2'''
        for number in range(1000000):
            print(number)
        self.dismiss()
        self.pop_up2()

    def pop_up2(self):
        if not self.dialog:
            self.dialog = MDDialog(
                title="Done",
                size_hint=(.6, None),
                text="Done",

                    )
        self.dialog.open()

    def dismiss(self, *args):
        self.dialog.dismiss()


Example().run()
约翰·安德森

您的代码有几个问题。首先,当您使用构造时:

    with concurrent.futures.ThreadPoolExecutor() as executor:
        f1 = executor.submit(self.pop_up1())
        f2 = executor.submit(self.test())

有一个隐式executor.sutdown()调用,它等待提交的任务完成。请参阅文档由于您在主线程上使用了此构造,因此所有GUI更新都将被阻止,直到所有提交的任务完成为止。因此,通常不应该在kivy应用程序的主线程上使用该构造。

第二个问题是an的创建和显示MDDialog应在主线程上完成,因此提交类似于pop_up1()the的方法executor可能会出现问题。

第三个问题是您尝试重复MDDialog使用if not self.dialog:条件。MDDialog无论如何,您都无法重用

因此,考虑到所有这些,以下是您的代码的修改版本,可以满足我的要求:

from kivy.clock import Clock, mainthread
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivymd.app import MDApp
from kivymd.uix.dialog import MDDialog
import concurrent.futures

KV = '''
<Content>
    orientation: "vertical"
    spacing: -40
    
    MDSpinner:
        size_hint: None, None
        size: dp(46), dp(46)
        pos_hint: {'center_x': 0.1}
        active: True
    MDLabel:
        text: "Processing..."
        pos_hint: {'center_x': .7}

FloatLayout:

    MDFlatButton:
        text: "ALERT DIALOG"
        pos_hint: {'center_x': .5, 'center_y': .5}
        on_release: app.start()
'''


class Content(BoxLayout):
    pass

class Example(MDApp):
    dialog = None

    def build(self):
        return Builder.load_string(KV)

    def start(self):
        # this must be done on the main thread
        self.pop_up1()

        executor = concurrent.futures.ThreadPoolExecutor()
        # f1 = executor.submit(self.pop_up1)  # this must be done on the main thread
        f2 = executor.submit(self.test)


    def pop_up1(self):
        '''Displays a pop_up with a spinning wheel'''
        self.dialog = MDDialog(
            size_hint=(.45, None),
            auto_dismiss=True,
            type="custom",
            content_cls=Content(),
        )
        self.dialog.open()

    def test(self):
        '''Counts to 1000000 and then it closes pop_up1 and opens pop_up2'''
        for number in range(100000):
            print(number)
        self.dismiss()
        Clock.schedule_once( self.pop_up2)  # pop_up2() must be done on the main thread

    def pop_up2(self,*args):
        self.dialog = MDDialog(
            title="Done",
            size_hint=(.6, None),
            text="Done",
                )
        self.dialog.open()

    @mainthread
    def dismiss(self, *args):
        self.dialog.dismiss()


Example().run()

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

Related 相关文章

热门标签

归档