(我为这个幼稚的问题表示歉意)
我有一个弹出的窗口,允许用户选择两个月作为数据收集的起点和终点。
单击“确定”按钮所发生的事件将返回所选范围之间月份的列表和字典,并通知用户其所选范围。但是,我也希望在单击“确定”后关闭此窗口。这些事件在callback
函数下。我无法使root.destroy
可达。
涉及的所有代码都在这里。我的功能callback
接近底部:
from tkinter import *
startDate = 'Dec 16'
now = datetime.now()
endDate = now.strftime('%b %y')
start = datetime.strptime(startDate, '%b %y').date()
end = datetime.strptime(endDate, '%b %y').date()
cur_date = start
range_months = []
while cur_date < end:
cur_date += relativedelta(months=1)
range_months.append(cur_date)
range_months = [month.strftime('%b %y') for month in range_months]
dict_months = dict((month, pd.to_datetime(month, format='%b %y')) for month in range_months)
root = Tk()
#root.withdraw()
root.title("Select your Month Range")
# Setting up Grid
mainframe = Frame(root)
mainframe.pack(pady=50, padx=50)
Label(mainframe, text="Select Start Month").grid(row=1, column=1)
Label(mainframe, text="Select End Month").grid(row=1, column=6)
# Creating two Tkinter variables to obtain user input from the drop down menus
tkvar_start = StringVar(root)
tkvar_end = StringVar(root)
tkvar_start.set('Jan 17') # Setting a default option
tkvar_end.set(endDate)
start_popupMenu = OptionMenu(mainframe, tkvar_start, *dict_months)
end_popupMenu = OptionMenu(mainframe, tkvar_end, *dict_months)
start_popupMenu.grid(row=2, column=1)
end_popupMenu.grid(row=2, column=6)
def callback_range():
print('The range is from %s to %s' % (tkvar_start.get(), tkvar_end.get()))
list_of_month_keys = list(dict_months.keys())
import itertools
range_dict_months = dict(itertools.islice(dict_months.items(), list_of_month_keys.index(tkvar_start.get()),
list_of_month_keys.index(tkvar_end.get()) + 1))
return list_of_month_keys, range_dict_months
button = Button(mainframe, text = "OK", command = callback_range)
button.grid(row=3, column=23)
root.mainloop()
list_of_month_keys, range_dict_months = callback_range()
如何在函数root.destroy()
中使callback
可达,同时仍然返回list_of_month_keys
和range_dict_months
,以便在单击“好吧?
答案 0 :(得分:0)
我试图进入您的程序并提出解决方案。
from tkinter import *
import tkinter.messagebox as mb
from datetime import datetime
import itertools
from dateutil.relativedelta import relativedelta
import pandas as pd
class MonthRangeWindow:
def __init__(self):
startDate='Dec 16'
endDate=datetime.now().strftime('%b %y')
cur_date=start=datetime.strptime(startDate,'%b %y').date()
end=datetime.strptime(endDate,'%b %y').date()
range_months=[]
self.list_of_month_keys,self.range_dict_months=None,None
while cur_date<end:
cur_date+=relativedelta(months=1)
range_months.append(cur_date)
range_months=[month.strftime('%b %y') for month in range_months]
self.dict_months=dict((month,pd.to_datetime(month,format='%b %y')) for month in range_months)
self.root=Tk()
#self.root.withdraw()
self.root.title("Select your Month Range")
mainframe=Frame(self.root)
mainframe.pack(pady=50,padx=50)
Label(mainframe,text="Select Start Month").grid(row=1,column=1)
Label(mainframe,text="Select End Month").grid(row=1,column=6)
self.tkvar_start=StringVar(root,'Jan 17')
self.tkvar_end=StringVar(root,endDate)
start_popupMenu=OptionMenu(mainframe,tkvar_start,*self.dict_months)
end_popupMenu=OptionMenu(mainframe,tkvar_end,*self.dict_months)
start_popupMenu.grid(row=2,column=1)
end_popupMenu.grid(row=2,column=6)
button=Button(mainframe,text="Ok",command=self.callback_range)
button.grid(row=3,column=23)
def callback_range(self):
mb.showinfo(title='Info',message='The range is from %s to %s.' % (self.tkvar_start.get(),self.tkvar_end.get()),master=self.root)
self.list_of_month_keys=list(self.dict_months.keys())
self.range_dict_months=dict(itertools.islice(self.dict_months.items(),self.list_of_month_keys.index(self.tkvar_start.get()),self.list_of_month_keys.index(self.tkvar_end.get()) + 1))
def mainloop(self,n=0):
self.root.mainloop(n)
return self.list_of_month_keys,self.range_dict_months
if __name__=='__main__':
mrw=MonthRangeWindow()
list_of_month_keys,range_dict_months=mrw.mainloop()
print(list_of_month_keys,range_dict_months)
由于我没有该pd.to_datetime(...)
的熊猫模块,而且我懒得下载它,因此无法对其进行测试。但是我认为您应该可以在需要时对其进行调试。
我还允许自己从tkinters消息框模块而不是print
插入信息窗口。如果您不希望这样做,请再次将其替换为打印。
答案 1 :(得分:0)
您可能希望将多个命令绑定到按钮。
def combined_functions(*funcs):
def combined_func(*args, **kwargs):
for f in funcs:
f(*args, **kwargs)
return combined_func
//close the mainframe
def close_window():
mainframe.quit()
button = Button(mainframe, text = "OK", command = combined_functions(callback_range, close_window))
此外,在方法中间导入模块可能不是一个好主意。如果将range_dict_months
分成几行,代码看起来会更好。