I've addressed this problem by writing my own tk_messageBox that uses tkwait but, being intellectually curious, I'd like to know what alternatives might exist. They could be existing packages or some design choice that permits the use of tk_messageBoxbut any other suggestions would be welcomed.
On 4/14/22 9:54 PM, Michael Soyka wrote:messageBox but any other suggestions would be welcomed.
I've addressed this problem by writing my own tk_messageBox that uses tkwait but, being intellectually curious, I'd like to know what alternatives might exist. They could be existing packages or some design choice that permits the use of tk_
Hello,
I am sure most everybody has faced the same and come up with a similar solution. However, it is good to point out that you can achieve your
goal with the built-in tk_messageBox. Here is a quick example:
package req Tk
toplevel .hidden
wm withdraw .hidden
# rest of your script
tk_messageBox -message "Not blocking anything..." -parent .hidden
Also, I would guess that tk_messageBox blocks the event loop whether or
not the -parent option is specified.
Michael Soyka <[email protected]> wrote:
Also, I would guess that tk_messageBox blocks the event loop whether or
not the -parent option is specified.
You would guess effectively right, but in detail it runs it's
own message loop and specifically suppresses gui-events for
anything but itself.
Anyway, a messageBox without "modality" is just a toplevel with
a message widget and a couple of buttons arranged in frames...
I vaguely remember times when tk_messageBox was itself just a
procedure setting up the complete dialog.
It is still a procedure, but nowadays only a wrapper for
::tk::MessageBox, which itself cannot be inspected as a proc.
Using my standard debug-trick when running wish from a terminal
window (on linux. might not work on purely graphical OSes):
% fileevent stdin readable { puts stderr "[catch [gets stdin] r]: $r" }
now:
% ::tk::MessageBox -message message -detail detail -title title
# dialog pops up - wish's own repl is busy, but filevent stdin still fires.
winfo children .
0: .__tk__messagebox
winfo children .__tk__messagebox
0: .__tk__messagebox.bot .__tk__messagebox.top .__tk__messagebox.msg .__tk__messagebox.dtl .__tk__messagebox.bitmap .__tk__messagebox.ok
winfo class .__tk__messagebox.bot
0: TFrame
winfo class .__tk__messagebox.msg
0: TLabel
winfo class .__tk__messagebox.dtl
0: TLabel
.__tk__messagebox.dtl conf
0: {-background ...[too long]
and step by step one could examine the actual layout and recreate it.
On Thursday, April 14, 2022 at 10:29:45 PM UTC-4, [email protected] wrote:messageBox but any other suggestions would be welcomed.
On 4/14/22 9:54 PM, Michael Soyka wrote:
I've addressed this problem by writing my own tk_messageBox that uses tkwait but, being intellectually curious, I'd like to know what alternatives might exist. They could be existing packages or some design choice that permits the use of tk_
Hello,
I am sure most everybody has faced the same and come up with a similar
solution. However, it is good to point out that you can achieve your
goal with the built-in tk_messageBox. Here is a quick example:
package req Tk
toplevel .hidden
wm withdraw .hidden
# rest of your script
tk_messageBox -message "Not blocking anything..." -parent .hidden
I don't see how this makes tk_messageBox usable in my context. If the window is withdrawn while the message box exists, the operator can't review the text widget contents.
Please explain how this helps.
Also, I would guess that tk_messageBox blocks the event loop whether or not the -parent option is specified. Perhaps its effect on the event loop should be mentioned in the documentation, unless I'm missing something (wouldn't be the first time!).
Nonetheless, thank you for responding,
-mike
package req Tk
toplevel .hidden
wm withdraw .hidden
# rest of your script
tk_messageBox -message "Not blocking anything..." -parent .hidden
On 4/15/22 3:53 PM, Michael Soyka wrote:
package req Tk
toplevel .hidden
wm withdraw .hidden
# rest of your script
tk_messageBox -message "Not blocking anything..." -parent .hidden
Hello,
Did you try it? It should have worked.
As jtyler explained in his reply, there are a couple of more lines to
add to your code. They create a new toplevel, and immediately hide it.
Then when you call tk_messageBox, you use that toplevel as the parent.
As to why it works, message and dialog boxes are assumed to be "modal";
i.e., the rough idea is that they are meant to interrupt the current
flow of program/user actions and wait for a "decision" to be made before proceeding. They achieve this by blocking interactivity on the toplevel window identified as parent (either implicitly or explicitly). This is
done via a grab as explained by Robert Heller in another reply.
However, that block is local to that single toplevel window only. That
is why your code would not allow the user to scroll up/down or do
anything else in the main window while the message box was displayed.
However, you can create a new toplevel and set it as the parent of the tk_messageBox. Since the new toplevel is not displayed at all, the
message box will just sit there all by its lonely self without blocking anything that belongs in your actual script.
At Fri, 15 Apr 2022 20:37:26 -0000 (UTC) Andreas Leitgeb <[email protected]> wrote:
Michael Soyka <[email protected]> wrote:
Also, I would guess that tk_messageBox blocks the event loop whether or not the -parent option is specified.
You would guess effectively right, but in detail it runs it'sNo, it just does a "grab":
own message loop and specifically suppresses gui-events for
anything but itself.
grab(3tk) Tk Built-In Commands grab(3tk)
______________________________________________________________________________
NAME
grab - Confine pointer and keyboard events to a window sub-tree
SYNOPSIS
grab ?-global? window
grab option ?arg arg ...? ______________________________________________________________________________
DESCRIPTION
This command implements simple pointer and keyboard grabs for Tk. Tk's
grabs are different than the grabs described in the Xlib documentation.
When a grab is set for a particular window, Tk restricts all pointer
events to the grab window and its descendants in Tk's window hierarchy. Whenever the pointer is within the grab window's subtree, the pointer
will behave exactly the same as if there had been no grab at all and
all events will be reported in the normal fashion. When the pointer is outside window's tree, button presses and releases and mouse motion
events are reported to window, and window entry and window exit events
are ignored. The grab subtree "owns" the pointer: windows outside the
grab subtree will be visible on the screen but they will be insensitive
until the grab is released. The tree of windows underneath the grab
window can include top-level windows, in which case all of those top-
level windows and their descendants will continue to receive mouse
events during the grab.
Basically, a modal toplevel does this:
toplevel .foo
(build the rest of .foo)
set oldgrab [grab current .foo]
grab .foo
set oldfocus [focus]
focus .foo
tkwait window .foo;# could wait on a global set by a close/cancel button.
if {$oldgrab ne {}} {
grab $oldgrab
}
if {$oldfocus ne {}} {
focus $oldfocus
}
Removing all of the grab infrastructure and tossing the tkwait, yields a non-modal toplevel.
Robert Heller -- Cell: 413-658-7953 GV: 978-633-5364
Deepwoods Software -- Custom Software Services
http://www.deepsoft.com/ -- Linux Administration Services
[email protected] -- Webhosting Services
On 4/15/22 3:53 PM, Michael Soyka wrote:
Did you try it? It should have worked.package req Tk
toplevel .hidden
wm withdraw .hidden
# rest of your script
tk_messageBox -message "Not blocking anything..." -parent .hidden
[email protected] <[email protected]> wrote:
On 4/15/22 3:53 PM, Michael Soyka wrote:The strange thing is, I did try it from an interactive "wish", and I did: toplevel .hidden; wm withdraw .hidden
Did you try it? It should have worked.package req Tk
toplevel .hidden
wm withdraw .hidden
# rest of your script
tk_messageBox -message "Not blocking anything..." -parent .hidden
in a single line, to avoid the toplevel to pop up first (to mimic
its behaviour in a script)
Then I created (and packed) a text widget ".t" in ".", then I started
the message box with the removed toplevel .hidden as its parent.
And...
while the messagebox was open, the text was deaf to all my actions,
until I closed the popup.
Conclusion: Maybe, the behaviour for invisible parent toplevels is OS-dependent.
(in my case that was on Linux)
However, on my linux box running Tk 8.6.9 neither order works, i.e., the text widget is unresponsive.
On Saturday, April 16, 2022 at 10:47:42 AM UTC-4, Andreas Leitgeb wrote:
[email protected] <[email protected]> wrote:
On 4/15/22 3:53 PM, Michael Soyka wrote:The strange thing is, I did try it from an interactive "wish", and I did: toplevel .hidden; wm withdraw .hidden
Did you try it? It should have worked.package req Tk
toplevel .hidden
wm withdraw .hidden
# rest of your script
tk_messageBox -message "Not blocking anything..." -parent .hidden
in a single line, to avoid the toplevel to pop up first (to mimic
its behaviour in a script)
Then I created (and packed) a text widget ".t" in ".", then I started
the message box with the removed toplevel .hidden as its parent.
And...
while the messagebox was open, the text was deaf to all my actions,
until I closed the popup.
Conclusion: Maybe, the behaviour for invisible parent toplevels is OS-dependent.
(in my case that was on Linux)
I'm running ActiveState 8.6.6 on Windows 10 and, if I use your create sequence, my text widget is alive and kicking; likewise if created in the other order.
However, on my linux box running Tk 8.6.9 neither order works, i.e., the text widget is unresponsive.
On 4/16/22 11:23 AM, Michael Soyka wrote:
However, on my linux box running Tk 8.6.9 neither order works, i.e.,
the text widget is unresponsive.
Hello,
That is interesting. It looks like Linux side only has global grab vs. local. Also consider that Linux has several window managers and I
believe some give you options to control this specific behavior. I
don't have a Linux handy at the moment to test, though.
Well, maybe then using a thread is not overkill :)
grab(3tk) Tk Built-In Commands grab(3tk)
______________________________________________________________________________
NAME
grab - Confine pointer and keyboard events to a window sub-tree
SYNOPSIS
grab ?-global? window
grab option ?arg arg ...? ______________________________________________________________________________
DESCRIPTION
This command implements simple pointer and keyboard grabs for Tk. Tk's
grabs are different than the grabs described in the Xlib documentation.
When a grab is set for a particular window, Tk restricts all pointer
events to the grab window and its descendants in Tk's window hierarchy. Whenever the pointer is within the grab window's subtree, the pointer
will behave exactly the same as if there had been no grab at all and
all events will be reported in the normal fashion.
When the pointer is
outside window's tree, button presses and releases and mouse motion
events are reported to window, and window entry and window exit events
are ignored. The grab subtree "owns" the pointer: windows outside the
grab subtree will be visible on the screen but they will be insensitive until the grab is released. The tree of windows underneath the grab
window can include top-level windows, in which case all of those top-
level windows and their descendants will continue to receive mouse
events during the grab.
Robert Heller -- Cell: 413-658-7953 GV: 978-633-5364
Deepwoods Software -- Custom Software Services
http://www.deepsoft.com/ -- Linux Administration Services [email protected] -- Webhosting Services
On Friday, April 15, 2022 at 5:52:14 PM UTC-4, Robert Heller wrote:
not follow that the linux behavior correctly implements "grab" and that Windows does not?grab(3tk) Tk Built-In Commands grab(3tk)
______________________________________________________________________________
NAME
grab - Confine pointer and keyboard events to a window sub-tree
SYNOPSIS
grab ?-global? window
grab option ?arg arg ...? ______________________________________________________________________________
DESCRIPTION
This command implements simple pointer and keyboard grabs for Tk. Tk's grabs are different than the grabs described in the Xlib documentation. When a grab is set for a particular window, Tk restricts all pointer
events to the grab window and its descendants in Tk's window hierarchy. Whenever the pointer is within the grab window's subtree, the pointer
will behave exactly the same as if there had been no grab at all and
all events will be reported in the normal fashion.
It was suggested in an earlier post to associate the tk_messageBox window with a hidden toplevel as a way of keeping my text widget responsive. This worked on Windows but not linux. If I understand the following two sentences in the manpage, does it
When the pointer is
outside window's tree, button presses and releases and mouse motion
events are reported to window, and window entry and window exit events
are ignored. The grab subtree "owns" the pointer: windows outside the
grab subtree will be visible on the screen but they will be insensitive until the grab is released. The tree of windows underneath the grab
window can include top-level windows, in which case all of those top-
level windows and their descendants will continue to receive mouse
events during the grab.
Robert Heller -- Cell: 413-658-7953 GV: 978-633-5364
Deepwoods Software -- Custom Software Services
http://www.deepsoft.com/ -- Linux Administration Services [email protected] -- Webhosting Services
not follow that the linux behavior correctly implements "grab" and that Windows does not?______________________________________________________________________________
DESCRIPTION
This command implements simple pointer and keyboard grabs for Tk. Tk's
grabs are different than the grabs described in the Xlib documentation.
When a grab is set for a particular window, Tk restricts all pointer
events to the grab window and its descendants in Tk's window hierarchy.
Whenever the pointer is within the grab window's subtree, the pointer
will behave exactly the same as if there had been no grab at all and
all events will be reported in the normal fashion.
It was suggested in an earlier post to associate the tk_messageBox window with a hidden toplevel as a way of keeping my text widget responsive. This worked on Windows but not linux. If I understand the following two sentences in the manpage, does it
On 4/18/22 10:18 AM, Michael Soyka wrote:it not follow that the linux behavior correctly implements "grab" and that Windows does not?
______________________________________________________________________________
DESCRIPTION
This command implements simple pointer and keyboard grabs for Tk. Tk's
grabs are different than the grabs described in the Xlib documentation.
When a grab is set for a particular window, Tk restricts all pointer
events to the grab window and its descendants in Tk's window hierarchy.
Whenever the pointer is within the grab window's subtree, the pointer
will behave exactly the same as if there had been no grab at all and
all events will be reported in the normal fashion.
It was suggested in an earlier post to associate the tk_messageBox window with a hidden toplevel as a way of keeping my text widget responsive. This worked on Windows but not linux. If I understand the following two sentences in the manpage, does
Hello,
First, a brief comment on the above and then a solution that should work
on Linux just as it does on Windows.
Widget hierarchy is a tree structure - top-down from a toplevel all the
way down through various frames to individual widgets. So when the documentation says "subtree" and its "descendants", it refers to that
pathway from the toplevel down. A "subtree" does not include widgets
from another toplevel. For example, ".a.b.c" and ".x.b.c.d" have
nothing in common except for sharing the root window as parent.
Hopefully this description is clear.
Now, as to why the original suggestion did not work on Linux: I think it comes down to the ".hidden" window being invisible. We can fix it by
keeping it visible but not too distracting to the user.
Please try this code on Linux and see if it works better:
package req Tk
toplevel .hidden
wm overrideredirect .hidden 1
wm geometry .hidden 1x1+0+0
# insert your script here
tk_messageBox -message "Not blocking anything..." -parent .hidden
So when the documentation says "subtree" and its "descendants", it
refers to that pathway from the toplevel down. A "subtree" does not
include widgets from another toplevel.
Really, the best way is to just implement a non-modal version of tk_messageBox. Which is really quite simple...
Playing games with hidden or almost hidden toplevels is just plain hokey...
Actually, in most of my applications, I make very minimual use of tk_messageBox. Instead I have a general purpose Dialog widget class, which...
If all you want to put up a non-modal message box that looks exactly like tk_messageBox, just grap the code in /usr/share/tcltk/tk8.6/msgbox.tcl and
On 18/04/2022 18:27, [email protected] wrote:
So when the documentation says "subtree" and its "descendants", it
refers to that pathway from the toplevel down. A "subtree" does not
include widgets from another toplevel.
The documentation refers to "the grab window and its descendants" *as*
the "subtree". So it's not from the toplevel down, but from the grab
window down. And only that part of the window hierarchy is active. All
the rest is blocked. That includes other toplevels and their descendants.
DESCRIPTION
When a grab is set for a ***particular window***, Tk restricts all pointer
events to the grab window and its descendants in Tk's window hierarchy.
Whenever the pointer is within the grab window's subtree, the pointer
will behave exactly the same as if there had been no grab at all and
all events will be reported in the normal fashion. When the pointer is
outside window's tree, button presses and releases and mouse motion
events are reported to window, and window entry and window exit events
are ignored. The grab subtree "owns" the pointer: windows outside the
grab subtree will be visible on the screen but they will be insensitive
until the grab is released. The tree of windows underneath the grab
window can include top-level windows, in which case all of those top-
level windows and their descendants will continue to receive mouse
events during the grab.
Really, the best way is to just implement a non-modal version of tk_messageBox. Which is really quite simple...
Playing games with hidden or almost hidden toplevels is just plain hokey...
Actually, in most of my applications, I make very minimual use of tk_messageBox. Instead I have a general purpose Dialog widget class, which has a flag for being modal or not. In some applications where I have a lot of
non-modal informational windows, I create a widget class just for that. (It is not rocket science...)
If all you want to put up a non-modal message box that looks exactly like tk_messageBox, just grap the code in /usr/share/tcltk/tk8.6/msgbox.tcl and remove some (all) of the code starting with the line "# 8. Set a grab and claim the focus too." -- this is where all of the modal fun and games starts.
Change the name of the function and you are all set.
--
Robert Heller -- Cell: 413-658-7953 GV: 978-633-5364
Deepwoods Software -- Custom Software Services
http://www.deepsoft.com/ -- Linux Administration Services [email protected] -- Webhosting Services
On Monday, April 18, 2022 at 1:42:23 PM UTC-4, Robert Heller wrote:messageBox works and it caused to crack-open my old Tk books, something I should have done from the start (RTFM as some might say).
Really, the best way is to just implement a non-modal version of tk_messageBox. Which is really quite simple...
and, as I mentioned in my initial post, I've done that and it works just fine (and it was easy).
My reason for posting was to learn from others about possible alternatives. So far, threads and slave interpreters were mentioned and those are the kinds of responses I was hoping for. Nonetheless, I do appreciate the explanations of how tk_
Playing games with hidden or almost hidden toplevels is just plain hokey...
Actually, in most of my applications, I make very minimual use of tk_messageBox. Instead I have a general purpose Dialog widget class, which has a flag for being modal or not. In some applications where I have a lot of
non-modal informational windows, I create a widget class just for that. (It is not rocket science...)
By the way, what you describe is sounds similar to the custom dialog implementation given in "Effective Tcl/Tk Programming" by Harrison & McLennan except for the modality flag.
If all you want to put up a non-modal message box that looks exactly like tk_messageBox, just grap the code in /usr/share/tcltk/tk8.6/msgbox.tcl and remove some (all) of the code starting with the line "# 8. Set a grab and claim the focus too." -- this is where all of the modal fun and games starts.
Change the name of the function and you are all set.
All I needed was a non-modal replacement with retry/cancel capability , the visual appearance of tk_messageBox served as a useful guide.
--
Robert Heller -- Cell: 413-658-7953 GV: 978-633-5364
Deepwoods Software -- Custom Software Services
http://www.deepsoft.com/ -- Linux Administration Services [email protected] -- Webhosting Services
Just to confirm: I tried your modified version on linux and it doesn't
work either.
I am not sure I read you correctly. Are you saying all other toplevels
are also locked due to the grab? If so, I would be surprised as it is contrary to my experience and to the documentation. The manual would
have to refer to the "application" and not the "window".
Also see the man page for grab. You can set it as global meaning application-wide, or local, meaning a single toplevel.
From the man page:
DESCRIPTION
When a grab is set for a ***particular window***, Tk restricts all pointer
events to the grab window and its descendants in Tk's window hierarchy.
[email protected] <[email protected]> wrote:
I am not sure I read you correctly. Are you saying all other toplevels
are also locked due to the grab? If so, I would be surprised as it is
contrary to my experience and to the documentation. The manual would
have to refer to the "application" and not the "window".
The "grabwindow" is really the start of the subtree that can still
receive events.
From the man page:
DESCRIPTION
When a grab is set for a ***particular window***, Tk
restricts all pointer events to the grab window and its
descendants in Tk's window hierarchy.
I understood the phrase "X restricts Y to Z" such that that X causes Y
to be "allowed only with Z".
| Sysop: | Keyop |
|---|---|
| Location: | Huddersfield, West Yorkshire, UK |
| Users: | 714 |
| Nodes: | 16 (2 / 14) |
| Uptime: | 133:55:25 |
| Calls: | 12,087 |
| Files: | 14,997 |
| Messages: | 6,517,349 |