Query the visibility of an window

43 views
Skip to first unread message

Alexandru

unread,
Jul 9, 2021, 3:02:57 AMJul 9
to
I use "lower" and "raise" to hide or show ttk::frame.
How can I query the visibility state?
Using "winfo ismapped" does not work.
I read a lot about the stacking order of widgets but cannot find a query command for this.

Many thanks
Alexnandru

Gerald Lester

unread,
Jul 9, 2021, 8:34:14 AMJul 9
to
First off read the entire winfo man/help page.

Second off, pay attention to the viewable subcommand.


--
+----------------------------------------------------------------------+
| Gerald W. Lester, President, KNG Consulting LLC |
| Email: Gerald...@kng-consulting.net |
+----------------------------------------------------------------------+

Alexandru

unread,
Jul 9, 2021, 8:59:39 AMJul 9
to
Did both. viewable didn't help. I'll look again, just in case...

Alexandru

unread,
Jul 9, 2021, 9:06:47 AMJul 9
to
As expected, the "viewable" subcommand returns 1, although the frame is hidden behind another widget.
Same for "ismapped".

Rich

unread,
Jul 9, 2021, 9:07:23 AMJul 9
to
Gerald Lester <Gerald...@kng-consulting.net> wrote:
> On 7/9/21 2:02 AM, Alexandru wrote:
>> I use "lower" and "raise" to hide or show ttk::frame.
>> How can I query the visibility state?
>> Using "winfo ismapped" does not work.
>> I read a lot about the stacking order of widgets but cannot find a query command for this.
>
> First off read the entire winfo man/help page.
>
> Second off, pay attention to the viewable subcommand.

viewable does not seem to produce what Alexandru presumably wants:

$ rlwrap wish
% frame .f1 -background yellow -width 100 -height 100
.f1
% frame .f2 -background blue -width 100 -height 100
.f2
% grid .f1 -row 0 -column 0
% grid .f2 -row 0 -column 0
% winfo viewable .f1
1
% raise .f1
% winfo viewable .f1
1
% lower .f1
% winfo viewable .f1
1

According to 'viewable' .f1 is visible no matter whether it is above,
or below .f2 in the stacking order.

Alexandru

unread,
Jul 9, 2021, 9:08:49 AMJul 9
to
Exactly. The only chance I see is getting the stacking order, but how?

Rich

unread,
Jul 9, 2021, 9:41:36 AMJul 9
to
Is there any possibility you could change your code to actually unmap
the frames? I.e., "pack forget", "grid forget", "place forget" instead
of raise/lower? Doing so would map/unmap the frames, and give you
visibility into their "on screen state" via 'ismapped'.

Otherwise if you must use raise/lower, you might have to instrument
raise/lower so that you can capture the stacking order yourself in a
list, then you can consult that list to determine what is on top.

Schelte

unread,
Jul 9, 2021, 10:28:04 AMJul 9
to
Have you tried putting a binding on the Visibility event? The man page
sounds promising: "A window is said to be obscured when another window
above it in the stacking order fully or partially overlaps it.
Visibility events are generated whenever a window's obscurity state
changes; the state field (%s) specifies the new state."

The binding could store the state in an array or dict keyed on the
window path so you can query it when needed.


Schelte.

Alexandru

unread,
Jul 9, 2021, 12:37:42 PMJul 9
to
I think that would be a viable solution. So I did:

bind $detailsframe <Visibility> {set ::frame_visible %s}

The tests show that the variable frame_visible is only set when the window is lowered and then the value is VisibilityUnobscured though I would expect VisibilityObscured.
When the frame becomes visible again (raised), then binding does not fire. So the variable value does not change.
Is this a bug?

Alexandru

unread,
Jul 9, 2021, 12:38:55 PMJul 9
to
Maybe, one of those. But I still hope that there is a better solution. In fact, maybe this could be inproved in Tcl by adding a new subcommand that queries the visibility state.

Rich

unread,
Jul 9, 2021, 1:15:17 PMJul 9
to
I would think the existing 'viewable' subcommand should provide that,
but instead it is documented as showing that the selected window is
mapped. The only difference from 'ismapped' is that 'viewable' is
documented to check that all ancestors are also mapped.

Christian Gollwitzer

unread,
Jul 9, 2021, 3:22:32 PMJul 9
to
Am 09.07.21 um 09:02 schrieb Alexandru:
> I use "lower" and "raise" to hide or show ttk::frame.
> How can I query the visibility state?

This may be a dumb question, but have you considered to use a
ttk::notebook? Multiple frames, where you see one at a time only
strongly sounds like ttk::notebook, and there you can simply ask it
about the selected page (tab "current")

Christian

Alexandru

unread,
Jul 10, 2021, 2:31:07 AMJul 10
to
No, that isn't an alternative. And it's actually just one frame in front of any other widgets.
I think Tl/Tk has missing feature here.

nemethi

unread,
Jul 10, 2021, 3:38:14 AMJul 10
to
Am 10.07.21 um 08:31 schrieb Alexandru:
Have you tried to solve your problem by using "winfo children <window>"?
From the man page:

"Returns a list containing the path names of all the children of
<window>. ... The list is in stacking order, with the lowest window
first, ..."

After raising/lowering your frame, its path name will be the last/first
element of [winfo children [winfo parent <window>]].

--
Csaba Nemethi https://www.nemethi.de mailto:csaba....@t-online.de

Alexandru

unread,
Jul 10, 2021, 3:41:20 AMJul 10
to
Oh, right, that could work. I knew there must be a way to get the stacking order but completly forgot about this command.
Nevertheless, in the meanwhile I use a global variable that stores the state of the frame.
It's not elegant but it's working.
Reply all
Reply to author
Forward
0 new messages