如何使用 tkinter 检查小部件是否是另一个小部件的后代

我正在创建一个弹出消息,如果用户在弹出窗口的框架之外单击,该消息就会消失。要检查用户是否在框架外单击,代码如下所示:


import tkinter as tk


def build_popup(self, root):

  popup_frame = tk.Frame(root)

  popup_frame.grid(row=0, column=0)


  # binding to check if click is outside the frame

  self.popup_frame_funcid = root.bind_all('<Button-1>', self.delete_popup)


  my_canvas = tk.Canvas(popup_frame, width=200, height=200)

  my_canvas.grid(row=0, column=0)


def delete_popup(self, root, event):

  # if location clicked is not that of a child of the frame destroy popup

  if root.winfo_containing(event.x_root, event.y_root) not in popup_frame.winfo_children():

    popup_frame.destroy()

    root.unbind('<Button-1>', self.popupframe_funcid)

然而,当一个小部件被添加到时,我遇到了一个问题my_canvas,例如一个条目,并且它的父级被声明为my_canvas. 当我单击添加的小部件时,popup_frame.winfo_children()(相当合理地)不会将添加的小部件识别为框架的子级popup_frame并破坏框架。


tkinter 中是否有一个函数可以用来检查一个小部件是否是另一个小部件的后代,或者我是否被迫手动跟踪我添加到的每个小部件popup_frame?


如果有更简单/替代的方法来实现相同的结果,我也会很高兴听到它。


明月笑刀无情
浏览 113回答 3
3回答

繁星coding

您可以使用winfo_parent来获取小部件的父级。然后,您可以在父级和父级的父级等上调用它,以获取小部件的祖先。winfo_parent返回一个字符串而不是父对象,但 tkinter 有办法将名称转换为小部件。例如,要获取名为 的小部件的父小部件w,您可以这样做:parent&nbsp;=&nbsp;w.nametowidget(w.winfo_parent())有了它,您可以沿着小部件的层次结构向上工作,当您到达根窗口时停止。

宝慕林4294392

我搞砸了一会儿,找到了已经提到的替代解决方案。str(my_widget)返回字符串路径my_widget因此,例如,您可以通过简单地检查 ' 的路径是否以 ' 的路径开头来检查是否my_canvas是 的后代。popup_framemy_canvaspopup_frame在 python 中,这很简单:str(my_canvas).startswith(str(popup_frame))

富国沪深

我使用winfo_children()andwinfo_parent()来标识子级和父级小部件/容器。请注意,单.指根窗口。import tkinter as tkclass App(tk.Tk):&nbsp; &nbsp; def __init__(self):&nbsp; &nbsp; &nbsp; &nbsp; super().__init__()&nbsp; &nbsp; &nbsp; &nbsp; frame1 = tk.Frame(self)&nbsp; &nbsp; &nbsp; &nbsp; btn1 = tk.Button(self)&nbsp; &nbsp; &nbsp; &nbsp; btn2 = tk.Button(self)&nbsp; &nbsp; &nbsp; &nbsp; btn3 = tk.Button(frame1)&nbsp; &nbsp; &nbsp; &nbsp; print('Root children widget are: {}'.format(self.winfo_children()))&nbsp; &nbsp; &nbsp; &nbsp; print('frame1 children widget is: {}'.format(frame1.winfo_children()))&nbsp; &nbsp; &nbsp; &nbsp; print('Button 1 parent is: {}'.format(btn1.winfo_parent()))&nbsp; &nbsp; &nbsp; &nbsp; print('Button 2 parent is: {}'.format(btn2.winfo_parent()))&nbsp; &nbsp; &nbsp; &nbsp; print('Button 3 parent is: {}'.format(btn3.winfo_parent()))if __name__ == '__main__':&nbsp; &nbsp; App().mainloop()
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python