Is there a way to show a number pad (preferably with a bubble) in a TextInput field using Kivy and Python? NEW ISSUE WITH CODE

陌路散爱 提交于 2021-01-27 16:16:18

问题


I have an app where you input numbers (a lot) and it gets hard that the keyboard is also letters, I would like it to be just numbers (0-9), and a dot. Is there any way to do this using Kivy's .kv file and Python? I have tried input_type: 'number' in the .kv file, but I couldn't get it to work. Thanks!

Edit: I have also tried using bubbles, no luck. Although, it would be nice to have a bubble number pad if possible.

Edit 2: I have put another bounty on this question because when I put the VKeyboard on a physical device (along with a popup) it breaks. In specific, the VKeyboard wont show up (and it also crashes after going to another TextInput field) and my popup doesn't scale correctly. My logcat is shown below.

10-21 08:30:23.944 11210 11233 I python  : [INFO   ] [Logger      ] Record log in /data/user/0/org.test.bfcalc5/files/app/.kivy/logs/kivy_20-10-21_3.txt
10-21 08:30:23.944 11210 11233 I python  : [INFO   ] [Kivy        ] v1.11.1
10-21 08:30:23.945 11210 11233 I python  : [INFO   ] [Kivy        ] Installed at "/data/user/0/org.test.bfcalc5/files/app/_python_bundle/site-packages/kivy/__init__.pyc"
10-21 08:30:23.946 11210 11233 I python  : [INFO   ] [Python      ] v3.8.1 (default, Oct 18 2020, 14:08:48) 
10-21 08:30:23.946 11210 11233 I python  : [Clang 8.0.2 (https://android.googlesource.com/toolchain/clang 40173bab62ec7462
10-21 08:30:23.946 11210 11233 I python  : [INFO   ] [Python      ] Interpreter at ""
10-21 08:30:25.540 11210 11233 I python  : [INFO   ] [Factory     ] 184 symbols loaded
10-21 08:30:26.210 11210 11233 I python  : [INFO   ] [Image       ] Providers: img_tex, img_dds, img_sdl2, img_gif (img_pil, img_ffpyplayer ignored)
10-21 08:30:26.289 11210 11233 I python  : [INFO   ] [Text        ] Provider: sdl2
10-21 08:30:26.387 11210 11233 I python  : [INFO   ] [Window      ] Provider: sdl2
10-21 08:30:26.437 11210 11233 I python  : [INFO   ] [GL          ] Using the "OpenGL ES 2" graphics system
10-21 08:30:26.439 11210 11233 I python  : [INFO   ] [GL          ] Backend used <sdl2>
10-21 08:30:26.440 11210 11233 I python  : [INFO   ] [GL          ] OpenGL version <b'OpenGL ES 3.2 build 1.10@5187610'>
10-21 08:30:26.440 11210 11233 I python  : [INFO   ] [GL          ] OpenGL vendor <b'Imagination Technologies'>
10-21 08:30:26.441 11210 11233 I python  : [INFO   ] [GL          ] OpenGL renderer <b'PowerVR Rogue GE8322'>
10-21 08:30:26.442 11210 11233 I python  : [INFO   ] [GL          ] OpenGL parsed version: 3, 2
10-21 08:30:26.442 11210 11233 I python  : [INFO   ] [GL          ] Texture max size <4096>
10-21 08:30:26.443 11210 11233 I python  : [INFO   ] [GL          ] Texture max units <16>
10-21 08:30:26.482 11210 11233 I python  : [INFO   ] [Window      ] auto add sdl2 input provider
10-21 08:30:26.484 11210 11233 I python  : [INFO   ] [Window      ] virtual keyboard allowed, single mode, docked
10-21 08:30:26.756 11210 11233 I python  : [INFO   ] [GL          ] NPOT texture support is available
10-21 08:30:26.818 11210 11233 I python  : [WARNING] [Base        ] Unknown <android> provider
10-21 08:30:26.819 11210 11233 I python  : [INFO   ] [Base        ] Start application main loop
10-21 08:30:26.938 11210 11233 I python  : [WARNING] [GL          ] Unpack subimage support is not available
10-21 08:30:33.249 11210 11233 I python  : [INFO   ] [Base        ] Leaving application in progress...
10-21 08:30:33.250 11210 11233 I python  :  Traceback (most recent call last):
10-21 08:30:33.250 11210 11233 I python  :    File "/home/ubuntu/BFCalcApp/.buildozer/android/app/main.py", line 88, in <module>
10-21 08:30:33.251 11210 11233 I python  :    File "/home/ubuntu/BFCalcApp/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/bfcalc5/kivy/app.py", line 855, in run
10-21 08:30:33.253 11210 11233 I python  :    File "/home/ubuntu/BFCalcApp/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/bfcalc5/kivy/base.py", line 504, in runTouchApp
10-21 08:30:33.255 11210 11233 I python  :    File "/home/ubuntu/BFCalcApp/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/bfcalc5/kivy/core/window/window_sdl2.py", line 747, in mainloop
10-21 08:30:33.257 11210 11233 I python  :    File "/home/ubuntu/BFCalcApp/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/bfcalc5/kivy/core/window/window_sdl2.py", line 479, in _mainloop
10-21 08:30:33.258 11210 11233 I python  :    File "/home/ubuntu/BFCalcApp/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/bfcalc5/kivy/base.py", line 339, in idle
10-21 08:30:33.259 11210 11233 I python  :    File "/home/ubuntu/BFCalcApp/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/bfcalc5/kivy/clock.py", line 591, in tick
10-21 08:30:33.260 11210 11233 I python  :    File "kivy/_clock.pyx", line 384, in kivy._clock.CyClockBase._process_events
10-21 08:30:33.261 11210 11233 I python  :    File "kivy/_clock.pyx", line 414, in kivy._clock.CyClockBase._process_events
10-21 08:30:33.261 11210 11233 I python  :    File "kivy/_clock.pyx", line 412, in kivy._clock.CyClockBase._process_events
10-21 08:30:33.262 11210 11233 I python  :    File "kivy/_clock.pyx", line 154, in kivy._clock.ClockEvent.tick
10-21 08:30:33.263 11210 11233 I python  :    File "kivy/_clock.pyx", line 86, in kivy._clock.ClockEvent.get_callback
10-21 08:30:33.264 11210 11233 I python  :    File "/home/ubuntu/BFCalcApp/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/bfcalc5/kivy/weakmethod.py", line 56, in is_dead
10-21 08:30:33.265 11210 11233 I python  :  ReferenceError: weakly-referenced object no longer exists
10-21 08:30:33.266 11210 11233 I python  : Python for android ended.

Edit 3: Thanks to Fadi Abu Raid, I was able to figure out the Pop-Up issue. Right now, I am looking to increase the size of the VKeyboard as it is very small on a phone. I found this post, but I did not find any help from it.


回答1:


I have done it using this example:

https://github.com/kivy/kivy/tree/master/examples/keyboard

Your .kv file it should be like this:

TextInput:
    input_type: 'number'
    on_focus: root.text_focused()

And you should have a method to call the keyboard with numeric layout in your Python file.

from kivy.uix.vkeyboard import VKeyboard 

def text_focused(self):
    VKeyboard.layout = 'numeric.json'
    player = VKeyboard()

Get the layout from the link above and save it in the same folder with your script.

And the output should look like this:

UPDATE

After posting this I have found a better solution here.

However it lacks some features that I have added :

  1. Add delete button.
  2. A touch outside the bubble keypad makes it disappear.
  3. Remove some unnecessary bits of code.
  4. Allow deleting using cursor position

You need to download arial-unicode-ms.ttf font from here and place the font in the same folder as your main.py script to be able to display the delete symbol on the keypad.

main.py

from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.bubble import Bubble, BubbleButton
from kivy.lang import Builder
from kivy.core.window import Window


class CustomBubbleButton(BubbleButton):
    
    def add_text(self):
        app= App.get_running_app()
        index=app.root.text_input.cursor[0]-1
        if self.text!="⌫":
            app.root.text_input.text= app.root.text_input.text[:index+1]+self.text + app.root.text_input.text[index+1:]
            app.root.text_input.cursor=(index+2,0)
        else:
            app.root.text_input.text=app.root.text_input.text[:index] + app.root.text_input.text[index+1:]
            app.root.text_input.cursor=(index,0)
    pass


class NumericKeyboard(Bubble):
    
    def on_touch_up(self, touch):
        app= App.get_running_app()
        if  not self.collide_point(*touch.pos) and not app.root.text_input.collide_point(*touch.pos):
            app.root.remove_widget(app.root.bubb)
            app.root.text_input.focus=False
            delattr(app.root, 'bubb')     
                   
    def __init__(self, **kwargs):
        super(NumericKeyboard, self).__init__(**kwargs)
        self.create_bubble_button()

    def create_bubble_button(self):
        numeric_keypad = ['7', '8', '9', '4', '5', '6', '1', '2', '3', '.', '0', '⌫']
        for x in numeric_keypad:
            bubb_btn = CustomBubbleButton(text=str(x),font_name='arial-unicode-ms.ttf')
            self.layout.add_widget(bubb_btn)


class BubbleShowcase(FloatLayout):
    
    def show_bubble(self, *l):
        if not hasattr(self, 'bubb'):
            self.bubb = NumericKeyboard()
            self.bubb.arrow_pos = "bottom_mid"
            self.add_widget(self.bubb)

Builder.load_file("test.kv")

class TestBubbleApp(App):
    title = "Numeric Key Pad - Using Bubble"

    def build(self):
        return BubbleShowcase()

if __name__ == '__main__':
    Window.show_cursor = True
    TestBubbleApp().run()

test.kv

<CustomBubbleButton>:
    on_release: root.add_text()
        
<NumericKeyboard>:
    layout: layout
    size_hint: (None, None)
    size: (160, 120)
    pos_hint: {'center_x': .5, 'y': .6}

    GridLayout:
        id: layout
        cols: 3

<BubbleShowcase>:
    text_input: text_input
    canvas:
        Color:
            rgba: 0, 1, 1, 1
        Rectangle:
            size: self.width, self.height
    TextInput:
        id: text_input
        keyboard_mode: 'managed'
        pos_hint: {'center_x': .5, 'y': .54}
        size_hint: (0.2, 0.06)
        cursor_blink: True
        font_size: 20
        multiline: False
        on_focus: root.show_bubble()

Output




回答2:


Can you post a piece of your code ? if you look at the docs, as you said, you can use the property input_type:"number" to do that, but maybe your are missing something in your instantiation or something like that, can you show us a piece of code? The following is from the docs:

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




回答3:


Need help, the documentation is very much confusing for VKeyboard, I tried the code suggested above, but its not work for me. Please check this simple code with one textinput, where i am trying to get keyboard out. But cant do it..

main.py

import kivy
from kivy.app import App
from kivy.lang.builder import Builder
from kivy.uix.vkeyboard import VKeyboard
from kivy.uix.floatlayout import FloatLayout

Builder.load_file('main.kv')

class MainLayout(FloatLayout):
 def text_focused(self):
  VKeyboard.layout = 'numeric.json'
  player = VKeyboard()

class TestApp(App):
 def build(self):
  return MainLayout()

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

main.kv

<MainLayout>
 TextInput:
  size_hint: (0.1,0.05)
  pos_hint: {'center_x':0.5,'center_y':0.8}
  input_type: 'number'
  on_focus: root.text_focused()


来源:https://stackoverflow.com/questions/64196094/is-there-a-way-to-show-a-number-pad-preferably-with-a-bubble-in-a-textinput-fi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!