带有kivy的android上的后退按钮功能
Posted
技术标签:
【中文标题】带有kivy的android上的后退按钮功能【英文标题】:back button functionality on android with kivy 【发布时间】:2013-12-04 03:16:23 【问题描述】:在 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 没问题。
【问题讨论】:
【参考方案1】: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
【讨论】:
我已经编辑了我的请求...也许它会更清楚,抱歉第一次是一个抽象的问题。【参考方案2】:我想我已经解决了,但应该感谢@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()
【讨论】:
没有。您必须在类级别声明 ObjectProperty,而不是在 init 函数中。 我想你是对的,但在 init 和类级别工作。但正确的方法是你说的地方。再次感谢你...... 它在 init 中不起作用,只是你没有注意到,因为巧合你所做的其他一些东西复制了正确的行为。 我不能说我理解你的意思。对象属性应该在类级别,它们要么在 init 中,要么在它之上。它应该双向工作 “在班级级别”是指您当前在示例中的位置。这是使属性正常工作的唯一方法,如果您在 init 中执行此操作,它们将无法正确绑定为属性。我认为 kv 语言也隐式地创建属性,这就是为什么你的示例以任何方式工作的原因 - kv 语言 _screen_manager 声明覆盖了 init 函数所做的事情。【参考方案3】:这当然是可能的。这是一个简短的示例应用程序,其中包含我用来执行此操作的方法:
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。正如 qua-non 在我写这篇文章时所说,前者侦听 esc
,因此您可以在桌面上获得相同的行为。
我没有尝试不使用 android.map_key
行,但似乎没有必要。
你提到你想使用 kivy 语言而不是 python。你需要做一些 python 来得到这个结果,我看不出有什么办法(它不是真正的 kv 语言的领域)。我想你可以通过在某处定义一个“go_back”事件并在按下键时触发它来将一些东西转移到 kv,同时绑定你的屏幕管理器来观看该事件,但这似乎还有很长的路要走。
我的代码基于https://groups.google.com/forum/#!topic/kivy-users/7rOZGMMIFXI 的邮件列表线程。可能有更好的方法,但这很实用。
【讨论】:
我已经编辑了我的请求...也许它会更清楚,抱歉第一次是一个抽象的问题。 那么你真正的问题是什么?您不知道如何更改当前屏幕?你不知道如何在 python 中获取 screenmanager 的引用? 我的问题是如何在 python 中获取对 screenmanager 的引用:会不会像 _screen_manager=ObjectProperty(None)?那么 self._screen_manager.current = 'screen1' ? 是的,这是一个很好的方法。不过,不要忘记将对象属性设置为实际指向您的 kv 文件中的屏幕管理器,您可以使用 ids 来执行此操作。 我尝试了以下方法:_screen_manager=ObjectProperty(ScreenManager()),然后在更改按键 27 按下事件上的屏幕的功能中添加:self._screen_manager.current='screen1' when测试它我没有名为“screen1”的屏幕,很抱歉打扰你@inclement,但我很接近......【参考方案4】:现在我一直在 2020 年使用:
Clock.schedule_once(lambda x: Window.bind(on_keyboard=self.hook_keyboard))
结合与其他答案类似的 hook_keyboard 方法,以延迟我的构建方法中的绑定。工作正常,但这些其他方式似乎都不适合我了。
【讨论】:
以上是关于带有kivy的android上的后退按钮功能的主要内容,如果未能解决你的问题,请参考以下文章
在工作灯中使用带有 Dojomobile 和 phonegap 的 android 后退按钮