有没有办法使用 Kivy 和 Python 在 TextInput 字段中显示数字键盘(最好带有气泡)?代码的新问题
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
我有一个应用程序,您可以在其中输入数字(很多),但键盘也是字母很难,我希望它只是数字 (0-9) 和一个点。有没有办法使用 Kivy 的 .kv 文件和 Python 来做到这一点?我已经在 .kv 文件中尝试了 input_type: 'number'
,但我无法让它工作。谢谢!
编辑:
我也尝试过使用气泡,但没有成功。不过,如果可能的话,最好有一个气泡数字板。
编辑 2:
我已经对这个问题提出了另一个悬赏,因为当我将 VKeyboard 放在物理设备上时(连同弹出窗口)它会坏掉。具体来说,VKeyboard 不会显示(并且在转到另一个 TextInput 字段后它也会崩溃)并且我的弹出窗口无法正确缩放。我的logcat如下图
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.
编辑 3:
感谢 Fadi Abu Raid,我得以解决弹出窗口问题。现在,我希望增加 VKeyboard 的尺寸,因为它在 phone 上非常小。我找到了 this post,但没有找到任何帮助。
你能 post 一段你的代码吗?如果你看看文档,正如你所说,你可以使用 属性 input_type:"number" 来做到这一点,但也许你遗漏了一些东西你的实例化或类似的东西,你能给我们看一段代码吗?以下内容来自文档:
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’.
我已经用这个例子完成了:
https://github.com/kivy/kivy/tree/master/examples/keyboard
您的 .kv 文件应该是这样的:
TextInput:
input_type: 'number'
on_focus: root.text_focused()
并且您应该有一种方法可以在您的 Python 文件中使用数字布局调用键盘。
from kivy.uix.vkeyboard import VKeyboard
def text_focused(self):
VKeyboard.layout = 'numeric.json'
player = VKeyboard()
从上面的 link 中获取布局并将其保存在与脚本相同的文件夹中。
输出应该是这样的:
更新
发布后我找到了更好的解决方案。
但是它缺少我添加的一些功能:
- 添加删除按钮。
- 触摸气泡键盘外部使其消失。
- 删除一些不必要的代码。
- 允许使用光标位置删除
您需要从 here 下载 arial-unicode-ms.ttf 字体并将字体放在与 main.py 脚本相同的文件夹中,以便能够在键盘上显示删除符号.
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()
输出
我有一个应用程序,您可以在其中输入数字(很多),但键盘也是字母很难,我希望它只是数字 (0-9) 和一个点。有没有办法使用 Kivy 的 .kv 文件和 Python 来做到这一点?我已经在 .kv 文件中尝试了 input_type: 'number'
,但我无法让它工作。谢谢!
编辑: 我也尝试过使用气泡,但没有成功。不过,如果可能的话,最好有一个气泡数字板。
编辑 2: 我已经对这个问题提出了另一个悬赏,因为当我将 VKeyboard 放在物理设备上时(连同弹出窗口)它会坏掉。具体来说,VKeyboard 不会显示(并且在转到另一个 TextInput 字段后它也会崩溃)并且我的弹出窗口无法正确缩放。我的logcat如下图
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.
编辑 3: 感谢 Fadi Abu Raid,我得以解决弹出窗口问题。现在,我希望增加 VKeyboard 的尺寸,因为它在 phone 上非常小。我找到了 this post,但没有找到任何帮助。
你能 post 一段你的代码吗?如果你看看文档,正如你所说,你可以使用 属性 input_type:"number" 来做到这一点,但也许你遗漏了一些东西你的实例化或类似的东西,你能给我们看一段代码吗?以下内容来自文档:
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’.
我已经用这个例子完成了:
https://github.com/kivy/kivy/tree/master/examples/keyboard
您的 .kv 文件应该是这样的:
TextInput:
input_type: 'number'
on_focus: root.text_focused()
并且您应该有一种方法可以在您的 Python 文件中使用数字布局调用键盘。
from kivy.uix.vkeyboard import VKeyboard
def text_focused(self):
VKeyboard.layout = 'numeric.json'
player = VKeyboard()
从上面的 link 中获取布局并将其保存在与脚本相同的文件夹中。
输出应该是这样的:
更新
发布后我找到了更好的解决方案
但是它缺少我添加的一些功能:
- 添加删除按钮。
- 触摸气泡键盘外部使其消失。
- 删除一些不必要的代码。
- 允许使用光标位置删除
您需要从 here 下载 arial-unicode-ms.ttf 字体并将字体放在与 main.py 脚本相同的文件夹中,以便能够在键盘上显示删除符号.
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()
输出