[РЕШЕНО] См. ниже приложение принятого ответа и исходный код для работы виджета kivy DatePicker.
Я изучал Kivy и решил сделать виджеты выбора даты в качестве учебного упражнения.
import kivy
kivy.require('1.4.0')
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.app import App
from datetime import date, timedelta
class DatePicker(BoxLayout):
def __init__(self, **kwargs):
super(DatePicker, self).__init__(**kwargs)
self.date = date.today()
self.orientation = "vertical"
self.header = BoxLayout(orientation = 'horizontal',
size_hint = (1, 0.2))
self.body = GridLayout(cols = 7)
self.add_widget(self.header)
self.add_widget(self.body)
self.populate_body()
self.populate_header()
def populate_header(self):
self.header.clear_widgets()
self.previous_month = Button(text = "<")
self.next_month = Button(text = ">")
self.current_month = Label(text = repr(self.date),
size_hint = (2, 1))
self.header.add_widget(self.previous_month)
self.header.add_widget(self.current_month)
self.header.add_widget(self.next_month)
def populate_body(self):
self.body.clear_widgets()
date_cursor = date(self.date.year, self.date.month, 1)
while date_cursor.month == self.date.month:
self.date_label = Label(text = str(date_cursor.day))
self.body.add_widget(self.date_label)
date_cursor += timedelta(days = 1)
# Not yet implimented ###
# def set_date(self, day):
# self.date = date(self.date.year, self.date.month, day)
# self.populate_body()
# self.populate_header()
#
# def move_next_month(self):
# if self.date.month == 12:
# self.date = date(self.date.year + 1, 1, self.date.day)
# else:
# self.date = date(self.date.year, self.date.month + 1, self.date.day)
# def move_previous_month(self):
# if self.date.month == 1:
# self.date = date(self.date.year - 1, 12, self.date.day)
# else:
# self.date = date(self.date.year, self.date.month -1, self.date.day)
# self.populate_header()
# self.populate_body()
class MyApp(App):
def build(self):
return DatePicker()
if __name__ == '__main__':
MyApp().run()
Я наткнулся на блокпост и не могу понять, как продолжить. Я хочу добавить такой метод, чтобы при нажатии на date_labels они устанавливали self.date в объект даты с этой частью дня.
я пытался добавить
self.date_label.bind(on_touch_down = self.set_date(date_cursor.day))
но получил только максимальные ошибки рекурсии.
РЕШЕНИЕ:
import kivy
kivy.require('1.4.0')
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.app import App
from datetime import date, timedelta
from functools import partial
class DatePicker(BoxLayout):
def __init__(self, *args, **kwargs):
super(DatePicker, self).__init__(**kwargs)
self.date = date.today()
self.orientation = "vertical"
self.month_names = ('January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December')
if kwargs.has_key("month_names"):
self.month_names = kwargs['month_names']
self.header = BoxLayout(orientation = 'horizontal',
size_hint = (1, 0.2))
self.body = GridLayout(cols = 7)
self.add_widget(self.header)
self.add_widget(self.body)
self.populate_body()
self.populate_header()
def populate_header(self, *args, **kwargs):
self.header.clear_widgets()
previous_month = Button(text = "<")
previous_month.bind(on_press=partial(self.move_previous_month))
next_month = Button(text = ">", on_press = self.move_next_month)
next_month.bind(on_press=partial(self.move_next_month))
month_year_text = self.month_names[self.date.month -1] + ' ' + str(self.date.year)
current_month = Label(text=month_year_text, size_hint = (2, 1))
self.header.add_widget(previous_month)
self.header.add_widget(current_month)
self.header.add_widget(next_month)
def populate_body(self, *args, **kwargs):
self.body.clear_widgets()
date_cursor = date(self.date.year, self.date.month, 1)
for filler in range(date_cursor.isoweekday()-1):
self.body.add_widget(Label(text=""))
while date_cursor.month == self.date.month:
date_label = Button(text = str(date_cursor.day))
date_label.bind(on_press=partial(self.set_date,
day=date_cursor.day))
if self.date.day == date_cursor.day:
date_label.background_normal, date_label.background_down = date_label.background_down, date_label.background_normal
self.body.add_widget(date_label)
date_cursor += timedelta(days = 1)
def set_date(self, *args, **kwargs):
self.date = date(self.date.year, self.date.month, kwargs['day'])
self.populate_body()
self.populate_header()
def move_next_month(self, *args, **kwargs):
if self.date.month == 12:
self.date = date(self.date.year + 1, 1, self.date.day)
else:
self.date = date(self.date.year, self.date.month + 1, self.date.day)
self.populate_header()
self.populate_body()
def move_previous_month(self, *args, **kwargs):
if self.date.month == 1:
self.date = date(self.date.year - 1, 12, self.date.day)
else:
self.date = date(self.date.year, self.date.month -1, self.date.day)
self.populate_header()
self.populate_body()
class MyApp(App):
def build(self):
return DatePicker()
if __name__ == '__main__':
MyApp().run()
self.date_label
можно заменить толькоdate_label
везде. В качестве примечания к примечанию, пожалуйста, уважайте pep8: P, никаких пробелов вокруг=
в вызове функции, две и только две строки между каждым определением класса. хорошего дня :) edit: а также спасибо за создание средства выбора даты для kivy, я уверен, что это может быть полезно другим :) - person Tshirtman   schedule 05.12.2012