问题
I am very new to Kivy, and have found an online example for a simple calculator here that I would like to try to modify using the Kivy examples ~/examples/keyboard/main.py. In that example is a numeric keyboard, but I can't seem to figure out how to get it to appear instead of the standard keyboard. Help or suggestions would be greatly appreciated.
Here is what I have started with:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout
from kivy.core.window import Window
from kivy.uix.vkeyboard import VKeyboard
from kivy.properties import ObjectProperty
from kivy.uix.button import Button
from kivy.config import Config
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy import require
Builder.load_string("""
<KeyboardScreen>:
displayLabel: displayLabel
kbContainer: kbContainer
BoxLayout:
orientation: 'vertical'
Label:
size_hint_y: 0.15
text: "Available Keyboard Layouts"
BoxLayout:
id: kbContainer
size_hint_y: 0.2
orientation:"horizontal"
padding: 10
Label:
id: displayLabel
size_hint_y: 0.15
markup: True
text: "[b]Key pressed[/b] - None"
halign: "center"
Button:
text: "Back"
size_hint_y: 0.1
on_release: root.manager.current = "mode"
Widget:
# Just a space taker to allow for the popup keyboard
size_hint_y: 0.5
<Calc>:
# This are attributes of the class Calc now
a: _a
b: _b
result: _result
KeyboardScreen:
AnchorLayout:
anchor_x: 'center'
anchor_y: 'top'
ScreenManager:
size_hint: 1, .9
id: _screen_manager
Screen:
name: 'screen1'
GridLayout:
cols:1
# TextInput:
Button:
id: _a
text: '3'
on_press:KeyboardScreen(name="keyboard")
# TextInput:
Button:
id: _b
text: '5'
on_press:KeyboardScreen(name="keyboard")
Label:
id: _result
Button:
text: 'sum'
# You can do the opertion directly
on_press: _result.text = str(int(_a.text) + int(_b.text))
Button:
text: 'product'
# Or you can call a method from the root class (instance of calc)
on_press: root.product(*args)
Screen:
name: 'screen2'
Label:
text: 'The second screen'
AnchorLayout:
anchor_x: 'center'
anchor_y: 'bottom'
BoxLayout:
orientation: 'horizontal'
size_hint: 1, .1
Button:
text: 'Go to Screen 1'
on_press: _screen_manager.current = 'screen1'
Button:
text: 'Go to Screen 2'
on_press: _screen_manager.current = 'screen2'""")
class Calc(FloatLayout):
# define the multiplication of a function
def product(self, instance):
# self.result, self.a and self.b where defined explicitely in the kv
self.result.text = str(int(self.a.text) * int(self.b.text))
class KeyboardScreen(Screen):
def __init__(self, **kwargs):
super(KeyboardScreen, self).__init__(**kwargs)
# self._add_keyboards()
self.set_layout("numeric.json","numeric.json")
self._keyboard = None
def set_layout(self, layout, button):
""" Change the keyboard layout to the one specified by *layout*. """
kb = Window.request_keyboard(
self._keyboard_close, self)
if kb.widget:
# If the current configuration supports Virtual Keyboards, this
# widget will be a kivy.uix.vkeyboard.VKeyboard instance.
self._keyboard = kb.widget
self._keyboard.layout = layout
else:
self._keyboard = kb
self._keyboard.bind(on_key_down=self.key_down,on_key_up=self.key_up)
def _keyboard_close(self, *args):
""" The active keyboard is being closed. """
if self._keyboard:
self._keyboard.unbind(on_key_down=self.key_down)
self._keyboard.unbind(on_key_up=self.key_up)
self._keyboard = None
def key_down(self, keyboard, keycode, text, modifiers):
""" The callback function that catches keyboard events. """
self.displayLabel.text = u"Key pressed - {0}".format(text)
# def key_up(self, keyboard, keycode):
def key_up(self, keyboard, keycode, *args):
""" The callback function that catches keyboard events. """
# system keyboard keycode: (122, 'z')
# dock keyboard keycode: 'z'
if isinstance(keycode, tuple):
keycode = keycode[1]
self.displayLabel.text += u" (up {0})".format(keycode)
class TestApp(App):
sm = None # The root screen manager
Config.set("kivy", "keyboard_mode", 'dock')
Config.write()
def build(self):
# self.sm = ScreenManager()
# self.sm.add_widget(KeyboardScreen(name="keyboard"))
return Calc()
if __name__ == '__main__':
TestApp().run()
回答1:
I know this question was asked 3 years ago, but since I came here seeking a similar answer I figured that I should answer now that I've got it figured out. Fortunately it's quite simple.
The VKeyboard documentation has a section detailing how to use custom layouts which is what the keyboard example is doing.
So to answer your question more directly, what you'll need to do is grab the numeric.json file from the keyboard example and put it in the directory next to your main.py.
From there you just need to add a keyboard setup function that grabs the virtual keyboard and sets the layout property to 'numeric.json'
. An example of this would be
kb = Window.request_keyboard(self._keyboard_close, self)
if kb.widget:
vkeyboard = kb.widget
vkeyboard.layout = 'numeric.json'
Additionally on desktop you need to specify that you want to use the 'docked' keyboard. You can do this by setting the keyboard_mode
property using kivy Config
Config.set("kivy", "keyboard_mode", 'dock')
And since it's often helpful to have everything in context, below is a minimum reproducible test app that does this.
import kivy
kivy.require("1.11.1")
from kivy.config import Config
Config.set("kivy", "keyboard_mode", 'dock')
from kivy.app import App
from kivy.core.window import Window
from kivy.uix.textinput import TextInput
class Calc(TextInput):
def _keyboard_close(self):
pass
def setup_keyboard(self):
kb = Window.request_keyboard(self._keyboard_close, self)
if kb.widget:
kb.widget.layout = 'numeric.json'
class TestApp(App):
def build(self):
root = Calc()
root.setup_keyboard()
return root
if __name__ == '__main__':
TestApp().run()
来源:https://stackoverflow.com/questions/43331290/numeric-input-in-kivy-with-python