在未调用 Popup.open() 的方法中触发 Popup.dismiss() (kivy)
triggering Popup.dismiss() in a method which didn't call Popup.open() (kivy)
我正在尝试为我不太精通的同事开发一个 kivy 应用程序,它围绕我为一个项目开发的一些计算包装了一个漂亮的 GUI;目前我在 class 中嵌入了两种方法,一种方法(称为 'dummy')可以防止 GUI 冻结,第二种方法(称为 'calculate')实际上运行计算。在虚拟方法中,我希望打开一个显示 'loading GIF' 的弹出窗口(表明该程序是 运行 而不仅仅是冻结),我希望弹出窗口在 'loading GIF' 完成后关闭=33=]方法。如何将弹出窗口的自动关闭绑定到方法 calculate(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 class - 问题是我无法弄清楚如何在计算方法中的 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()
尝试将弹出窗口分配给 class 中继承自 App
的变量(我将其称为 "main app class")。您可以在主应用程序 class 中引用变量和函数,方法是在 Python 中使用 App.get_running_app().your_variable
或在 kv 语言中简单地使用 app.your_variable
。
对于您的情况,删除 GUI.py 中的行
Pop().open()
并将其替换为以下行:
App.get_running_app().pop.open()
然后在您的 graphics
class 中为弹出窗口创建一个变量。您可以在 build
函数中执行此操作,只需添加 self.pop = Pop()
现在,在您的 calc.py
程序中,您需要添加 from kivy.app import App
,然后在 main
函数的末尾,添加一行以关闭弹出窗口:
App.get_running_app().pop.dismiss()
我正在尝试为我不太精通的同事开发一个 kivy 应用程序,它围绕我为一个项目开发的一些计算包装了一个漂亮的 GUI;目前我在 class 中嵌入了两种方法,一种方法(称为 'dummy')可以防止 GUI 冻结,第二种方法(称为 'calculate')实际上运行计算。在虚拟方法中,我希望打开一个显示 'loading GIF' 的弹出窗口(表明该程序是 运行 而不仅仅是冻结),我希望弹出窗口在 'loading GIF' 完成后关闭=33=]方法。如何将弹出窗口的自动关闭绑定到方法 calculate(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 class - 问题是我无法弄清楚如何在计算方法中的 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()
尝试将弹出窗口分配给 class 中继承自 App
的变量(我将其称为 "main app class")。您可以在主应用程序 class 中引用变量和函数,方法是在 Python 中使用 App.get_running_app().your_variable
或在 kv 语言中简单地使用 app.your_variable
。
对于您的情况,删除 GUI.py 中的行
Pop().open()
并将其替换为以下行:
App.get_running_app().pop.open()
然后在您的 graphics
class 中为弹出窗口创建一个变量。您可以在 build
函数中执行此操作,只需添加 self.pop = Pop()
现在,在您的 calc.py
程序中,您需要添加 from kivy.app import App
,然后在 main
函数的末尾,添加一行以关闭弹出窗口:
App.get_running_app().pop.dismiss()