【问题标题】:KeyError stopping App in kivyKeyError在kivy中停止应用程序
【发布时间】:2014-05-22 01:56:37
【问题描述】:

我正在尝试让我一直在构建的应用程序在某个时间点停止,并在停止时运行清理程序。这看起来应该很容易,但我一直遇到错误,我一直无法找到解决方案。

我使用 kivy 1.8.0 和 Python 3.3。为方便起见,我修改了 kivy 文档中的一些代码,因为我的代码基于相同的框架,并且都给了我完全相同的错误:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen    
# Create both screens. Please note the root.manager.current: this is how
# you can control the ScreenManager from kv. Each screen has by default a
# property manager that gives you the instance of the ScreenManager used.
Builder.load_string("""
<MenuScreen>:
    BoxLayout:
        Button:
            text: 'Goto settings'
            on_press: root.manager.current = 'settings'
        Button:
            text: 'Quit'
            on_press: root.exit()

<SettingsScreen>:
    BoxLayout:
        Button:
            text: 'My settings button'
        Button:
            text: 'Back to menu'
            on_press: root.manager.current = 'menu'    
""")

# Declare both screens
class MenuScreen(Screen):
    def exit(self):
        App.stop(self)


class SettingsScreen(Screen):
    pass     

# Create the screen manager
sm = ScreenManager()
sm.add_widget(MenuScreen(name='menu'))
sm.add_widget(SettingsScreen(name='settings'))

class TestApp(App):

    def build(self):
        return sm

    def on_stop(self):
        print('leaving now') # this is where I'd want to run the end of program procedure

if __name__ == '__main__':
    TestApp().run()

当我运行它并单击Quit 按钮时,我收到以下错误:

builtins.KeyError: 'on_stop'

我还要注意,如果我注释掉class TestApp 中的on_stop 函数,错误仍然存​​在。知道出了什么问题吗?

【问题讨论】:

    标签: python kivy


    【解决方案1】:

    您将MenuScreen 的实例传递给App.stop(),这会导致您的错误,因为它需要App 实例。您可以像这样检索正在运行的应用程序并停止它:

    class MenuScreen(Screen):
        def exit(self):
            App.get_running_app().stop()
    

    【讨论】:

      【解决方案2】:

      以下是您的问题的解决方案:

      # Declare both screens
      class MenuScreen(Screen):
          def exit(self):
              self.manager.app.stop()
      
      class TestApp(App):
      
          def build(self):
              # Create the screen manager
              sm = ScreenManager()
              # monkey patch the screen manager instance to add the app
              sm.app = self
              sm.add_widget(MenuScreen(name='menu'))
              sm.add_widget(SettingsScreen(name='settings'))
              return sm
      

      虽然我不认为这是解决您问题的规范解决方案,因为这里涉及猴子修补。

      但是问题在于,您要调用的 stop() 方法仅存在于应用程序实例中,尽​​管您处理它的方式,您无法访问正在运行的应用程序实例,因为它是在代码之后声明的需要它。

      因此解决方案是将ScreenManager 构建移动到构建方法中。这就是我认为我的解决方案不是一个好的设计的地方:我基本上是通过猴子修补实例向ScreenManager 添加一个成员,给它一个指向App 实例的链接。

      您可以在此处调用close() 函数,并优雅地关闭您的应用程序。

      【讨论】:

        猜你喜欢
        • 2018-02-25
        • 2020-08-17
        • 1970-01-01
        • 1970-01-01
        • 2020-01-04
        • 1970-01-01
        • 1970-01-01
        • 2012-08-14
        • 1970-01-01
        相关资源
        最近更新 更多