从继承自tk.Frame的类中销毁tk.Frame

时间:2017-06-06 17:47:21

标签: python tkinter refresh destroy

我正在尝试开发基于日历的程序。在我的日历中,每月的每一天都是一个按钮,我可以在其中存储信息。这是我的代码:

import numpy as np
import calendar
import tkinter as tk
import datetime

kalender =  tk.Tk()
kalender.title("Overtime Tracker")
kalender.resizable(0, 0)

year = int(str(datetime.datetime.now())[0:4])
month = int(str(datetime.datetime.now())[6:7])

monthmatrix = calendar.monthcalendar(year,month)

class GUI(tk.Frame):
    def __init__(self, kalender, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
        self.createwidgets()

    def createwidgets(self):
        <all the widgets I need for my GUI>

class Application (GUI):
    def __init__(self, *args, **kwargs):
        self.year = year    
        self.month = month
        self.monthmatrix = monthmatrix 
        GUI.__init__(self, *args, **kwargs)

        self.previousmonth = tk.Button(self, font=("Helvetica", 15), text= "<", command=lambda: self.PrevMonth())
        self.previousmonth.grid(row=0, column=0, sticky="NWNESWSE")
        self.nextmonth = tk.Button(self, font=("Helvetica", 15), text= ">", command=lambda: self.NextMonth())
        self.nextmonth.grid(row=0, column=7, sticky="NWNESWSE")

    def PrevMonth(self):
        self.month = self.month-1
        self.monthmatrix = calendar.monthcalendar(self.year,self.month)
        GUI.destroy(self)
        GUI.__init__(self, kalender)


    def NextMonth(self):
        self.year = year
        self.month = self.month+1
        self.monthmatrix = calendar.monthcalendar(self.year,self.month)
        GUI.destroy(self)
        GUI.__init__(self, kalender)

app = Application(kalender).grid()     
kalender.mainloop()

应用程序本身是另一个继承自GUI的类,它具有GUI按钮所连接的所有其他功能,等等。

事情是,两个按钮“self.previousmonth”和“self.nextmonth”位于应用程序类中而不是GUI中,用于浏览月份。因此,我的想法是将月份值+1或-1(取决于按钮),移除tk.Frame,然后使用新月份再次打开GUI。

在内部,一切正常,数组和程序正常工作的所有内容都适当切换到相应的月前/后,但相应月份的日历不会出现。相反,框架与所有小部件一起被移除(我猜它会发生什么。可以看到的是程序完全清空的窗口),但下个月没有出现。窗口保持空白。除此之外,控制台不会产生任何错误。

首先,我不确定我是否正确地破坏了tk.Frame,尽管这在视觉上似乎正在发生。为了确保我尝试构建GUI,如:

kalender = tk.Tk()

class GUI():
    def __init__(self, kalender):
        self.kalender = kalender
        self.frame = tk.Frame(self.kalender)

但是,显然,类Application没有它需要的tk属性。

另一方面,可能是在正确销毁tk.Frame后,我在某种程度上再次调用GUI时出错了。

有人能发现问题吗?

在Brian的评论之后编辑

我在这里放了一个问题的简化版本:

import calendar
import tkinter as tk
import datetime

kalender =  tk.Tk()

year = int(str(datetime.datetime.now())[0:4]) # takes the year from datetime
month = int(str(datetime.datetime.now())[6:7]) # takes the month from datetime

class GUI(tk.Frame):
    def __init__(self, kalender, *args, **kwargs):
        self.kalender = kalender
        tk.Frame.__init__(self, *args, **kwargs)
        self.createwidgets()

    def createwidgets(self):
        self.kalendertitle = tk.Label(self, text=str(calendar.month_name[self.month])+" "+str(year)).grid(row=0, column=1)

class Application (GUI):
    def __init__(self, *args, **kwargs):
        self.year = year    
        self.month = month
        GUI.__init__(self, *args, **kwargs)

        self.nextmonth = tk.Button(self, text= ">", command=lambda: self.NextMonth())
        self.nextmonth.grid(row=0, column=7)

    def NextMonth(self):
        self.year = year
        self.month = self.month+1
        GUI.destroy(self)
        GUI.__init__(self, kalender)

app = Application(kalender).grid()     
kalender.mainloop()

从datetime读取年份和月份。类GUI初始化并调用函数“createwidgets”,在这种情况下只显示当前月份和年份。该应用程序作为另一个继承自GUI的类而来。它还包含一个按钮,可以切换到下个月。这是通过函数“NextMonth”完成的。该功能的想法是增加月份索引,销毁GUI并再次检索它,月份索引大一个单位,即显示应显示“2017年7月”。

如前所述,框架的破坏不起作用或GUI的检索未正确传递。 GUI完全清空的窗口(这让我觉得“破坏”功能正常工作)。控制台不会出现任何错误。

1 个答案:

答案 0 :(得分:0)

我已经解决了这个问题。

问题主要是我正在创建小部件如下:

undefined

这意味着框架的破坏及其新的检索工作正常。但由于小部件不在框架中,因此没有任何东西在视觉上发生。

我最终通过做类似的事情解决了这个问题:

self.randomWidget = tk.Widget(self, ....)

如你所见,我还需要传递“master”或root,这是以前不存在的(我相信它默认为“None”)。我还不清楚这个缺少“大师”的原始问题有多少部分。

在“self.frame”中插入的小部件使整个过程正常工作。之前代码的另一个坏主意是将浏览按钮放在应用程序中而不是GUI中。因为,当然,在第一帧刷新后,按钮消失了。

通过使GUI类不从tk.Frame继承来做的全部事情。我对此进行了一些研究,并没有找到除了美学和代码可读性之外的一个或其他选项的主要论据(这也很重要)。