单击按钮,Tkinter窗口将不会关闭

时间:2018-07-23 17:33:18

标签: python button tkinter

(我为这个幼稚的问题表示歉意)

我有一个弹出的窗口,允许用户选择两个月作为数据收集的起点和终点。

enter image description here

单击“确定”按钮所发生的事件将返回所选范围之间月份的列表和字典,并通知用户其所选范围。但是,我也希望在单击“确定”后关闭此窗口。这些事件在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_keysrange_dict_months,以便在单击“好吧?

2 个答案:

答案 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分成几行,代码看起来会更好。