Tkinter: modal ok in windows, but not in Linux

D

DoubleM

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
 
K

klappnase

DoubleM said:
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()

Cheers

Michael
 
E

Eric Brunel

klappnase said:
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
 
D

DoubleM

Eric Brunel wrote:

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.

Thanks for the replies. I rather suspected as much, given that it works
find in Windows XP, but was hoping I was wrong.

Mike
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top