自己捣鼓了一个python小程序可视化的集合,需要调用一个下拉日历控件进行日期时间的选择。先百度了一通,找到两篇文章写的很完善了,稍加改动就可以直接调用。最大的问题是没有时-分-秒选择的功能,其中一位添加了这个功能。。。。。。但是。。。。。。竟然做起来收费的买卖
求人不如求己,既然主体代码都有了,那我们就自己来添加剩下的这点小功能。
import datetime
import calendar
datetime = calendar.datetime.datetime
timedelta = calendar.datetime.timedelta
class Calendar:
def __init__(s, point = None):
s.master = tk.Toplevel()
s.master.withdraw()
s.master.attributes('-topmost' ,True)
fwday = calendar.SUNDAY
year = datetime.now().year
month = datetime.now().month
locale = None
sel_bg = '#ecffc4'
sel_fg = '#05640e'
s._date = datetime(year, month, 1) #每月第一日
s._selection = None #设置为未选中日期
s.G_Frame = ttk.Frame(s.master)
s._cal = s.__get_calendar(locale, fwday)
s.__setup_styles() # 创建自定义样式
s.__place_widgets() # pack/grid 小部件
s.__config_calendar() # 调整日历列和安装标记
# 配置画布和正确的绑定,以选择日期。
s.__setup_selection(sel_bg, sel_fg)
# 存储项ID,用于稍后插入。
s._items = [s._calendar.insert('', 'end', values='') for _ in range(6)]
# 在当前空日历中插入日期
s._update()
s.G_Frame.pack(expand = 1, fill = 'both')
s.master.overrideredirect(1)
s.master.update_idletasks()
width, height = s.master.winfo_reqwidth(), s.master.winfo_reqheight()
s.height=height
if point:
x, y = point[0], point[1]
else:
x, y = (s.master.winfo_screenwidth() - width)/2, (s.master.winfo_screenheight() - height)/2
s.master.geometry('%dx%d+%d+%d' % (width, height, x, y)) #窗口位置居中
s.master.after(300, s._main_judge)
s.master.deiconify()
s.master.focus_set()
s.master.wait_window() #这里应该使用wait_window挂起窗口,如果使用mainloop,可能会导致主程序很多错误
def __get_calendar(s, locale, fwday):
if locale is None:
return calendar.TextCalendar(fwday)
else:
return calendar.LocaleTextCalendar(fwday, locale)
def __setitem__(s, item, value):
if item in ('year', 'month'):
raise AttributeError("attribute '%s' is not writeable" % item)
elif item == 'selectbackground':
s._canvas['background'] = value
elif item == 'selectforeground':
s._canvas.itemconfigure(s._canvas.text, item=value)
else:
s.G_Frame.__setitem__(s, item, value)
def __getitem__(s, item):
if item in ('year', 'month'):
return getattr(s._date, item)
elif item == 'selectbackground':
return s._canvas['background']
elif item == 'selectforeground':
return s._canvas.itemcget(s._canvas.text, 'fill')
else:
r = ttk.tclobjs_to_py({
item: ttk.Frame.__getitem__(s, item)})
return r[item]
def __setup_styles(s):
# 自定义TTK风格
style = ttk.Style(s.master)
arrow_layout = lambda dir: (
[('Button.focus', {
'children': [('Button.%sarrow' % dir, None)]})]
)
style.layout('L.TButton', arrow_layout('left'