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

tou*_*ich 7 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
Run Code Online (Sandbox Code Playgroud)

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

qua*_*non 12

Android上的Kivy将后退按钮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 
Run Code Online (Sandbox Code Playgroud)


tou*_*ich 9

我想我已经解决了,但应该感谢@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()
Run Code Online (Sandbox Code Playgroud)

  • 不可以。您必须在类级别而不是在 __init__ 函数中声明 ObjectProperty。 (2认同)

inc*_*ent 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
Run Code Online (Sandbox Code Playgroud)

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

  • 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.可能有更好的方法,但这很有用.

  • 删除:'if platform() == 'android':''导入 android' 和 'android.map_key(android.KEYCODE_BACK, 1001)'。这不再是必要的,并且会在 TextInput 处于活动状态时导致关闭键盘时出错。 (2认同)