Can Android open a vkeyboard instead of system keyboard?

115 views
Skip to first unread message

Ian Collins

unread,
Oct 23, 2016, 10:10:52 PM10/23/16
to Kivy users support
Hi,
I wrote this little example program using the Kivy (1.9.1) virtual keyboard (vkeyboard).
The program works perfectly on Windows and Linux - but the system keyboard always opens on Android (not the vkeyboard).

Can anyone point me in the right direction please? - I'm stumped.

(The apk for the app was built with buildozer).

Source for app.... (ok - it's rough, but was only a test app).

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.vkeyboard import VKeyboard
from kivy.uix.textinput import TextInput
from kivy.uix.boxlayout import BoxLayout

kv="""
<MyVKeyboardQwerty>:
layout: 'qwerty'

<MyVKeyboardNumeric>:
layout: 'numeric.json'
"""

'''
#Contents of file numeric.json in app directory

{
"title" : "Numeric",
"description" : "A numeric keypad",
"cols" : 3,
"rows": 4,
"normal_1": [
["7", "7", "7", 1],
["8", "8", "8", 1],
["9", "9", "9", 1]],
"normal_2": [
["4", "4", "4", 1],
["5", "5", "5", 1],
["6", "6", "6", 1]],
"normal_3": [
["1", "1", "1", 1],
["2", "2", "2", 1],
["3", "3", "3", 1]],
"normal_4": [
["0", "0", "0", 1],
[".", ".", ".", 1],
["\u232b", null, "backspace", 1]],
"shift_1": [
["7", "7", "7", 1],
["8", "8", "8", 1],
["9", "9", "9", 1]],
"shift_2": [
["4", "4", "4", 1],
["5", "5", "5", 1],
["6", "6", "6", 1]],
"shift_3": [
["1", "1", "1", 1],
["2", "2", "2", 1],
["3", "3", "3", 1]],
"shift_4": [
["0", "0", "0", 1],
[".", ".", ".", 1],
["\u232b", null, "backspace", 1]]
}
'''
class MyVKeyboardQwerty(VKeyboard):
def __init__(self, **kwargs):
super(MyVKeyboardQwerty, self).__init__(**kwargs)
self.setup_mode(True)

def setup_mode_dock(self, *largs):
'''Override from VKeyboard

Dock mode will reset the rotation, disable translation, rotation and
scale. Scale and position will be automatically adjusted to attach the
keyboard to the bottom of the screen.

.. note::
Don't call this method directly, use :meth:`setup_mode` instead.
'''

self.do_translation = False
self.do_rotation = False
self.do_scale = False
self.rotation = 0
win = self.get_parent_window()
scale = win.width / float(self.width)
#scale = 1.0
self.do_scale
self.scale = scale
print "setup scale " + str(scale)
print "win.height " + str(win.height)
print "self.height " + str(self.height)
#ty = win.height - ((self.height * scale) - 30.0)
#ty = win.height - ((self.height-30) * scale)
ty = win.height - (self.height * self.scale) - 30.0


#ty = win.height - self.height - 30.0
if ty >= self.target.top:
self.pos = 0.0, ty # (30.0) How do you get windows titlebar height
else:
self.pos = 0, 30

print "setup pos " + str(self.pos)

win.bind(on_resize=self._update_dock_mode)

def _update_dock_mode(self, win, *largs):
#ty = win.height - ((self.height * self.scale) - 30.0)
#ty = win.height - (self.height * self.scale) - 30.0
ty = win.height - self.height - 30.0
if ty >= self.target.top:
self.pos = 0.0, ty # top
else:
self.pos = 0, 30 #botton
print "update pos " + str(self.pos)
print "update scale " + str(self.scale)


class MyVKeyboardNumeric(VKeyboard):
def __init__(self, **kwargs):
super(MyVKeyboardNumeric, self).__init__(**kwargs)
self.setup_mode(False)


def setup_mode_dock(self, *largs):
''' Override from VKeyboard.

Dock mode will reset the rotation, disable translation, rotation and
scale. Scale and position will be automatically adjusted to attach the
keyboard to the bottom of the screen.

.. note::
Don't call this method directly, use :meth:`setup_mode` instead.
'''

self.do_translation = False
self.do_rotation = False
self.do_scale = False
self.rotation = 0
win = self.get_parent_window()
scale = win.width / float(self.width)
self.scale = scale
print "setup scale " + str(scale)
ty = win.height - (self.height * self.scale) - 30.0
if ty >= self.target.top:
self.pos = 0.0, ty
else:
self.pos = 0, 30

print "setup pos " + str(self.pos)

win.bind(on_resize=self._update_dock_mode)

def _update_dock_mode(self, win, *largs):
ty = win.height - (self.height * self.scale) - 30.0
# ty = win.height - self.height - 30.0
if ty >= self.target.top:
self.pos = 0.0, win.height - self.height - 30.0
else:
self.pos = 0, 30
print "setup pos " + str(self.pos)


class MyTextInput(TextInput):
def __init__(self, **kwargs):
super(MyTextInput, self).__init__(**kwargs)
self.wx = self.x
self.wy = self.y
self.wpos = self.pos


def on_focus(self, instance, value, *largs):
win = self.get_root_window()

if win:
win.release_all_keyboards()
win._keyboards = {}

if value: #User focus; use special keyboard
if self.input_type == 'number':
win.set_vkeyboard_class(MyVKeyboardNumeric)
else:
win.set_vkeyboard_class(MyVKeyboardQwerty)

print "VKeyboard true:", win._vkeyboard_cls, VKeyboard.layout_path
else: #User defocus; switch back to standard keyboard
win.set_vkeyboard_class(VKeyboard)
print "VKeyboard false:", win._vkeyboard_cls, VKeyboard.layout_path


##########

class vtest(App):

def build(self):
Builder.load_string(kv)

self.approot = BoxLayout(orientation='vertical')

b1 = BoxLayout(orientation='horizontal')
t11 = MyTextInput()
b1.add_widget(t11)
t12 = MyTextInput()
b1.add_widget(t12)
t13 = MyTextInput(text="12", input_type='number', input_filter='int')
b1.add_widget(t13)

b2 = BoxLayout(orientation='horizontal')
t21 = MyTextInput()
b2.add_widget(t21)
t22 = MyTextInput()
b2.add_widget(t22)
t23 = MyTextInput()
b2.add_widget(t23)

b3 = BoxLayout(orientation='horizontal')
t31 = MyTextInput()
b3.add_widget(t31)
t32 = MyTextInput()
b3.add_widget(t32)
t33 = MyTextInput()
b3.add_widget(t33)

b4 = BoxLayout(orientation='horizontal')
t41 = MyTextInput()
b4.add_widget(t41)
t42 = MyTextInput()
b4.add_widget(t42)
t43 = MyTextInput()
b4.add_widget(t43)

b5 = BoxLayout(orientation='horizontal')
t51 = MyTextInput()
b5.add_widget(t51)
t52 = MyTextInput()
b5.add_widget(t52)
t53 = MyTextInput()
b5.add_widget(t53)

b6 = BoxLayout(orientation='horizontal')
t61 = MyTextInput()
b6.add_widget(t61)
t62 = MyTextInput()
b6.add_widget(t62)
t63 = MyTextInput(text="12", input_type='number', input_filter='float')
b6.add_widget(t63)

b7 = BoxLayout(orientation='horizontal')
t71 = MyTextInput()
b7.add_widget(t71)
t72 = MyTextInput()
b7.add_widget(t72)
t73 = MyTextInput(input_type='number')
b7.add_widget(t73)

self.approot.add_widget(b1)
self.approot.add_widget(b2)
self.approot.add_widget(b3)
self.approot.add_widget(b4)
self.approot.add_widget(b5)
self.approot.add_widget(b6)
self.approot.add_widget(b7)


return self.approot



if __name__ == "__main__":
vtest().run()

Jacek Blocki

unread,
Mar 16, 2017, 9:50:20 AM3/16/17
to Kivy users support
I've tried to get vkeyboard on Android using TextInput keyboard property and setting keyboard mode to docked:
Window.use_syskeyboard = False
Window.allow_vkeyboard = True
Window.single_vkeyboard = True
Window.docked_vkeyboard = True

Unfortunately on Android I get system keyboard hiding virtual one. I can close swype keyboard and then use virtual one. Unfortunately
Window._win.hide_keyboard()
 
closes both system and virtual keyboard. The function is defined as simple pass, but it I think it is replaced by some (probably) non-python code and
kivy.core.window._window_sdl2
where it is defined is just a placeholder for headers.
BR, Jacek

Tom Grundy

unread,
Dec 24, 2018, 9:42:24 AM12/24/18
to Kivy users support
same issue here with kivy 1.10.1, python 3 (not crystax), buildozer in ubuntu in WSL, api 21.  The virtual keyboard does show, but the system keyboard always shows too.  I would like to only show the virtual keyboard and not the system one.  Did you find a solution or a workaround?

bagpuss

unread,
Dec 26, 2018, 3:02:01 PM12/26/18
to kivy-...@googlegroups.com
Hi.... No, never found a robust solution.... Redesigned my app to not need it. 
Hope you sort it out.
Cheers,
Ian

--
You received this message because you are subscribed to a topic in the Google Groups "Kivy users support" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/kivy-users/ngLpNuwI_sU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to kivy-users+...@googlegroups.com.
To post to this group, send email to kivy-...@googlegroups.com.
Visit this group at https://groups.google.com/group/kivy-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/1f69e665-68cb-422c-a0e1-5d57bd806c56%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Tom Grundy

unread,
Dec 26, 2018, 3:07:45 PM12/26/18
to kivy-...@googlegroups.com
Interesting.  Thanks for the reply.  Opened a new question here and on stackexchange, no hits yet.

You received this message because you are subscribed to the Google Groups "Kivy users support" group.
To unsubscribe from this group and stop receiving emails from it, send an email to kivy-users+...@googlegroups.com.

To post to this group, send email to kivy-...@googlegroups.com.
Visit this group at https://groups.google.com/group/kivy-users.
Reply all
Reply to author
Forward
0 new messages