KivyMD中Planlist组件文本不更新及组件通信问题求助
问题原因
文本无法更新和列表项点击不生效的核心原因都是实例不对应、属性绑定不符合Kivy规范,具体有三个错误点:
- Kivy的响应式属性(如
StringProperty)必须声明为类属性,你写在Planlist的__init__方法里无法触发绑定更新 - 你在多处重复创建了
Planlist、MainApp的独立实例:Content类的__init__里手动新建了MainApp和Planlist实例MainApp的__init__里手动新建了Planlist实例- kv文件中界面渲染的是另一个独立的
Planlist实例
你在提交输入时修改的是MainApp初始化时创建的内存实例,和界面上渲染的实例完全无关,自然看不到更新
- 列表项
on_press中直接调用screen_manager时,该对象不在Planlist的上下文作用域内,找不到对应实例所以点击无效
修改方案
1. 修改Python代码
from kivy.lang import Builder from kivy.uix.screenmanager import ScreenManager, Screen from kivy.metrics import dp from kivy.properties import StringProperty, ObjectProperty from kivy.uix.boxlayout import BoxLayout from kivymd.app import MDApp from kivymd.uix.button import MDFlatButton from kivymd.uix.dialog import MDDialog from kivymd.uix.textfield import MDTextField from kivymd.uix.list import MDList class RootWidget(BoxLayout): pass class MyScreenManager(ScreenManager): pass class ScreenPlan1(Screen): pass class Content(BoxLayout): # 删掉原有__init__内容,不需要手动新建实例 pass class Planlist(MDList): # 属性必须声明为类属性才能正常绑定 text_input_str = StringProperty("plan-unmodifiziert1") def __init__(self, **kwargs): super().__init__(**kwargs) class MainApp(MDApp): dialog = None planlist = ObjectProperty(None) def __init__(self, **kwargs): self.plan1 = None # 删掉原有手动创建root、planlist的代码,避免和kv渲染的实例冲突 super().__init__(**kwargs) def build(self): self.theme_cls.theme_style = "Dark" self.theme_cls.primary_palette = "BlueGray" return Builder.load_file("fit_app.kv") def show_confirmation_dialog(self): if not self.dialog: self.dialog = MDDialog( title="Namenseingabe:", type="custom", content_cls=Content(), buttons=[ MDFlatButton( text="CANCEL", text_color=self.theme_cls.primary_color, on_release=self.dialog_close ), ], md_bg_color=(.38, .38, .38, 1) ) self.dialog.open() def dialog_close(self, *args): self.dialog.dismiss(force=True) def on_text_validate(self, widget): # 直接修改绑定属性即可自动更新界面 self.planlist.text_input_str = widget.text self.dialog_close() MainApp().run()
2. 修改KV代码
RootWidget: orientation: "vertical" MDToolbar: title: "FitApp" md_bg_color: .2,.2,.2,1 specific_text_color: 1, 1, 1, 1 MDBottomNavigation: MDBottomNavigationItem: name: "nav1" text: "Dashboard" icon: "desktop-mac-dashboard" MDLabel: text: "Python" halign: "center" MDBottomNavigationItem: name: "nav2" text: "Workout" icon: "dumbbell" MyScreenManager: id: screen_manager Screen: name: "screen_overview" BoxLayout: orientation: "vertical" MDBoxLayout: size_hint: 1, .2 pos_hint: {"top": 1} MDLabel: text: "Neuer Trainingsplan" pos_hint: {"center_x":1, "top":1} text_size: self.size halign: 'left' valign: 'top' padding: "30dp", "30dp" MDIconButton: icon: "plus" pos_hint: {"center_x":1, "center_y":.92} on_release: app.show_confirmation_dialog() # 把界面上的Planlist实例绑定到app的planlist属性 Planlist: on_parent: app.planlist = self Screen: name: "plan1" MDLabel: text: "Screen" halign: "center" Button: text: "change" on_press: screen_manager.current = 'screen_overview' MDBottomNavigationItem: name: "nav3" text: "History" icon: "history" MDLabel: text: "Cobra" halign: "center" <Content>: orientation: "horizontal" spacing: "12dp" size_hint_y: None height: "100dp" MDTextField: id: plan_name hint_text: "Planname" # 直接调用全局运行的app实例方法 on_text_validate: app.on_text_validate(self) MDFlatButton: text: "OK" size: "70dp", "30dp" pos_hint: {"right": 1} on_release: app.on_text_validate(plan_name) <Planlist>: OneLineListItem: id: plan1 # 直接绑定属性自动更新 text: root.text_input_str # 从全局app获取screen_manager实例 on_press: app.root.ids.screen_manager.current = "plan1" OneLineListItem: text: "plan-unmodifiziert2" on_press: app.root.ids.screen_manager.current = "plan1" OneLineListItem: text: "plan-unmodifiziert3" on_press: app.root.ids.screen_manager.current = "plan1"
修改后文本更新和列表点击跳转的问题都会同时解决。
内容的提问来源于stack exchange,提问作者S4ker900
相关产品推荐
相关产品推荐

