Python 选择日期的快捷菜单

Python 选择日期的快捷菜单,python,drop-down-menu,tkinter,Python,Drop Down Menu,Tkinter,我正在建立一个下拉菜单,将用于选择开始日期。它有三个级联,分别命名为年、月、日。生成日期级联的内容,以便可用日期与所选年份和月份一致。 用户可能会在一次会话中多次更改日期 我的问题是:当用户第一次选择年/月时,会生成days命令。在任何新年/月份组合之后,下面的代码只是将命令添加到级联中。因此,日期级联包含两个月的日期 我一直试图让代码删除旧的菜单栏条目daymenu,并基于新数据重新创建它。 我想知道,如何对一个先前存在的、正在运行的菜单栏进行这样的更改?我搜索了tkinter文档,但找不出

我正在建立一个下拉菜单,将用于选择开始日期。它有三个级联,分别命名为年、月、日。生成日期级联的内容,以便可用日期与所选年份和月份一致。 用户可能会在一次会话中多次更改日期

我的问题是:当用户第一次选择年/月时,会生成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()
将日历导入为cal
将Tkinter作为tk导入
导入日期时间
导入操作系统路径
window=tk.tk()
#菜单变量:
年份=tk.IntVar()
month=tk.IntVar()
day=tk.IntVar()
小时=tk.IntVar()
分钟=tk.IntVar()
dur_hour=tk.IntVar()
dur_minute=tk.IntVar()
duration=tk.StringVar()
start=tk.StringVar()
#列表初始化
年份列表=[]
月的列表=[]
工时列表=[]
列出天数=[]
分钟列表=[]
def年设置器(值):
年份设置(值)
全天工作()
def all_for_day():#检查确定月份天数所需的数据是否存在
列出天数=[]
y=年。获取()
m=月。获取()
月的长度=加州蒙特兰奇(y,m)
月长2=月长[1]
如果m!=0和y!=0:
制作日清单(月长2)
make_day菜单()
def月设置器(值):
月。设置(值)
全天工作()
def日设置器(值):
设置日期(值)
def time_参数():
_date=datetime.datetime(1,1,1,0,0,0)
日期=日期。现在()
end_year=年的日期
制作年鉴(1995年,年终)
制作月刊
make_hourlist()
制作会议记录表()
def make_yearlist(年度、年终):

在添加新条目之前,您可以删除
daymmenu
中的所有条目

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)

遇到您的代码以选择日期。最近我不得不为类似的目的写一个简单的日历。我可以给你这个选择作为替代。我认为这个选项更方便选择日期

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()
导入日历、日期时间、Tkinter
类calendarTk(Tkinter.Frame):#类calendarTk
“”“日历,当前日期今天公开,或转移到日期”“”
def _uuinit _uuuu(self,master=None,date=None,dateformat=“%d/%m/%Y”,command=lambda i:None):
Tkinter.Frame.\uuuuu init\uuuuuuuuu(自我,主控)
self.dt=datetime.datetime.now()如果日期不是其他日期,则为datetime.datetime.strtime(日期,日期格式)
self.showmount()
self.command=命令
self.dateformat=dateformat
def showmonth(self):#显示一个月的日历
sc=日历月(self.dt.year,self.dt.month)。拆分('\n')
对于t,c in[('',6)]:#从左到右的按钮是年份和月份
Tkinter.Button(self,text=t,relief='flat',command=lambda i=t:self.callback(i)).grid(行=0,列=c)
Tkinter.Label(self,text=sc[0]).grid(行=0,列=2,列span=3)#年和月
对于line,lineT in[(i,sc[i+1])对于i in范围(1,len(sc)-1)]:#日历
对于col,colT in[(i,lineT[i*3:(i+1)*3-1]),对于范围(7)]中的i:#对于每个元素
obj=Tkinter.Button如果colT.strip().isdigit()否则Tkinter.Label#如果此数字是按钮,或标签
args={'command':lambda i=colT:self.callback(i)}如果obj==Tkinter.Button,则{}如果是此按钮,则将其固定到命令
bg='green'如果colT.strip()==str(self.dt.day)或者'SystemButtonFace'#如果日期与日期一致,则将其设置为绿色背景
fg='red'如果col>=5 else'systembuttonext'#在过去两天中,颜色为红色
obj(self,text=“%s”%colT,relief='flat',bg=bg,fg=fg,**args).网格(行=行,列=列,ipadx=2,粘性='nwse')#绘制按钮或标签
def回调(self,but):#按钮上的事件
if but.strip().isdigit():self.dt=self.dt.replace(day=int(but))#如果您单击了某个日期,则日期会更改
elif但在['',''中:
天=自我日
if but in[“”]:self.dt=self.dt+datetime.timedelta(如果but='>'else-30,则天数=30)#提前一个月移动/倒带
如果但是在['':self.dt=self.dt+datetime.timedelta(如果但是='>>'否则为365天)#向前/向后一年
try:self.dt=self.dt.replace(day=day)#我们正在努力确定日期
除了:通过#这不总是可能的
self.showmonth()#然后始终再次显示日历
如果是but.strip().isdigit():self.command(self.dt.strftime(self.dateformat))#如果是日期,则调用该命令
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
def com(f):打印f
root=Tkinter.Tk()
根标题(“月历”)
c=calendarTk(根,date=“21/11/2006”,dateformat=“%d/%m/%Y”,command=com)
c、 包()
root.mainloop()

当然,每个月至少有28天,所以你只需要添加或删除更多的内容。@ByanOakley:我不太知道如何实现你的建议。它不像使用
daymenu.delete(29,31)
那么简单,因为那样会重复第1天到第28天。将for循环限制为只添加所需的天数需要找出菜单中已经存在的天数。如何做到这一点?我也考虑过这个解决方案,但我仍在学习基础知识,所以我不知道如何实现它。无论如何,感谢你们两位的投入。@unutbu:一旦你们第一次填写菜单,它将始终至少有28个条目。只需要一点点数学就可以算出m