首页 > 解决方案 > kivy 日历:如何在 BoxLayout 中插入 kivy 日历并在其按钮中设置功能

问题描述

[已编辑]我是 kivy 的新手,我想问一下是否可以在 BoxLayout 中包含日历以及其他将显示日历选定按钮的输入的 BoxLayout。我试图将它添加为一个小部件,但不幸的是它抛出了这个错误

 File "C:\Python27\coffee.py", line 572, in calendar
 self.calendar.add_widget(self.cal)
 AttributeError: 'function' object has no attribute 'add_widget'

我想在单击日历中的按钮时添加一个 on_release 属性(如果可能),例如(按钮 1 -> 重定向到另一个屏幕或将其文本显示到另一个 BoxLayout)这里是 python 文件:

class Reservation(Screen):
    def __init__(self, **kwargs):
        super(Reservation, self).__init__(**kwargs)
        calen = ObjectProperty()
        self.calendar()
    def calendar(self):
        self.cal = CalendarWidget()
        self.calen.add_widget(self.cal)

这里是它的添加位置:

<Reservation>:
     name: "Reserve"
     calen: Cal
     BoxLayout:
         BoxLayout: 
             id: Cal
         BoxLayout: 
             id: output_box
             orientation: 'vertical'

标签: pythonpython-2.7kivy

解决方案


正如我在评论中指出的那样,调用具有相同名称的变量和函数是不好的编程习惯,因为它可以隐藏其他属性

言归正传,calendar = ObjectProperty()与 Calendar 没有链接的任何东西都没有链接BoxLayout,它也是一个局部变量,它的生命周期在构造函数完成时结束。在您使用self.calendar.add_widget(self.cal)self.calendar 的情况下,指的是您调用它的日历方法,并且显然方法的名称不是导致该错误的小部件。

ObjectProperty除了更改函数的名称之外,您必须做的是成为类的属性,并在 .kv 中分配它:

您必须使用时钟来访问小部件,因为子代尚未在构造中建立。在Clockschedule_once 的情况下,这将在之后被称为一个框架,因此它已经有了孩子。

*.py

from kivy.clock import Clock

...

class Reservation(Screen):
    calendar = ObjectProperty()
    def __init__(self, **kwargs):
        super(Reservation, self).__init__(**kwargs)
        Clock.schedule_once(lambda *args: self.create_calendar())

    def create_calendar(self):
        self.cal = CalendarWidget()
        self.calendar.add_widget(self.cal)

*.kv

<Reservation>:
     name: "Reserve"
     calendar: calendar # set value to ObjectProperty
     BoxLayout:
         BoxLayout: 
             id: calendar
         BoxLayout: 
             id: output_box
             orientation: 'vertical'

推荐阅读