如何将KivyMD日期选择器选中日期同步到kv文件的Label中?
将MDDatePicker选中日期同步到Label的解决方案
问题描述
我尝试将MDDatePicker中选中的日期同步到kv布局文件内指定的Label组件中,但目前编写的Python和kv代码无法实现该功能,需要技术帮助。
原Python代码
from tkinter import Button from kivymd.app import MDApp from kivy.lang import Builder from kivy.uix.screenmanager import ScreenManager from kivy.uix.boxlayout import BoxLayout from kivy.properties import ObjectProperty from kivymd.uix.picker import MDDatePicker from datetime import datetime from kivy.properties import StringProperty class Demo(ScreenManager): pass class Main(MDApp): def build(self): Builder.load_file("layout.kv") return Demo() def on_save(self, instance, value, date_range): print(instance, value, date_range) fristbeginn = StringProperty(value) def on_cancel(self, instance, value): '''Events called when the "CANCEL" dialog box button is clicked.''' def show_date_picker(self): date_dialog = MDDatePicker() date_dialog.bind(on_save=self.on_save, on_cancel=self.on_cancel) date_dialog.open() class Content(BoxLayout): nav_drawer = ObjectProperty() manager = ObjectProperty() Main().run()
原kv布局代码
<Content>: ScrollView: MDList: OneLineListItem: text: "Screen 1" on_release: root.nav_drawer.set_state("close") root.manager.current = "screen1" OneLineListItem: text: "Screen 2" on_release: root.nav_drawer.set_state("close") root.manager.current = "screen2" OneLineListItem: text: "Screen 3" on_release: root.nav_drawer.set_state("close") root.manager.current = "screen3" OneLineListItem: text: "Screen 4" on_release: root.nav_drawer.set_state("close") root.manager.current = "screen4" OneLineListItem: text: "Screen 5" on_release: root.nav_drawer.set_state("close") root.manager.current = "screen5" <Demo>: Screen: adaptive_size: True MDToolbar: pos_hint: {"top":1} title: "Menü" elevation: 8 left_action_items:[["menu", lambda x: nav_drawer.set_state("open") ]] MDNavigationDrawer: id: nav_drawer Content: nav_drawer: nav_drawer manager: screen_manager MDNavigationLayout: ScreenManager: id: screen_manager Screen: name: "screen1" MDLabel: text: "Guten Tag Bildschirm 1" halign: "center" Screen: name: "screen2" MDBoxLayout: adaptive_size: True size_hint: .8, None orientation: "vertical" pos_hint: {'center_x': .7, 'center_y': 0.55} spacing: '20dp' padding: ('20dp', '20dp', '20dp', '20dp') MDLabel: text: "Berechnung einer Frist nach §183 BGB:" halign: "left" font_style: "Subtitle1" MDLabel: text:"" halign: "center" MDLabel: text: "Wählen sie den Tag des Fristbeginn aus" halign: "left" font_style: "Subtitle2" MDRaisedButton: text: "Datum wählen" on_release:app.show_date_picker() MDLabel: id: fristbeginn text: root.fristbeginn halign: "left" font_style: "Subtitle2" MDRaisedButton: text: "MDRaised Button" MDRaisedButton: text: "MDRaised Button" MDRaisedButton: text: "MDRaised Button" MDRaisedButton: text: "MDRaised Button" MDRaisedButton: text: "MDRaised Button" Screen: name: "screen3" MDLabel: text: "Guten Tag Bildschirm 3" halign: "center" Screen: name: "screen4" MDLabel: text: "Guten Tag Bildschirm 4" halign: "center" Screen: name: "screen5" MDLabel: text: "Guten Tag Bildschirm 5" halign: "center"
问题分析
- 属性定义错误:在
on_save方法中创建的fristbeginn是局部变量,并非App类的可绑定属性,无法被kv布局访问。 - 绑定目标错误:kv中
text: root.fristbeginn的root指向当前Screen,但Screen未定义该属性,应该绑定到App实例的属性。 - 缺少可观察属性:App类中没有定义
StringProperty来存储选中日期,导致属性变化无法自动同步到UI。
修改后的代码
Python代码
from kivymd.app import MDApp from kivy.lang import Builder from kivy.uix.screenmanager import ScreenManager from kivy.uix.boxlayout import BoxLayout from kivy.properties import ObjectProperty, StringProperty from kivymd.uix.picker import MDDatePicker from datetime import datetime class Demo(ScreenManager): pass class Main(MDApp): # 定义全局可绑定的字符串属性,存储选中日期 fristbeginn = StringProperty("") def build(self): Builder.load_file("layout.kv") return Demo() def on_save(self, instance, value, date_range): # 将datetime对象格式化为可读字符串,赋值给App属性 self.fristbeginn = value.strftime("%Y-%m-%d") print(f"选中日期: {self.fristbeginn}") def on_cancel(self, instance, value): pass def show_date_picker(self): date_dialog = MDDatePicker() date_dialog.bind(on_save=self.on_save, on_cancel=self.on_cancel) date_dialog.open() class Content(BoxLayout): nav_drawer = ObjectProperty() manager = ObjectProperty() Main().run()
kv布局代码
<Content>: ScrollView: MDList: OneLineListItem: text: "Screen 1" on_release: root.nav_drawer.set_state("close") root.manager.current = "screen1" OneLineListItem: text: "Screen 2" on_release: root.nav_drawer.set_state("close") root.manager.current = "screen2" OneLineListItem: text: "Screen 3" on_release: root.nav_drawer.set_state("close") root.manager.current = "screen3" OneLineListItem: text: "Screen 4" on_release: root.nav_drawer.set_state("close") root.manager.current = "screen4" OneLineListItem: text: "Screen 5" on_release: root.nav_drawer.set_state("close") root.manager.current = "screen5" <Demo>: Screen: adaptive_size: True MDToolbar: pos_hint: {"top":1} title: "Menü" elevation: 8 left_action_items:[["menu", lambda x: nav_drawer.set_state("open") ]] MDNavigationDrawer: id: nav_drawer Content: nav_drawer: nav_drawer manager: screen_manager MDNavigationLayout: ScreenManager: id: screen_manager Screen: name: "screen1" MDLabel: text: "Guten Tag Bildschirm 1" halign: "center" Screen: name: "screen2" MDBoxLayout: adaptive_size: True size_hint: .8, None orientation: "vertical" pos_hint: {'center_x': .7, 'center_y': 0.55} spacing: '20dp' padding: ('20dp', '20dp', '20dp', '20dp') MDLabel: text: "Berechnung einer Frist nach §183 BGB:" halign: "left" font_style: "Subtitle1" MDLabel: text:"" halign: "center" MDLabel: text: "Wählen sie den Tag des Fristbeginn aus" halign: "left" font_style: "Subtitle2" MDRaisedButton: text: "Datum wählen" on_release: app.show_date_picker() MDLabel: id: fristbeginn # 绑定到App实例的fristbeginn属性 text: app.fristbeginn halign: "left" font_style: "Subtitle2" MDRaisedButton: text: "MDRaised Button" MDRaisedButton: text: "MDRaised Button" MDRaisedButton: text: "MDRaised Button" MDRaisedButton: text: "MDRaised Button" MDRaisedButton: text: "MDRaised Button" Screen: name: "screen3" MDLabel: text: "Guten Tag Bildschirm 3" halign: "center" Screen: name: "screen4" MDLabel: text: "Guten Tag Bildschirm 4" halign: "center" Screen: name: "screen5" MDLabel: text: "Guten Tag Bildschirm 5" halign: "center"
修改说明
- 在
Main类中添加fristbeginn = StringProperty(""),作为全局可观察属性,当值变化时自动通知UI更新。 on_save方法中,将选中的datetime对象格式化为YYYY-MM-DD字符串,赋值给self.fristbeginn。- kv布局中,将Label的
text绑定改为app.fristbeginn,直接关联到App实例的属性,实现数据同步。
内容的提问来源于stack exchange,提问作者OwenGreen
相关产品推荐
相关产品推荐

