简体   繁体   中英

How to access attribute of dynamically created button in Kivy

I'm trying to create my calendar in Kivy. I managed to put it in the Popup widget, but now I do not know how to get the attribute. I'm trying to get the text from the dynamically created button that represents the date. My problem arises here. I do not know how to do it. Below is a code and kv file. Also, if someone needs a "calendar", you could download and modify it according to you're needs. It's free :)


Py file

from kivy.app import App
from kivy.uix.popup import Popup
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.properties import StringProperty, ObjectProperty, ListProperty, NumericProperty
import datetime


class Pocetni(BoxLayout):
    def calendar(self):
        Calendar().open()


class Calendar(Popup):
    td = datetime.datetime.today()
    day = td.day
    fdm = td.replace(day=1)
    d = "{:%w}"
    mg = "{:%B %Y}"
    month = StringProperty()
    change = ObjectProperty()
    days = ListProperty()
    first = NumericProperty()
    dani = ObjectProperty(None)

    def __init__(self, **kwargs):
        super(Calendar, self).__init__(**kwargs)
        self.month = str(self.mg.format(self.td))
        self.change = self.td

        self.update_days()

        self.first = self.d.format(self.fdm)

        self.draw_date()

    def update_days(self):
        for i in range(1, 32):
            prov = str(i)+'.'+str(self.change.month)+'.'+str(self.change.year)+'.'
            if i >= 28:
                try:
                    datetime.datetime.strptime(prov, "%d.%m.%Y.")
                    self.days.append(i)
                except ValueError:
                    pass
            else:
                self.days.append(i)

    def draw_date(self):
        if int(self.first) == 0:
            self.first = str(int(self.first) + 6)
        else:
            self.first = str(int(self.first) - 1)

        for i in range(int(self.first)):
            self.ids.dani.add_widget(Label(text=""))

        for j in self.days:
            if j == self.day and self.change.month == self.td.month and self.change.year == self.td.year:
                self.ids.dani.add_widget(Button(text=str(j), color=(1, 0, 0, 1),
                                                background_color=(1, 1, 1, .3),
                                                on_press=self.ispis))
            else:
                self.ids.dani.add_widget(Button(text=str(j),
                                                color=(0, 0, 0, 1),
                                                background_color=(1, 1, 1, .3)))

        self.days = []

    def next(self):
        self.ids.dani.clear_widgets()

        if self.change.month < 12:
            add = self.change.month + 1
            up = self.change.replace(month=add)
            self.change = up
            self.month = str(self.mg.format(up))
            self.fdm = self.change.replace(day=1)
            self.first = self.d.format(self.fdm)
            self.update_days()
            self.draw_date()
        else:
            start = self.change.month - 11
            new = self.change.year + 1
            up = self.change.replace(month=start, year=new)
            self.change = up
            self.month = str(self.mg.format(up))
            self.fdm = self.change.replace(day=1)
            self.first = self.d.format(self.fdm)
            self.update_days()
            self.draw_date()

    def previous(self):
        self.ids.dani.clear_widgets()

        if self.change.month > 1:
            add = self.change.month - 1
            up = self.change.replace(month=add)
            self.change = up
            self.month = str(self.mg.format(up))
            self.fdm = self.change.replace(day=1)
            self.first = self.d.format(self.fdm)
            self.update_days()
            self.draw_date()
        else:
            start = self.change.month + 11
            new = self.change.year - 1
            up = self.change.replace(month=start, year=new)
            self.change = up
            self.month = str(self.mg.format(up))
            self.fdm = self.change.replace(day=1)
            self.first = self.d.format(self.fdm)
            self.update_days()
            self.draw_date()

    def ispis(self, a):
        print(self.ids.dani.ids)
        print("Stiglo")


class CalendarApp(App):
    def build(self):
        return Pocetni()


if __name__ == '__main__':
    CalendarApp().run()

Kv file

<Datumi@Label>:
font_size: self.height / 4

<Date@Label>:
    color: 0, 0, 1, .8
    font_size: self.height / 2
    italic: True

<Calendar@Popup>:
    dani: dani
    title: "Calendar"
    title_size: '20sp'
    title_align: "center"
    separator_color: 1, 0, 0, 1
    size_hint: .9, .7
    auto_dismiss: False
    canvas.before:
        Color:
            rgba: 0, 0, 1, 1
        Rectangle:
            size: self.size
            pos: self.pos

    BoxLayout:
        orientation: "vertical"
        canvas.before:
            Color:
                rgba: 1, 1, 1, 1
            Rectangle:
                size: self.size
                pos: self.pos

        BoxLayout:
            size_hint_y: .15
            orientation: "horizontal"
            padding: 10
            canvas.before:
                Color:
                    rgba: .12, .54, .97, 1
                Rectangle:
                    size: self.size
                    pos: self.pos

            Label:
                font_size: self.height / 1.5
                size: self.texture_size
                text_size: self.size
                halign: "left"
                valign: "middle"
                text: root.month
                italic: True
                bold: True
            Button:
                size_hint_x: .2
                text: "back"
                on_press: root.previous()
            Button:
                size_hint_x: .2
                text: "next"
                on_press: root.next()

        BoxLayout:
            size_hint_y: .1
            orientation: "horizontal"
            Date:
                text: "Mon"
            Date:
                text: "Tue"
            Date:
                text: "Wed"
            Date:
                text: "Thu"
            Date:
                text: "Fri"
            Date:
                text: "Sat"
            Date:
                text: "Sun"

        GridLayout:
            id: dani
            cols: 7
            rows: 6

<Pocetni>:
    Button:
        text: "Poziv"
        on_press: root.calendar()

Red number is current day

红色数字是当前日期

One way to do it, is to add on_press=self.ispis to every button, not only the current date's.

            self.ids.dani.add_widget(Button(text=str(j),
                                            color=(0, 0, 0, 1),
                                            background_color=(1, 1, 1, .3),
                                            on_press=self.ispis))

So now, if you change your ispis function a little like that

def ispis(self, button):
    print(button.text)
    if button.color == [1, 0, 0, 1]:
        print("Stiglo")

you will get the button text and also check for the current day pressed...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM