【问题标题】:Check if widget exists in tkinter before deleting it在删除之前检查小部件是否存在于 tkinter
【发布时间】:2015-03-05 14:49:31
【问题描述】:

我正在使用下拉菜单来创建多个小部件。我想在删除它之前检查小部件是否存在(来自下拉菜单上的先前选择)。我正在使用以下代码:

self.ndim_options, self.ndim_options_var = self.DropdownMenuCommand(("1","2","3"),'-',"Number of indirect dimensions","-")

def DropdownMenuCommand(self,options,status,name,row):

    if row == "-":
      row = self.row

    optionLabel = tk.Label(self.frame, bg='turquoise')
    optionLabel["text"] = name
    optionLabel.grid(row=row, column=0, sticky='w')
    var = tk.StringVar(self)
    var.set(status)
    w = tk.OptionMenu(self.frame, var, *options, command = self.setdimensionproperties)
    w.config(bg = 'paleturquoise')
    w["menu"].config(bg = 'paleturquoise')
    w.grid(row=row, column=1)
    self.row += 1
    return w, var

def setdimensionproperties(self,val):
    row = self.RowEnd

    if val == "3":  #Set parameters for a 4D (3 indirect dimensions)

      #Remove any existing weighting functions
      if self.weightingFuncNameDim2.winfo_exists():
        self.weightingFuncNameDim2.grid_remove()

      self.weightingFuncNameDim2, self.weightingFuncNameDim2_var = self.DropdownMenu(("sinebell","gaussian", "sinebell2"),'-', "Weighting function dimension 2",row)

但是,如果尚未创建小部件,我会收到属性错误:

Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1413, in __call__
    return self.func(*args)
  File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 3141, in __call__
    self.__callback(self.__value, *args)
  File "test.py", line 224, in setdimensionproperties
    if self.weightingFuncNameDim2.winfo_exists():
AttributeError: Window instance has no attribute 'weightingFuncNameDim2'

理想情况下,如果小部件存在,我希望 if 语句返回 1,如果不存在,则返回 0,这是我认为 .winfo_exists() 所做的。我怎样才能绕过这个错误?另外,如何确保.grid_remove 删除了小部件和标签?

【问题讨论】:

    标签: python tkinter


    【解决方案1】:

    我看到了三种可能的解决方案。按优先顺序:

    1. self.weightingFuncNameDim2 = None 添加到您的班级的__init__ 方法中,并将您的if 条件更改为if self.weightingFuncNameDim2 is not None and self.weightingFuncNameDim2.winfo_exists():

    2. 将您的条件更改为if hasattr(self, "weightingFuncNameDim2") and self.weightingFuncNameDim2.winfo_exists():

    3. 将您的 if 块放入一个 try-except 块中,该块会捕获并忽略 AttributeErrors。

    【讨论】:

    • 我对“如何确保 .grid_remove 删除小部件和标签?”没有任何想法,但我想你宁愿有一半的答案也不愿没有答案. (将来,对于足够不同的问题,最好单独发帖,这样回答者就不用担心这个困境了)
    【解决方案2】:

    ...但是,如果尚未创建小部件,则会出现属性错误:

    最好的解决方案是确保您的类始终具有该属性,即使该小部件不存在。将其设置为None,然后在创建小部件时将其重置。那么你的条件变成:

      if self.weightingFuncNameDim2 is not None:
        self.weightingFuncNameDim2.grid_remove()
    

    如何确保 .grid_remove 删除了小部件和 标签?

    grid_remove 将始终只从视图中删除一个小部件。但是,如果该小部件包含其他小部件,则这些其他小部件也将从视图中删除。

    【讨论】:

    • 请注意,“if self.weightingFuncNameDim2 is not None:”与“if self.weightingFuncNameDim2”相同:
    • @CurlyJoe:这并不完全正确。在实践中它通常已经足够好了,但在我看来,如果你想明确地检查 None 的值,你应该明确地检查 None 的值,而不是采取“真实”的捷径。这可能是一个细微的差别,但您应该始终努力使您的代码尽可能清晰。
    • 感谢您的回答。关于问题的第二部分 .grid_remove() 似乎将标签留在原处。所以在我给出的例子中,下拉菜单被移除了,但是文本“加权函数名称维度 2”仍然存在。
    猜你喜欢
    • 2016-02-10
    • 2010-09-27
    • 2016-09-25
    • 1970-01-01
    • 1970-01-01
    • 2021-07-22
    • 2013-02-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多