【问题标题】:Python Tkinter delete labels before they have been addedPython Tkinter 在添加标签之前删除标签
【发布时间】:2016-04-15 13:48:57
【问题描述】:

我用 Python 创建了一个简单的 DNS 解析器应用程序

#!/usr/bin/env python
import dns.resolver
import socket
from Tkinter import *
import Tkinter
import tkMessageBox

# GUI
root = Tkinter.Tk()
root.geometry("1200x300")
root.title("DNS RESOLVER)



# User input name server, from web address
def InputNameServer():
    NameServerEntryText = BoxTextNameServer.get()
    answers = dns.resolver.query(NameServerEntryText,'NS')
    var2 = 2
    for server in answers:
        DisplayTextNameServer = Label(root,text=server)
        DisplayTextNameServer.grid(row = var2, column = 5)
        var2 = var2 + 1
    return

BoxTextNameServer = StringVar()
InputIPAddrButton = Button(root, text = "Get the name server",command = InputNameServer)
InputIPAddrButton.grid(row = 0, column = 5)
InputIPAddrEntry = Entry(root, textvariable=BoxTextNameServer)
InputIPAddrEntry.grid(row = 1, column = 5)


root.mainloop()

基本前提是用户在文本框中输入网址,然后解析器应通过导入的 DNS Resolver 获取名称服务器,并应添加各个名称服务器的标签。问题是当用户输入新网址并按下提交按钮时,我无法删除它们。我了解 .grid_forget() 和 .destroy() 方法,但无法声明标签变量,然后在函数运行之前删除它们,并在之前的顶部再次打印标签。 抱歉,如果我有复杂的事情,简而言之,输入地址,按提交,打印标签,输入新地址,按提交,删除以前的标签,打印新标签。

【问题讨论】:

  • 我们可以得到一个工作的 MWE 吗?还是只是描述?从我看到你创建带有文本“THS”的新标签然后立即销毁那些(应该将它们从框架中删除,我们是否在框架中?),然后在它们下方和旁边添加一个新标签,其中包含永远不会得到的新文本毁了?为什么是空返回?我的建议是有一个专用的 Frame 来保存它,将它作为继承的 Frame 对象,即 DNSNameFrame,并让它有一个带有 for widget in frame.winfo_children(): widget.destroy() 的销毁方法。在打印新标签之前调用该方法。
  • 我会相应地编辑代码

标签: python tkinter


【解决方案1】:

当我缺少个人 dns 解析器模块时,仍然很难有一个最小的工作示例。下次只需放入一个替代函数,如果它主要与您所问的问题无关,则该函数会返回。

这就是我所说的:

from Tkinter import *
from ttk import *
import tkMessageBox

def dummy_DNS_Resolver():
    return "IT'S HARD TO HELP PEOPLE WHEN THEY GIVE "+\
            "MWE'S THAT NEED THEIR SPECIAL MODULES"

class DNSNameFrame(Frame):
    def __init__(self, parent):
        Frame.__init__(self, relief=RAISED, borderwidth=1)
        self.pack(side=RIGHT, fill=BOTH, expand=1)

        self.parent = parent

    def update(self):
        self.clearTable()

        servername = self.parent.ServerInputFrame.getServerName()
        for i in range(0, 10):
            Label(self, text=servername, relief=RIDGE).grid(row=i, column=0)
            Label(self, text=dummy_DNS_Resolver()).grid(row=i,column=1)

    def clearTable(self):
        for widget in self.winfo_children(): 
            widget.destroy()

class ServerInputFrame(Frame):
    def __init__(self, parent):
        Frame.__init__(self, relief=RAISED, borderwidth=1)
        self.pack(side=TOP, fill=Y, expand=1)

        Label(self, text="Enter Server:").pack(side=TOP)

        self.serverName = StringVar()
        self.entry = Entry(self, width=70, textvariable=self.serverName)
        self.entry.pack(side=TOP)

        Button(self, text="Run", width=30, command=parent.update).pack(side=BOTTOM)

    def getServerName(self):
        return self.serverName.get()


class MainWindow(Tk):
    def __init__(self, geom="1200x300", title="DNS RESOLVER"):
        Tk.__init__(self)
        self.title(title)
        self.geometry(geom)
        self.initGui()

    def initGui(self):
        self.DNSNameFrame = DNSNameFrame(self)
        self.ServerInputFrame = ServerInputFrame(self)

    def update(self):
        self.DNSNameFrame.update()

app = MainWindow()
app.mainloop()

它比人们用来执行 Tkinter 的平均整体方式要长一些,但我发现它更容易,而且只需额外增加 1 个 __init__ 函数。此外,每个 Frame 子类都可以放在不同的文件中,然后导入到 MainWindow 中,这样可以减少处理 Tk 时通常的混乱。

分离 GUI 的逻辑工作单元有助于您单独处理每个工作单元,这样更容易。

您最感兴趣的部分应该是 DNSNameFrame。在每次表更新之前,您清除表。您可以通过从您的 ServerInputFrame 中抓取 servername 而不是 self.parent(即 MainFrame)来填充您的表格。您将其发送到您的 dns 模块并检索一些结果。您遍历该结果并粘贴适当的服务器名称。当我这样做的时候,我把它做成了一个表格,但现在我看到你只有一个列表,它应该仍然很容易根据你的需要修改代码。

适用于 Ipython 2.7 Notebook,win7 x64。

【讨论】:

  • 我不知道还要添加什么,上面复制到 .py 文件中的代码可以完美运行,根据我的定义和最小的工作示例也是如此。不过还是谢谢
  • 我不想在这里挑起一场战斗或其他什么,所以不要太在意。但我是说MWE 应该尽可能短(真),但提供它工作所需的所有部分(假)和可验证(假)。在任何情况下,只要使用我给你的代码,改变for 循环范围并用函数调用替换你的模块函数调用,你就应该让它像你需要的那样工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-15
  • 2022-01-05
  • 1970-01-01
  • 2016-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多