kivy捕获键盘在使用屏幕管理器的xinitrc的raspberrypi上表现得很奇怪



我正试图使用kivy在raspberryPi上制作一个嵌入式应用程序,我有一个xinitrc,它调用我的应用程序,启动屏幕加载良好,但当我点击"1"或"2"时,我的应用程序会转到第二个屏幕,并立即跳回启动屏幕,直到我意外地点击ctrl,此时我得到:

Exception in thread Thread-4:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 754, in run
self.__target(*self.__args, **self.__kwargs)
File "/usr/lib/python2.7/dist-packages/kivy/input/providers/hidinput.py", line 701, in _thread_run
process_as_mouse_or_keyboard(*infos)
File "/usr/lib/python2.7/dist-packages/kivy/input/providers/hidinput.py", line 551, in process_as_mouse_or_keyboard
Keyboard.keycodes[l.lower()],
KeyError: 'ctrl'

然后一切都很好。我有一种感觉,这与我开始的极简主义环境有关。也许甚至还有一些东西还没有加载,但睡眠15并不能解决它,我只需要在不到15秒内按下ctrl,所以似乎不是这样。也许我只是启动键盘错了。下面是一个展示这种行为的小程序:

from __future__ import print_function
from kivy.app import App
from kivy.lang import Builder
from kivy.config import Config
from kivy.base import runTouchApp
from kivy.properties import ListProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.core.window import Window
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
import time
import random
import os
class StartScreen(Screen):
pass
class SecondScreen(Screen):
pass
class RootWidget(BoxLayout):
pass
class MyScreenManager(ScreenManager):
pass
root_widget = Builder.load_string('''
#:import hex kivy.utils.get_color_from_hex
MyScreenManager:
StartScreen:
SecondScreen:
<StartScreen>:
name: 'start'
kbContainer: kbContainer
BoxLayout:
id: kbContainer
canvas.before:
Color:
rgba: hex('#0000b1ff')
Rectangle:
pos: self.pos
size: self.size
orientation: 'vertical'
Label:
text: 'Welcome to the Example!'
color: hex('#f8ee3fff')
font_size: 30
BoxLayout:
Button:
background_normal: ''
background_color: hex('#0000b1ff')
#color: hex('#cc2729ff')
color: hex('#f8ee3fff')
text: 'go to second'
font_size: 30
on_release: app.root.current = 'second'
<SecondScreen>:
name: 'second'
BoxLayout:
canvas.before:
Color:
rgba: hex('#0000b1ff')
Rectangle:
pos: self.pos
size: self.size
orientation: 'vertical'
Label:
text: 'SecondScreen'
font_size: 30
BoxLayout:
canvas.before:
Color:
rgba: hex('#0000b1ff')
Rectangle:
pos: self.pos
size: self.size
orientation: 'vertical'
padding: 10
spacing: 10
Button:
background_normal: ''
border: (22,22,22,22)
background_color: hex('#f8ee3fff')
color: hex('#cc2729ff')
text: 'go to start!'
font_size: 30
on_release: app.root.current = 'start'
''')

class ExampleApp(App):
def __init__(self, **kwargs):
super(ExampleApp, self).__init__(**kwargs)
self._keyboard = Window.request_keyboard(
self._keyboard_closed, self, 'text')
if self._keyboard.widget:
pass
self._keyboard.bind(on_key_down=self._on_keyboard_down)
def _keyboard_closed(self):
print('My keyboard have been closed!')
self._keyboard.unbind(on_key_down=self._on_keyboard_down)
self._keyboard = None
def _on_keyboard_down(self, keyboard, keycode, text, modifiers):
print('The key', keycode, 'have been pressed')
print(' - text is %r' % text)
print(' - modifiers are %r' % modifiers)
if self.sm.current == "start":
if keycode[1] == '1':
self.sm.current = "second"
elif keycode[1] == '2':
self.sm.current = "second"
elif self.sm.current == "second":
if keycode[1] == '1':
self.sm.current = "start"
elif keycode[1] == '2':
self.sm.current = "start"
return True
def build(self):
self.sm = root_widget
self.sm.current = "start"
return self.sm
if __name__ == "__main__":
ExampleApp().run()

在Kivy应用程序中,定义了两个根小部件。一个来自kv文件MyScreenManager:,另一个来自Python代码return self.sm。删除第二个根小部件,如下所示。

def build(self):
self.sm = root_widget
return self.sm

屏幕管理器»默认第一个屏幕显示

默认情况下,添加到ScreenManager中的第一个屏幕将是显示

崩溃实际上是由hidinput未正确处理ctrl键引起的。我已经在hidinput中修复了这个问题,一旦我弄清楚如何不让密钥代码进入我启动kivy的shell,我就会尝试为它做PR。

最新更新