Kivy - 从弹出窗口自动启动方法

Posted

技术标签:

【中文标题】Kivy - 从弹出窗口自动启动方法【英文标题】:Kivy - automatically start a method from popup 【发布时间】:2020-10-22 18:41:38 【问题描述】:

问题

我正在使用 Python3 和 Kivy2。无论如何,我希望弹出窗口在后台自动启动一个耗时的方法

描述 在满足条件时弹出的脚本调用中。

if  self.header == "loadbag":
    messageTitle = "machine status"
    messageLabel = "work in progress"
    self.popup(messageTitle, messageLabel)

弹出方法结构为:

def popup(self, boxTitle, boxLabel):    # popup for showing the activity
    self.MessageButtonCancel = "ANNULLA"
    self.MessageBoxTitle = boxTitle
    self.MessageBoxLabel = boxLabel
    self.popup = ActivityBox(self)
    self.popup.open()

ActivityBox的Builder.load_string中的kv语言部分是:

<ActivityBox>:
    size_hint: 1, .7
    auto_dismiss: False
    title: app.MessageBoxTitle       
    title_align: "center"
    title_size: 30

    BoxLayout:
        orientation: "vertical"
        Label:
            font_size: '30sp'
            text: app.MessageBoxLabel
        BoxLayout:
            orientation: "horizontal"
            spacing: 10
            size_hint: 1, .5
            # both buttons are not necessary
            # the popup just shows a message
            # Button:
                # font_size: 50
                # background_color: 0,204,0,1
                # text: app.MessageButtonConfirm  # "CONFIRM"
                # on_press:
                    # self.disabled = True
                    # self.background_color = 0,255,0,1
                    # app.do()
            # Button:
                # font_size: 50
                # background_color: 204,0,0,1
                # text: app.MessageButtonCancel  # "CANCEL"
                # on_press:
                    # self.background_color = 255,0,0,1
                    # app.cancel()
                    # root.dismiss()

如您所见,ActivityBox 中的按钮被禁用,因为我只想显示标签。以下是我检查过的一些类似问题,但没有找到解决方案。

    Displaying something in kivy while a process is running background Kivy: how to display a widget while waiting for another one to be displayed (both called from a same event) Kivy popup running in separate thread Pop up Kivy displaying while a process is running in background Open kivy popup before continuing

问题

有没有办法从 ActivityBox 中自动启动一个方法,而不将它绑定到按钮上?

更新 1

我尝试在 def popup(self, boxTitle, boxLabel): 中插入方法调用,但弹出窗口仅在方法终止后出现。

def popup(self, boxTitle, boxLabel):    # popup for showing the activity
    self.MessageBoxTitle = boxTitle
    self.MessageBoxLabel = boxLabel
    self.popup = ActivityBox(self)
    self.time_consuming_method() # here goes the method to run
    self.popup.open()

更新 2

我尝试了线程但没有成功。弹出窗口和方法各自在一个单独的线程中。弹出窗口仅在方法终止后出现。

    def popup(self, boxTitle, boxLabel):    # popup for showing the activity
        self.MessageBoxTitle = boxTitle
        self.MessageBoxLabel = boxLabel
        self.popup = ActivityBox(self)
        self.popup.open()
    
    t1 = threading.Thread(target = popup, args = (boxTitle, boxLabel))
    t2 = threading.Thread(target = time_consuming_method)
    
    t1.start()
    t2.start()
    
    t1.join()
    t2.join()

【问题讨论】:

【参考方案1】:

使用Threadjoin() 方法会导致等待Thread 完成,这几乎等同于不使用threading

尝试消除线程t1,然后直接调用popup,而不使用新线程。然后启动线程t2,但消除t2.join()调用。

【讨论】:

【参考方案2】:

回答

@John Anderson 提出的答案很有帮助。 join 方法会导致不必要的等待。

首先,我尝试将def popup 方法作为线索运行,将time_consuming_method 作为线程运行。这种方法没有解决问题。

代码无效

    def popup(self, boxTitle, boxLabel):    # popup for showing the activity
        self.MessageBoxTitle = boxTitle
        self.MessageBoxLabel = boxLabel
        self.popup = ActivityBox(self)
        self.popup.open()
    
    self.popup(boxTitle, boxLabel)
    t2 = threading.Thread(target = time_consuming_method)
    t2.start()

然后我尝试运行 self.popup.open() 方法作为线索,并将 time_consuming_method 作为线程从 def popup 方法内部运行。此解决方案效果很好,方法启动时会出现弹出窗口。

工作代码

    def popup(self, boxTitle, boxLabel):    # popup for showing the activity
        self.MessageBoxTitle = boxTitle
        self.MessageBoxLabel = boxLabel
        self.popup = ActivityBox(self)
        self.popup.open()                   # call the popup    
        t2 = threading.Thread(target = time_consuming_method)    # define the thread
        t2.start()    # start the thread
    

【讨论】:

以上是关于Kivy - 从弹出窗口自动启动方法的主要内容,如果未能解决你的问题,请参考以下文章

Javascript - 从弹出窗口重定向父窗口

从弹出窗口设置localStorage

从弹出窗口呈现视图

从弹出窗口在父窗口中提交表单?

访问 kivy 弹出父级

如何从弹出窗口向 boxlayout 添加新标签?