KivyMD//Python 如何创建一个加载对话框(弹出),当代码在后台运行另一个函数时显示

我正在使用并发.futures,目前看来我的代码根据需要运行两个函数,但在两个函数完成之前第一个弹出窗口不会显示(问题是第二个函数首先关闭第一个对话框而结束-box,然后打开第二个对话框)。


这是我的完整 .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()


慕工程0101907
浏览 146回答 1
1回答

摇曳的蔷薇

您的代码有几个问题。首先,当您使用该构造时:&nbsp; &nbsp; with concurrent.futures.ThreadPoolExecutor() as executor:&nbsp; &nbsp; &nbsp; &nbsp; f1 = executor.submit(self.pop_up1())&nbsp; &nbsp; &nbsp; &nbsp; f2 = executor.submit(self.test())有一个隐含的executor.sutdown()调用,等待提交的任务完成。请参阅文档。由于您在主线程上使用此构造,因此所有 GUI 更新都将被阻止,直到所有提交的任务完成。因此,您通常不应在 kivy 应用程序的主线程上使用该构造。第二个问题是 an 的创建和显示MDDialog应该在主线程上完成,因此提交类似 的方法pop_up1()可能executor会出现问题。第三个问题是您尝试重用MDDialogwithif not self.dialog:条件。无论如何你都不能重复使用MDDialog。因此,考虑到所有这些,这里是代码的修改版本,可以实现我认为您想要的功能:from kivy.clock import Clock, mainthreadfrom kivy.lang import Builderfrom kivy.uix.boxlayout import BoxLayoutfrom kivymd.app import MDAppfrom kivymd.uix.dialog import MDDialogimport concurrent.futuresKV = '''<Content>&nbsp; &nbsp; orientation: "vertical"&nbsp; &nbsp; spacing: -40&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; MDSpinner:&nbsp; &nbsp; &nbsp; &nbsp; size_hint: None, None&nbsp; &nbsp; &nbsp; &nbsp; size: dp(46), dp(46)&nbsp; &nbsp; &nbsp; &nbsp; pos_hint: {'center_x': 0.1}&nbsp; &nbsp; &nbsp; &nbsp; active: True&nbsp; &nbsp; MDLabel:&nbsp; &nbsp; &nbsp; &nbsp; text: "Processing..."&nbsp; &nbsp; &nbsp; &nbsp; pos_hint: {'center_x': .7}FloatLayout:&nbsp; &nbsp; MDFlatButton:&nbsp; &nbsp; &nbsp; &nbsp; text: "ALERT DIALOG"&nbsp; &nbsp; &nbsp; &nbsp; pos_hint: {'center_x': .5, 'center_y': .5}&nbsp; &nbsp; &nbsp; &nbsp; on_release: app.start()'''class Content(BoxLayout):&nbsp; &nbsp; passclass Example(MDApp):&nbsp; &nbsp; dialog = None&nbsp; &nbsp; def build(self):&nbsp; &nbsp; &nbsp; &nbsp; return Builder.load_string(KV)&nbsp; &nbsp; def start(self):&nbsp; &nbsp; &nbsp; &nbsp; # this must be done on the main thread&nbsp; &nbsp; &nbsp; &nbsp; self.pop_up1()&nbsp; &nbsp; &nbsp; &nbsp; executor = concurrent.futures.ThreadPoolExecutor()&nbsp; &nbsp; &nbsp; &nbsp; # f1 = executor.submit(self.pop_up1)&nbsp; # this must be done on the main thread&nbsp; &nbsp; &nbsp; &nbsp; f2 = executor.submit(self.test)&nbsp; &nbsp; def pop_up1(self):&nbsp; &nbsp; &nbsp; &nbsp; '''Displays a pop_up with a spinning wheel'''&nbsp; &nbsp; &nbsp; &nbsp; self.dialog = MDDialog(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; size_hint=(.45, None),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; auto_dismiss=True,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; type="custom",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; content_cls=Content(),&nbsp; &nbsp; &nbsp; &nbsp; )&nbsp; &nbsp; &nbsp; &nbsp; self.dialog.open()&nbsp; &nbsp; def test(self):&nbsp; &nbsp; &nbsp; &nbsp; '''Counts to 1000000 and then it closes pop_up1 and opens pop_up2'''&nbsp; &nbsp; &nbsp; &nbsp; for number in range(100000):&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print(number)&nbsp; &nbsp; &nbsp; &nbsp; self.dismiss()&nbsp; &nbsp; &nbsp; &nbsp; Clock.schedule_once( self.pop_up2)&nbsp; # pop_up2() must be done on the main thread&nbsp; &nbsp; def pop_up2(self,*args):&nbsp; &nbsp; &nbsp; &nbsp; self.dialog = MDDialog(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; title="Done",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; size_hint=(.6, None),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; text="Done",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )&nbsp; &nbsp; &nbsp; &nbsp; self.dialog.open()&nbsp; &nbsp; @mainthread&nbsp; &nbsp; def dismiss(self, *args):&nbsp; &nbsp; &nbsp; &nbsp; self.dialog.dismiss()Example().run()
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python