如何真正破坏一个框架,使它消失

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何真正破坏一个框架,使它消失相关的知识,希望对你有一定的参考价值。

我有一个小程序在数据库中进行搜索并显示结果。我的计划是将结果显示在放置搜索参数的同一窗口中的适当大小的框架中。

由于我想替换每个新查询的结果,因此我有一个results_owner框架,该框架是永久性的,并且具有一个子result_frame,该框架根据需要进行填充和销毁。至少,这是计划。它进展不顺利。

我可以创建框架并将内容放入其中。但是当我想删除或替换它时,我留下了前一个化身的东西。有些东西被修改了,有些东西似乎是永久性的,它让我感到困惑。

你可能需要让窗户更高才能看到完整的效果。基本缺陷是,当您单击“线+”按钮时,显示的行是永久性的,因此当您单击“新框架”按钮时,线条应该消失但不会消失。

这是代码:

#!/usr/bin/env python3
"""Find a matching record in the database

Last Modified: Fri Dec 15 18:20:32 PST 2017
"""

import tkinter as tk    # https://docs.python.org/3.5/library/tkinter.html

class Asker(tk.Frame):
    def __init__(self, root=None):
        super().__init__(root)
        self.root = root
        root.title("Asker")
        self.pack()
        self._create_widgets()

    results_owner = None
    results_frame = None
    iteration = 0

    def _create_widgets(self):
        noterow2 = tk.Frame(root)
        msgtx = "This represents the fixed area of the window"
        tx2 = tk.Label(noterow2, width=len(msgtx), text=msgtx, anchor='w')
        noterow2.pack(side=tk.TOP, fill=tk.X, padx=2, pady=2)
        tx2.pack(side=tk.LEFT, padx=5, pady=5)

        buttonrow = tk.Frame(root)
        buttonrow.pack(side=tk.TOP, fill=tk.X, padx=2, pady=2)

        b2 = tk.Button(buttonrow, text='Quit', command=root.quit)
        b2.pack(side=tk.LEFT, padx=5, pady=5)

        test1 = tk.Button(buttonrow, text='Line+', command=(lambda arg=self.results_frame: self.addline(arg)))
        test1.pack(side=tk.LEFT, padx=5, pady=5)

        test2 = tk.Button(buttonrow, text='New Frame', command=self.new_results)
        test2.pack(side=tk.LEFT, padx=5, pady=5)

        self.results_owner = tk.Frame(root)
        self.results_owner.pack(side=tk.TOP, fill=tk.X)

        self.new_results()

    def new_results(self):
        if self.results_frame is not None:
            self.results_frame.destroy()
        self.results_frame = tk.Frame(self.results_owner)
        sampletxt = "New frame " + str(self.iteration)
        sample = tk.Label(self.results_frame, text=sampletxt, width=len(sampletxt), anchor='w')
        sample.pack(side=tk.LEFT, padx=5, pady=5)
        self.results_frame.pack(side=tk.TOP,fill=tk.X,padx=0, pady=self.iteration)

        self.root.update_idletasks()
        self.iteration += 1

    def addline(self, results):
        print("addline")
        msg = "New Line"
        mytx = tk.Label(results, text=msg, width=len(msg), anchor='w')
        mytx.pack(side=tk.TOP, fill=tk.X, padx=2, pady=2)

if __name__ == '__main__':

    root = tk.Tk()
    anti = Asker(root=root)
    anti.mainloop()

这是使用注释中的一些建议修改的代码(但它仍然无法按预期工作):

#!/usr/bin/env python3
"""Find a matching record in the database

Last Modified: Fri Dec 15 20:31:17 PST 2017
"""

import tkinter as tk    # https://docs.python.org/3.5/library/tkinter.html

class Asker(tk.Frame):
    def __init__(self, root=None):
        super().__init__(root)
        self.root = root
        root.title("Asker")
        self.pack()
        self.results_owner = None
        self.results_frame = None
        self.iteration = 0
        self._create_widgets()

    def _create_widgets(self):
        noterow2 = tk.Frame(root)
        msgtx = "This represents the fixed area of the window"
        tx2 = tk.Label(noterow2, width=len(msgtx), text=msgtx, anchor='w')
        noterow2.pack(side=tk.TOP, fill=tk.X, padx=2, pady=2)
        tx2.pack(side=tk.LEFT, padx=5, pady=5)

        buttonrow = tk.Frame(root)
        buttonrow.pack(side=tk.TOP, fill=tk.X, padx=2, pady=2)

        b2 = tk.Button(buttonrow, text='Quit', command=root.quit)
        b2.pack(side=tk.LEFT, padx=5, pady=5)

        test1 = tk.Button(buttonrow, text='Line+', command=self.addline(self.results_frame))
        test1.pack(side=tk.LEFT, padx=5, pady=5)

        test2 = tk.Button(buttonrow, text='New Frame', command=self.new_results)
        test2.pack(side=tk.LEFT, padx=5, pady=5)

        self.results_owner = tk.Frame(root)
        self.results_owner.pack(side=tk.TOP, fill=tk.X)

        self.new_results()

    def new_results(self):
        if self.results_frame is not None:
            self.results_frame.pack_forget()
            self.results_frame.destroy()
        self.results_frame = tk.Frame(self.results_owner)
        sampletxt = "New frame " + str(self.iteration)
        sample = tk.Label(self.results_frame, text=sampletxt, width=len(sampletxt), anchor='w')
        sample.pack(side=tk.LEFT, padx=5, pady=5)
        self.results_frame.pack(side=tk.TOP,fill=tk.X,padx=0, pady=self.iteration)

        self.root.update_idletasks()
        self.iteration += 1

    def addline(self, results):
        print("addline")
        msg = "New Line" + str(self.iteration)
        mytx = tk.Label(results, text=msg, width=len(msg), anchor='w')
        mytx.pack(side=tk.TOP, fill=tk.X, padx=2, pady=2)

