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

Kivy - automatically start a method from popup

问题

我正在使用 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 中的按钮被禁用,因为我只想显示标签。下面是我查过的一些类似的问题,没有找到解决方案。

  1. Kivy popup running in separate thread
  2. 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()

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

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

回答

@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()

然后我尝试 运行ning 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