[已解決]請參閱下面有關運行kivy DatePicker小工具的接受答案和源代碼的應用。Kivy Date Picker Widget
我一直在學習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))
,但只得到了最大的遞歸誤差。
SOLUTION:
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()
此外,作爲評論,因爲它不是你的問題,但你不需要存儲在你的實例,如果你不會使用後的值,所以在populate_body中,'self.date_label'可以被' date_label'到處都是。作爲旁註的旁註,請尊重pep8:P,在函數調用中'='周圍沒有空格,每個類定義之間只有兩行和兩行。祝你有個美好的一天:)編輯:哦,也感謝爲kivy製作日期選擇器,我相信它可以對其他人有用:) – Tshirtman
是的,我經歷了幾次迭代date_label和self.date_label,只是發生帖子以這種形式。 無論何時,當我看到東西時,我都會看到你的頭像。我開始認爲這是某種默認/模仿頭像! – Horba
呵呵,好吧,我嘗試回答所有kivy問題^^ – Tshirtman