Should users of Tkinter be calling this?
--
Randall Hopper
aa...@yahoo.com
as long as nobody calls the Tkinter police, you're safe.
however, using the *toplevel* rather than the actual root
object is usually sufficient:
root = widget.winfo_toplevel()
to get from the toplevel to the real root, just add:
if root.master:
root = root.master # real root
</F>
FL> Randall Hopper wrote:
>> I have a widget and want to retrieve the root. I see the _root()
>> method, but by Python convention, isn't this method private?
>>
>> Should users of Tkinter be calling this?
FL> as long as nobody calls the Tkinter police, you're safe.
FL> however, using the *toplevel* rather than the actual root object
FL> is usually sufficient:
FL> root = widget.winfo_toplevel()
FL> to get from the toplevel to the real root, just add:
FL> if root.master: root = root.master # real root
Hm. Except that my Toplevel windows are often nested deeply, and
certainly not restricted to children of the root! I think that your
approach is distinctly different from _root() except if you severely
restrict your toplevel window creation.
Rob
--
===== r...@hooft.net http://www.xs4all.nl/~hooft/rob/ =====
===== R&D, Nonius BV, Delft http://www.nonius.nl/ =====
===== PGPid 0xFA19277D ========================== Use Linux! =========
Well as Python doesn't have enforced data hiding, I try to honor the
conventional access rules. _<symbol> is private, an implementation detail,
and thus less likely to be present in future versions than <symbol>.
| root = widget.winfo_toplevel()
| if root.master:
| root = root.master # real root
Rob W. W. Hooft:
|Hm. Except that my Toplevel windows are often nested deeply, and
|certainly not restricted to children of the root! I think that your
|approach is distinctly different from _root() except if you severely
|restrict your toplevel window creation.
Given this it seems we should have a public root() method. Could we
add a:
root = _root
definition to Tkinter's Misc class, to make this a public feature?
Thanks,
Randall
--
Randall Hopper
aa...@yahoo.com
the question is why?
if you're only out to get an interpreter handle (e.g. to
instantiate a variable or image object), any widget will
do.
if you wish to find the original application window, I'd say
it's much cleaner if you keep track of that by yourself
(IMO and IME, a good GUI design has one application level
object, which should *not* be a subclass of Tk).
so why, exactly, do you need the root?
</F>
I have a timer class built around Tk timers. I realize I could just pass
any_old_widget into this routine, and it would store it off into state data
and use it periodically to access the 'after' and 'after_cancel' methods.
However, this timer has nothing to do with this widget in particular, so
why should it have a reference to it (versus the button next to it, or the
list widget below it)? It makes more sense for the timer class to accept
and bookmark the root object. This root is associated with the global Tk
state, and it makes sense for a timer to bookmark this to use global Tk
state commands.
--
Randall Hopper
aa...@yahoo.com
Unless you're doing something wacky (creating multiple roots??), you
could just do what Tkinter itself (generally) does and use
Tkinter._default_root to get the instance of the root object....
--
-Jas
Right. I'm using _root() now which works. My original point wasn't that I
couldn't get root from a widget, but that to do it I violate the declared
public/private/protected policy for Tkinter. Since Python has no enforced
access control, I can poke at object internals anytime, but I really want
to avoid this.
My understanding is that .<symbol> is public, ._<symbol> is protected, and
.__<symbol> is private.
If _root() was ripped out in the next version of Python, I wouldn't have a
leg to stand on. And by all rights it's protected so removing it should
not affect me (or any other external code), unless I (or it) was deriving
off this class.
As Fredrik mentioned I could just snitch global Tk commands off
any_old_widget, but an event loop timer object that has nothing to do with
"any" widget shouldn't be keeping a handle to any_old_widget. That's not
clean code.
An alternative is just to pass root around everywhere, but that seems silly
if every widget already knows its root.
So my request was for _root() to be declared public (e.g. as .root())
--
Randall Hopper
aa...@yahoo.com
[...deriving from one of the widget class... this is a common practice, no?
So, you're probably safe anyway...]
> As Fredrik mentioned I could just snitch global Tk commands off
> any_old_widget, but an event loop timer object that has nothing to do with
> "any" widget shouldn't be keeping a handle to any_old_widget. That's not
> clean code.
Definitely.
...
> So my request was for _root() to be declared public (e.g. as .root())
Sorry -- I missed the very beginning of the thread. Indeed a public
Tkinter.root() (or .default_root()) seems like the best solution.
For the short run you could duplicate _root() in your own code -- it
relies only on "public" members after all ;-)
Class Misc:
...
def _root(self):
w = self
while w.master: w = w.master
return w
--
-Jas