KivyMD实例化Vkeyboard与MDDropdownMenu及报错处理方案
问题解决说明
报错根因及修复点
- 第一个ParserException报错是因为KV语法规则错误:VKeyboard的布局属性名是全小写
layout,你写了大写开头的Layout,KV中大写开头的标识符会被识别为类声明,属性名必须小写。 - MDDropdownMenu无法显示的两个错误:
- 类名拼写错误,正确写法是
MDDropdownMenu(最后一个M大写) - 该组件不能直接作为静态组件放置在屏幕上,需要绑定触发组件(例如按钮),通过回调方法调用
open()弹出
- 类名拼写错误,正确写法是
- 冗余代码删除:build方法中
return screen0之后的代码永远不会执行,可直接删除 - 虚拟键盘无需手动添加:Kivy默认在输入框获焦时自动弹出虚拟键盘,手动添加VKeyboard到界面会导致固定显示冗余键盘,影响交互。如果需要指定数字布局,可通过配置键盘参数实现。
输入获取方法
MDTextField的text属性本身就是标准字符串类型,不需要额外做类型转换,后端逻辑直接读取对应id的text属性即可。比如获取用户名输入,代码写法为:
username = self.root.get_screen('menu').ids.username.text
拿到的字符串可直接传入后端逻辑使用。
修复后可运行完整代码
from kivymd.app import MDApp from kivy.lang.builder import Builder from kivy.uix.screenmanager import Screen, ScreenManager from kivy.core.window import Window from kivymd.uix.menu import MDDropdownMenu Window.size = (300, 500) Window.keyboard_anim_args = {'d':.2,'t': 'in_out_expo'} Window.softinput_mode = "below_target" # 指定虚拟键盘默认布局为数字布局 Window.set_vkeyboard_layout('numeric.json') screen_helper = """ ScreenManager: MenuScreen: ProfileScreen: UploadScreen: <MenuScreen>: name: 'menu' MDTextField: id : username hint_text: "Enter Username" helper_text: "or click on forgot username" helper_text_mode: "on_focus" icon_right: "account" icon_right_color: app.theme_cls.primary_color pos_hint : {'center_x': 0.5, 'center_y': 0.4} size_hint_x:None width:250 mode : "rectangle" # 下拉菜单触发按钮 MDRaisedButton: id: menu_btn text: "选择城市" pos_hint: {'center_x':0.5, 'center_y':0.7} on_release: app.menu.open() MDRectangleFlatButton: text: 'Profile' pos_hint: {'center_x':0.5, 'center_y':0.5} on_press: root.manager.current = 'profile' MDRectangleFlatButton: text: 'Upload' pos_hint: {'center_x':0.5, 'center_y':0.6} on_press: root.manager.current = 'upload' <ProfileScreen>: name: 'profile' MDLabel: text: 'Welcome Oliver' halign: 'center' MDRectangleFlatButton: text: 'Menu' pos_hint: {'center_x':0.5, 'center_y':0.2} on_press: root.manager.current = 'menu' <UploadScreen>: name: 'upload' MDLabel: text: 'upload daw ek ek' halign: 'center' MDRectangleFlatButton: text: 'Menu' pos_hint: {'center_x':0.5, 'center_y':0.2} on_press: root.manager.current = 'menu' """ class MenuScreen(Screen): pass class ProfileScreen(Screen): pass class UploadScreen(Screen): pass class DemoApp(MDApp): def build(self): screen0 = Builder.load_string(screen_helper) # 初始化下拉菜单 menu_items = [ {"text": "Los Angeles", "viewclass": "OneLineListItem", "on_release": lambda x="Los Angeles": self.menu_callback(x)}, {"text": "Las Vegas", "viewclass": "OneLineListItem", "on_release": lambda x="Las Vegas": self.menu_callback(x)}, {"text": "New York", "viewclass": "OneLineListItem", "on_release": lambda x="New York": self.menu_callback(x)}, ] self.menu = MDDropdownMenu( caller=screen0.get_screen('menu').ids.menu_btn, items=menu_items, width_mult=4, ) return screen0 # 下拉菜单选择回调 def menu_callback(self, city): print(f"选择的城市是:{city}") self.menu.dismiss() # 测试获取输入框内容 username = self.root.get_screen('menu').ids.username.text print(f"输入的用户名是:{username}") DemoApp().run()
内容的提问来源于stack exchange,提问作者Oliver George Almonte
相关产品推荐
相关产品推荐

