【问题标题】:Destroy a tk.Frame from a class that inherits from tk.Frame从继承自 tk.Frame 的类中销毁 tk.Frame
【发布时间】:2017-11-07 20:35:51
【问题描述】:

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

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 时出现了某种错误。

有人能发现问题吗?

在布赖恩的评论后编辑

我把问题的简化版本放在这里:

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()

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

如前所述,要么框架的破坏不起作用,要么 GUI 的检索没有正确通过。 GUI 完全清空的窗口(这让我认为“破坏”功能正常工作)。控制台没有报错。

【问题讨论】:

标签: python tkinter refresh destroy


【解决方案1】:

我已经解决了这个问题。

问题主要在于我按如下方式创建小部件:

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

这意味着框架的破坏和新的检索正在工作。但由于这些小部件不在框架中,因此视觉上什么也没有发生。

我最终通过以下方式解决了这个问题:

import calendar
import tkinter as tk
import datetime

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():
    def __init__(self, master, *args, **kwargs):
        self.frame = tk.Frame(master)
        self.frame.pack()
        self.createwidgets()

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

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

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

    def NextMonth(self):
        self.month = self.month+1
        self.frame.destroy()
        GUI.__init__(self, root)


root =  tk.Tk()
app = Application(root)
root.mainloop()

如您所见,我还需要传递以前不存在的“master”或 root(我相信它默认为“None”)。我还不清楚这个失踪的“主人”在最初的问题中有多少部分。

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

我所做的所有事情都是让 GUI 类不继承自 tk.Frame。我对此进行了一些研究,除了美观和代码可读性(这也很重要)之外,没有找到一个或其他选项的主要论据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-15
    • 2020-04-17
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多