Tkinter: modal ok in windows, but not in Linux

Eric Brunel eric.brunel at N0SP4M.com
Fri Jan 16 16:07:38 CET 2004


klappnase wrote:
> DoubleM <mmoum at woh.rr.com> wrote in message news:<NWkNb.2858$fU.1773 at fe2.columbus.rr.com>...
> 
>>Hi,
>>
>>I'm running Python2.3.3c1 on Mandrake 9.1
>>
>>The following code is designed to bring up a window with a button labeled
>>"popup".  Clicking on the popup buttons triggers a secondary window with a
>>button labeled "ok".  The second window is supposed to be modal - it should
>>not be possible to reset the focus back to the first window or close the
>>first window without first closing the second.  The program works just fine
>>in Windows XP home, but in Linux I can close the first window while the
>>second one is still active.
>>
>>This seems to be a bug, or am I doing something wrong.  I searched google
>>for Tkinter Linux modal, but found nothing relevant.
>>
>>Thanks for your help.
>>
>>Here's the code, copied and pasted from IDLE.
>>
>>#############################
>>from Tkinter import *
>>
>>makemodal = 1
>>
>>def dialog():
>>    win = Toplevel()
>>    Label(win, text = "Secondary").pack()
>>    Button(win, text = "Ok", command = win.destroy).pack()
>>    if makemodal:
>>        win.focus_set()
>>        win.grab_set()
>>        win.wait_window()
>>    print "dialog exit"
>>
>>root = Tk()
>>Button(root, text = 'popup', command = dialog).pack()
>>root.mainloop()
>>#################################
>>
>>Mike
>>mmoum-xxxspam.woh.rr.com
> 
> 
> Hi Mike,
> 
> I guess you should use
> 
>     root.wait_window(win)
> 
> instead of
>  
>     win.wait_window()

It is indeed better, and so is doing a:

win.transient(root)

to avoid being able to put the main window on top of the dialog.

This won't however solve the OP's problem, which is that the main window can 
still be closed when the second window is running.

We've had the same problem, and I finally ended up thinking this problem's is 
not Python's fault, nor Tkinter's one, nor even tk's one: with X11, the controls 
on the window frame are actually managed not by the client application (from the 
X11 server point of view), but by the window manager. If the window manager 
decides to ignore the grab set on one of your windows and to continue to treat 
events for the other windows, you're stuck. The only thing you can do is 
treating the window deletion event to explicitely ignore it via a 
root.protocol('WM_DELETE_WINDOW', ...). There may be a way of doing it 
automatically at tk's level, but it would certainly be a big work, not to 
mention that there may be some window managers that *do* take the grab_set into 
account, and so where this work would be unnecessary.

There are other issues due to the window manager on various platforms; for 
example, the CDE window manager dtwm used on Sun's apparently can't make a 
window always stay on top of another. So dialogs on Sun's can always be put 
behind by clicking on another window of your application, which is really annoying.

All of the above is only my analysis of the problem; if anybody can confirm or 
prove me wrong, I'll be happy to learn something :-). But since tk is just a 
layer on "native" widgets for all platforms, you may always get behaviour 
differences across platforms for such things. I suppose other toolkits using the 
same principles (e.g. wxWindows) may have the same problems.

HTH
-- 
- Eric Brunel <eric dot brunel at pragmadev dot com> -
PragmaDev : Real Time Software Development Tools - http://www.pragmadev.com




More information about the Python-list mailing list