if __name__ == '__main__':

    root = tk.Tk()
    anti = Asker(root=root)
    anti.mainloop()
答案

在你的情况下,你必须直接在lambda中使用self.results_frame

command=lambda:self.addline(self.results_frame) 

始终访问变量self.results_frame中的当前值

arg=self.results_frame中使用lambda

lambda arg=self.results_frame: self.addline(arg)

您只需将值从self.results_frame复制到arg一次(开始时),之后函数始终使用相同的值。

另一答案

事实证明我必须调用addline一个lambda;事实上,该功能只被调用一次。我还调整了包装和边框,以明确事情是如何分组的。我现在可以将它用作我的应用程序的模型。

#!/usr/bin/env python3
"""Last Modified: Sat Dec 16 07:28:31 PST 2017
"""

import tkinter as tk    # https://docs.python.org/3.5/library/tkinter.html

class Asker(tk.Frame):
    def __init__(self, root=None):
        super().__init__(root)
        self.root = root
        root.title("Asker")
        self.pack()
        self.results_owner = None
        self.results_frame = None
        self.iteration = 0
        self._create_widgets()

    def _create_widgets(self):
        noterow2 = tk.Frame(root)
        msgtx = "This represents the fixed area of the window"
        tx2 = tk.Label(noterow2, width=len(msgtx), text=msgtx, anchor='w')
        noterow2.pack(side=tk.TOP, fill=tk.X, padx=2, pady=2)
        tx2.pack(side=tk.LEFT, padx=5, pady=5)

        buttonrow = tk.Frame(root)
        buttonrow.pack(side=tk.TOP, fill=tk.X, padx=2, pady=2)

        b2 = tk.Button(buttonrow, text='Quit', command=root.quit)
        b2.pack(side=tk.LEFT, padx=5, pady=5)

        test1 = tk.Button(buttonrow, text='Line+', command=(lambda :self.addline(self.results_frame)))
        test1.pack(side=tk.LEFT, padx=5, pady=5)

        test2 = tk.Button(buttonrow, text='New Frame', command=self.new_results)
        test2.pack(side=tk.LEFT, padx=5, pady=5)

        self.results_owner = tk.Frame(root, borderwidth=3, relief=tk.RAISED)
        self.results_owner.pack(side=tk.TOP, fill=tk.X, padx=2, pady=2)

        self.new_results()

    def new_results(self):
        if self.results_frame is not None:
            self.results_frame.destroy()
        self.results_frame = tk.Frame(self.results_owner, borderwidth=1, relief=tk.GROOVE)
        sampletxt = "New frame " + str(self.iteration)
        sample = tk.Label(self.results_frame, text=sampletxt, width=len(sampletxt), anchor='w')
        sample.pack(side=tk.TOP, fill=tk.X, padx=2, pady=2)
        self.results_frame.pack(side=tk.TOP,fill=tk.X,padx=2, pady=2)

        self.root.update_idletasks()
        self.iteration += 1

    def addline(self, results):
        msg = "New Line" + str(self.iteration)
        mytx = tk.Label(results, text=msg, width=len(msg), anchor='w')
        mytx.pack(side=tk.TOP, fill=tk.X, padx=2, pady=2)
        self.root.update_idletasks()
        self.iteration += 1

if __name__ == '__main__':

    root = tk.Tk()
    anti = Asker(root=root)
    anti.mainloop()

以上是关于如何真正破坏一个框架,使它消失的主要内容,如果未能解决你的问题,请参考以下文章

Fmt 0.9.0 破坏了我的代码,我怎样才能使它兼容? Format.pp_set_formatter_stag_functions

当活动被破坏但我必须继续执行片段中的代码时该怎么办?

如何使我的片段适合我的工具栏和底部导航栏,并使它仍可滚动?

如何停止框架破坏者?

在方向更改时保留列表片段中的列表

关于侧边导航菜单和片段的一般设计问题