How to get the name of the Master Frame in Tkinter

2019-07-31 15:42发布

问题:


to cut a long story short: Is there a function to get the name of the Master Frame of a widget in Tkinter?

Let me tell you a little bit more:
There is a Button, named "BackButton"

self.BackButton = Button(self.SCPIFrame, text = "Back", command = self.CloseFrame)
self.BackButton.place(x = 320, y = 320, anchor = CENTER)

When I click on this Button, there is a function named "CloseFrame", which closes the current Frame (and doing some other stuff), in this case "SCPIFrame". But for this, I need the name of the Frame, in which the BackButton is present. Any ideas? Thanks for helping.

回答1:

To literally answer your question:

Is there a function to get the name of the Master Frame of a widget in Tkinter?

winfo_parent is exactly what you need. To be useful, you can use it combined with _nametowidget (since winfo_parent actually returns the name of the parent).

parent_name = widget.winfo_parent()
parent = widget._nametowidget(parent_name)


回答2:

I think the best way is to use the .master attribute, which is literally the master's instance :) For example (I am doing this in IPython):

import Tkinter as tk

# We organize a 3-level widget hierarchy:
# root
#   frame
#     button

root = tk.Tk()
frame = tk.Frame(root)    
frame.pack()
button = tk.Button(frame, text="Privet!", background='tan')
button.pack()

# Now, let's try to access all the ancestors 
# of the "grandson" button:

button.master   # Father of the button is the frame instance:
<Tkinter.Frame instance at 0x7f47e9c22128>

button.master.master   # Grandfather of the button, root, is the frame's father:
<Tkinter.Tk instance at 0x7f47e9c0def0>

button.master.master.master  # Empty result - the button has no great-grand-father ;) 


回答3:

If you use an object oriented style of programming the master frame is either the object itself, or an attribute of the object. For example:

class MyApplication(tk.Tk):
    ...
    def close_frame(self):
        # 'self' refers to the root window

Another simple way to solve this problem in a non-OO way is to either store the master in a global window (works fine for very small programs but not recommended for anything that will have to be maintained over time), or you can pass it in to the callback. For example:

self.BackButton = Button(..., command=lambda root=self.SCPIFrame: self.close_frame(root))
...
def CloseFrame(self, root):
    # 'root' refers to whatever window was passed in