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

时间:2017-12-16 02:41:31

标签: python-3.x tkinter widget

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

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

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

您可能需要让窗户更高才能看到完整的效果。基本缺陷是当你点击" Line +"按钮,显示的行是永久的,所以当你点击"新框架"按钮,线条应该消失,但不要。

此处的代码:

#!/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()

2 个答案:

答案 0 :(得分:1)

在你的情况下,你必须直接在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一次(在开始时),之后的函数始终使用相同的值。

答案 1 :(得分:1)

事实证明我必须调用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()