为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕工程0101907 2023-11-09 21:25:34
我正在使用并发.futures,目前看来我的代码根据需要运行两个函数,但在两个函数完成之前第一个弹出窗口不会显示(问题是第二个函数首先关闭第一个对话框而结束-box,然后打开第二个对话框)。这是我的完整 .py 代码:from kivy.lang import Builderfrom kivy.uix.boxlayout import BoxLayoutfrom kivymd.app import MDAppfrom kivymd.uix.dialog import MDDialogimport concurrent.futuresKV = '''<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):    passclass 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()
查看完整描述

1 回答

?
摇曳的蔷薇

TA贡献1793条经验 获得超6个赞

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


    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()可能executor会出现问题。


第三个问题是您尝试重用MDDialogwithif 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()



查看完整回答
反对 回复 2023-11-09
  • 1 回答
  • 0 关注
  • 144 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信