我正在构建一个用于选择开始日期的下拉菜单。它有3个级联,分别为年,月,日。生成日级联的内容,以便可用日期对所选年份和月份都是真实的。 用户可能/可能在单个会话期间多次更改日期。
我的问题:当用户第一次选择年/月时,会生成days命令。此后,任何新的年/月组合,以下代码只是将命令添加到级联。因此,日级联包含两个月的日子。
我一直试图让代码删除旧的菜单栏条目daymenu并根据新数据重新创建它。 我想知道,如何对已有的,正在运行的菜单栏进行此类更改?我已经搜索了tkinter文档,但无法实现它。
import calendar as cal
import Tkinter as tk
import datetime
import os.path
window = tk.Tk()
# Menu variables:
year = tk.IntVar()
month = tk.IntVar()
day = tk.IntVar()
hour = tk.IntVar()
minute = tk.IntVar()
dur_hour = tk.IntVar()
dur_minute = tk.IntVar()
duration = tk.StringVar()
start = tk.StringVar()
# list initializations
list_of_years = []
list_of_months = []
list_of_hours = []
list_of_days = []
list_of_minutes = []
def year_seter(value):
year.set(value)
all_for_day()
def all_for_day(): #checks if the data needed to determine number of days in the month is present
list_of_days = []
y = year.get()
m = month.get()
lenght_of_month = cal.monthrange(y,m)
lenght_of_month2 = lenght_of_month[1]
if m != 0 and y != 0:
make_daylist(lenght_of_month2)
make_daymenu()
def month_seter(value):
month.set(value)
all_for_day()
def day_seter(value):
day.set(value)
def time_parameters():
the_date = datetime.datetime(1,1,1,0,0,0,0)
the_date = the_date.now()
end_year = the_date.year
make_yearlist(1995, end_year)
make_monthlist()
make_hourlist()
make_minutelist()
def make_yearlist(the_year, end_year):
while the_year <= end_year:
list_of_years.append(the_year)
the_year += 1
def make_monthlist():
for i in range(12):
list_of_months.append(i + 1)
def make_daylist(num_days):
for i in range(num_days):
list_of_days.append(i + 1)
def make_hourlist():
for i in range(24):
list_of_hours.append(i)
def make_minutelist():
for i in range(60):
list_of_minutes.append(i)
def make_daymenu():
for the_day in list_of_days:
daymenu.add_command(label=the_day, command=lambda : day_seter(the_day))
window.config(menu=menubar)
# The following constructs the menu
time_parameters()
menubar = tk.Menu(window)
yearmenu = tk.Menu(menubar)
for the_year in list_of_years:
yearmenu.add_command(label=str(the_year), command=lambda the_year=the_year: year_seter(the_year))
menubar.add_cascade(label = 'Year', menu=yearmenu)
window.config(menu=menubar)
monthmenu = tk.Menu(menubar)
for the_month in list_of_months:
monthmenu.add_command(label=the_month, command=lambda the_month=the_month: month_seter(the_month))
menubar.add_cascade(label = 'Month', menu=monthmenu)
window.config(menu=menubar)
daymenu = tk.Menu(menubar)
menubar.add_cascade(label = 'Day', menu=daymenu)
window.config(menu=menubar)
window.mainloop()
答案 0 :(得分:2)
您可以在添加新条目之前删除daymenu
中的所有条目:
def make_daymenu():
daymenu.delete(0,31)
for the_day in list_of_days:
daymenu.add_command(label=the_day, command=lambda : day_setter(the_day))
window.config(menu=menubar)
答案 1 :(得分:0)
遇到您的代码以选择日期。最近不得不为类似的目的写一个简单的日历。我可以为您提供该选项。我认为这个选项更方便选择日期。
import calendar, datetime, Tkinter
class calendarTk(Tkinter.Frame): # class calendarTk
""" Calendar, the current date is exposed today, or transferred to date"""
def __init__(self,master=None,date=None,dateformat="%d/%m/%Y",command=lambda i:None):
Tkinter.Frame.__init__(self, master)
self.dt=datetime.datetime.now() if date is None else datetime.datetime.strptime(date, dateformat)
self.showmonth()
self.command=command
self.dateformat=dateformat
def showmonth(self): # Show the calendar for a month
sc = calendar.month(self.dt.year, self.dt.month).split('\n')
for t,c in [('<<',0),('<',1),('>',5),('>>',6)]: # The buttons to the left to the right year and month
Tkinter.Button(self,text=t,relief='flat',command=lambda i=t:self.callback(i)).grid(row=0,column=c)
Tkinter.Label(self,text=sc[0]).grid(row=0,column=2,columnspan=3) # year and month
for line,lineT in [(i,sc[i+1]) for i in range(1,len(sc)-1)]: # The calendar
for col,colT in [(i,lineT[i*3:(i+1)*3-1]) for i in range(7)]: # For each element
obj=Tkinter.Button if colT.strip().isdigit() else Tkinter.Label # If this number is a button, or Label
args={'command':lambda i=colT:self.callback(i)} if obj==Tkinter.Button else {} # If this button, then fasten it to the command
bg='green' if colT.strip()==str(self.dt.day) else 'SystemButtonFace' # If the date coincides with the day of date - make him a green background
fg='red' if col>=5 else 'SystemButtonText' # For the past two days, the color red
obj(self,text="%s"% colT,relief='flat',bg=bg,fg=fg,**args).grid(row=line, column=col, ipadx=2, sticky='nwse') # Draw Button or Label
def callback(self,but): # Event on the button
if but.strip().isdigit(): self.dt=self.dt.replace(day=int(but)) # If you clicked on a date - the date change
elif but in ['<','>','<<','>>']:
day=self.dt.day
if but in['<','>']: self.dt=self.dt+datetime.timedelta(days=30 if but=='>' else -30) # Move a month in advance / rewind
if but in['<<','>>']: self.dt=self.dt+datetime.timedelta(days=365 if but=='>>' else -365) # Year forward / backward
try: self.dt=self.dt.replace(day=day) # We are trying to put the date on which stood
except: pass # It is not always possible
self.showmonth() # Then always show calendar again
if but.strip().isdigit(): self.command(self.dt.strftime(self.dateformat)) # If it was a date, then call the command
if __name__ == '__main__':
def com(f): print f
root = Tkinter.Tk()
root.title("Monthly Calendar")
c=calendarTk(root,date="21/11/2006",dateformat="%d/%m/%Y",command=com)
c.pack()
root.mainloop()