3

I have a Screen where I want to ask a question, so in the kv language, I have

Screen:
        name: 'keyb'
        BoxLayout:
            orientation: 'vertical'
            Label:
                id: rnl
                size_hint_y: .1
                text: ''
            TextInput:
                id: tinput
                hint_text: '.mid'
                size_hint: (.8, .1)
                pos_hint: {'x': .1}
                multiline: False
                on_focus: root.focusCallback(args[1])
            Widget:
                size_hint_y: .7

When I want to ask the question, I select the screen and set the focus to the TextInput

 self.tinput.text = ""
 self.screens.current = 'keyb'
 Clock.schedule_once(self.focusKbd, .1)

which then cascades through this code:

def focusKbd(self, x):
    self.tinput.focus = True
def focusCallback(self, f):
    if not f:
        # Deal with input now
        self.screens.current = 'seq'

Somewhere in this code, I would like to

  1. Select which VKeyboard layout the TextInput is going to pop up (and it will be different in other parts of my code)
  2. Adjust the height of the VKeyboard.

I don't understand where the VKeyboard comes from in Text Input; is there some way I can get a reference to it from the TextInput?

This is a restatement of https://stackoverflow.com/questions/36414654/how-can-i-change-the-size-of-kivys-vkeyboard There is a hint there, but not enough to get me going!

*********************Edit: **************************

Trying to understand the answer from Tshirtman, I put this at the top of my main widget:

Window.set_vkeyboard_class(get_vkeyboard())

and then added

def get_vkeyboard():
    print '>>>>>>>>>>>>>>>>>>>>>>>>>>in get_vkeyboard'
    return VKeyboard

I found that get_vkeyboard() was called immediately, long before I needed a keyboard. So it seems that I'm not going to be able to control anything about the appearance of the VKeyboard dynamically in get_vkeyboard(). Please correct me if I'm confused (which I undoubtedly am!).

Is there some other way to modify the appearance of the VKeyboard dynamically?

P.S. There seems to be a hint in Focus Behavior:

input_type is an OptionsProperty and defaults to ‘text’. Can be one of ‘text’, ‘number’, ‘url’, ‘mail’, ‘datetime’, ‘tel’ or ‘address’.

I added "input_type: 'number'" to a TextInput in .kv, but it didn't have any affect.

Community
  • 1
  • 1
rich
  • 425
  • 3
  • 17
  • Input type is more relevant on platforms like android which provide a native keyboard (not kivy vkeyboard) with multiple layout depending on the usage. – Tshirtman Feb 08 '17 at 09:13

1 Answers1

0

You can set keyboard class using Window.set_vkeyboard_class, but nothing prevents you from registering any function that returns a keyboard instance there, so you could use the context (your app's state) to decide which class will be used, dynamically. Since you are returning an instance yourself in this case, you can decide of its size, pos, and other details. I used this technique in a few app to use Animation on the instance to place it in a particular spot of the screen smoothly.

pseudo example:

from kivy.core.window import Window
from kivy.uix.vkeyboard import VKeyboard
from kivy.animation import Animation
from kivy.uix.screenmanager import ScreenManager, Screen

class KeyboardA(VKeyboard):
    def place(self):
        self.center_x = Window.center_x
        self.top = 0
        Animation(y=100, t='out_elastic', d=.4).start(self)

class KeyboardB(VKeyboard):
     def place(self):
        self.opacity = 0
        Animation(opacity=1).start(self)

class MyApp(App):
     def build(self):
         sm = ScreenManger()
         sm.add_widget(Screen(name='a'))
         sm.add_widget(Screen(name='b'))
         return sm

     def get_keyboard(self, **kwargs):
         if self.root.current == 'a':
             kb = KeyboardA(**kwargs)

         else:
             kb = KeyboardB(**kwargs)

         kb.place()
         return kb

Window.set_vkeyboard_class(app.get_keyboard)

untested, but you should get the idea.

Tshirtman
  • 5,859
  • 1
  • 19
  • 26
  • I'm still trying to understand this, but I suspect that the last line should be something like Window.set_vkeyboard_class(app.get_keyboard()) and it should be included in the code somewhere, like in build() – rich Feb 06 '17 at 21:54
  • Ouch, nearly, fixing. – Tshirtman Feb 08 '17 at 09:09