与kivy在Android上的后退按钮功能

时间:2013-11-20 08:21:48

标签: android python-2.7 kivy

在Kivy,当我按下Android设备上的后退按钮时,它会把我从应用程序中抛出。有没有办法使用Kivy语言而不是python返回上一个屏幕?这就是我在kivy写的:

<MyAppClass>:
AnchorLayout:
    anchor_x : 'center'
    anchor_y : 'top'
    ScreenManager:
        size_hint : 1, .9
        id: _screen_manager

        Screen:
            name:'screen1'
            StackLayout:
                # irrelevant code

        Screen:
            name:'screen2'
            StackLayout:
                # irrelevant code

我需要从python中操作屏幕管理器及其屏幕......如果我能这样做,我将使用python。

4 个答案:

答案 0 :(得分:10)

Kivy on android将后退按钮绑定到esc按钮,因此绑定并聆听应用中的esc按钮可帮助您处理按下后退按钮时应用的行为。

换句话说,在您的应用程序中,在桌面上测试时,请从系统键盘上听取转义键,这将自动转换为Android设备上的后退按钮。像::

之类的东西
def on_start():
    from kivy.base import EventLoop
    EventLoop.window.bind(on_keyboard=self.hook_keyboard)

def hook_keyboard(self, window, key, *largs):
    if key == 27:
       # do what you want, return True for stopping the propagation
       return True 

答案 1 :(得分:5)

这当然是可能的。这是一个简短的示例应用程序,使用我用来执行此操作的方法:

from kivy.utils import platform
from kivy.core.window import Window

class ExampleApp(App):
    manager = ObjectProperty()

    def build(self):
        sm = MyScreenManager()
        self.manager = sm
        self.bind(on_start=self.post_build_init)
        return sm

    def post_build_init(self, *args):
        if platform() == 'android':
            import android
            android.map_key(android.KEYCODE_BACK, 1001)

        win = Window
        win.bind(on_keyboard=self.my_key_handler)

    def my_key_handler(self, window, keycode1, keycode2, text, modifiers):
        if keycode1 in [27, 1001]:
            self.manager.go_back()
            return True
        return False

这应该给出正确的基本想法,但有一些注意事项:

  • ScreenManager无法跟踪以前的屏幕,您可以根据自己的喜好来实现。我的示例假设您使用go_back方法定义了一个MyScreenManager类。
  • 可能没有必要绑定到on_start并运行post_build_init,这就是我最初使用的示例(见下文)。有时可能很重要,可能是在运行build()时窗口未初始化,原始邮件列表帖子表明作者出于某种原因需要它。
  • 该示例侦听密钥代码27或1001.正如我在写这篇文章时所说的那样,前者会监听esc,因此您可以在桌面上获得相同的行为。
  • 我没有尝试没有android.map_key行,但似乎没有必要。
  • 你提到你想使用kivy语言而不是python。你需要做一些python来得到这个结果,我没有看到解决方法(它不是真正的kv语言的领域)。我想你可以通过在某个地方定义一个'go_back'事件并在按下键时触发它来将一些东西转移到kv,同时绑定你的屏幕管理员来观察那个事件,但这似乎还有很长的路要走。

我将代码基于https://groups.google.com/forum/#!topic/kivy-users/7rOZGMMIFXI的邮件列表主题。可能有更好的方法,但这很有用。

答案 2 :(得分:3)

我想我已经解决了,但应该感谢@inclement和@ qua-non!你的答案让我走向了正确的道路!所以在kv我假设我给我的屏幕管理员一个id(请参考我的问题,我已经写了kv代码),在python我应该做以下:

    from kivy.core.window import Window
    from kivy.properties import ObjectProperty

    class MyAppClass(FloatLayout):#its a FloatLayout in my case
        _screen_manager=ObjectProperty(None)
        def __init__(self,**kwargs):
            super(MyAppClass,self).__init__(**kwargs)
            #code goes here and add:
            Window.bind(on_keyboard=self.Android_back_click)

        def Android_back_click(self,window,key,*largs):
            if key == 27:
                self._scree_manager.current='screen1'#you can create a method here to cache in a list the number of screens and then pop the last visited screen.
                return True

    class MyApp(App):
        def build(self):
            return MyAppClass()

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

答案 3 :(得分:0)

现在我一直在使用2020:

Clock.schedule_once(lambda x: Window.bind(on_keyboard=self.hook_keyboard))

与其他答案的相似hook_keyboard方法结合使用,可以延迟我的build方法中的绑定。效果很好,但是这些方法似乎对我而言不再起作用。