在一个没有调用 Popup.open() (kivy) 的方法中触发 Popup.dismiss()



我正在尝试为我的精通同事开发一个kivy应用程序,该应用程序包裹着我为项目开发的一些计算的不错的GUI;目前,我有两种嵌入在类中的方法,一种方法(称为"虚拟"(,可防止GUI冻结,从此类多线程中,第二种方法(称为"计算"(实际运行了计算。在虚拟方法中,我希望打开一个弹出窗口,该弹出窗口显示"加载gif"(表明程序正在运行,而不仅仅是冻结(,我希望弹出窗口在完成"计算"方法完成后关闭。如何将弹出窗口的自动关闭绑定到方法的完成(self, *args(?

- gui.py-

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.popup import Popup
import threading
from calc import main

class Pop(Popup):
    pass

class MetaLevel(GridLayout):
    def dummy(self, *args):
        Pop().open()
        threading.Thread(target=self.calculate, args=(args,)).start()
    def calculate(self, *args):
        main()

class graphics(App):
    def build(self):
        return MetaLevel()

if __name__ == "__main__":
    graphics().run()

- calc.py-

def main():
    import numpy as np
    from pathos.multiprocessing import ProcessPool as Pool
    grid = np.array([(m, n)
                     for m in np.arange(1, 100, 1)
                     for n in np.arange(1, 100, 1)])
    def calc(grid):
        var1 = grid[0]
        var2 = grid[1]
        y = var1*var2
        return y
    res = Pool().map(calc, grid)
    print('done')
    # data output from res here

- graphics.kv-

<Button>:
    font_size: 12
<MetaLevel>:
    id: calculator
    rows: 5
    padding: 10
    spacing: 10
    BoxLayout:
        height: 10
        Label:
            spacing: 10
            text: 'test'
    BoxLayout:
        Button:
            id: run_button
            text: "Run"
            on_release: root.dummy()

--- 编辑1 ---

仍在努力解决问题;我遇到了clock.create_trigger((函数,并尝试将其集成到POP类中 - 问题是我无法在计算方法中弄清楚如何在main((之后调用trigger(((见下文(。如果我们能触发触发器,可能是解决问题的可行解决方案。

- gui.py-


from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.popup import Popup
import threading
from kivy.clock import Clock
from calc import main

class Pop(Popup):
    def __init__(self, **kwargs):
        super(Pop, self).__init__(**kwargs)
        trigger = Clock.create_trigger(self.dismiss_popup)
    def dismiss_popup(self, dt):
        self.dismiss()

class MetaLevel(GridLayout):
    def dummy(self, *args):
        Pop().open()
        threading.Thread(target=self.calculate, args=(args,)).start()
    def calculate(self, *args):
        main()
        trigger() # after main finishes I want to toggle the trigger, but kivy/python doesn't like this

class graphics(App):
    def build(self):
        return MetaLevel()

if __name__ == "__main__":
    graphics().run()

尝试将弹出窗口分配给从App继承的类中的一个变量(我将其称为您的"主应用程序类"(。您可以通过在Python中使用App.get_running_app().your_variable或简单地使用KV语言的app.your_variable来引用主应用程序类中的变量和函数。

对于您的情况,请删除gui.py中的行 Pop().open()并用以下行替换:

App.get_running_app().pop.open()

然后在您的graphics类中,为弹出窗口创建一个变量。您可以在build函数中执行此操作,只需添加self.pop = Pop()

现在,在您的calc.py程序中,您需要添加from kivy.app import App,然后在main函数末尾,添加行以删除弹出窗口:

App.get_running_app().pop.dismiss()

最新更新