Discussion:
[Tkinter-discuss] Removing/disabling a resizable window's maximize button under Windows
python
2010-12-02 04:31:00 UTC
Permalink
Looking for advice on how to remove or disable a *resizable*
window's maximize button under Windows. I'm using Python 2.7 for
Windows.

Background: I have a resizable window with min and max sizes set
via the window's minsize() and maxsize() methods. When a user
clicks the maximize button, the window moves to the upper left of
the display. This is very confusing to my users so I would like
to prevent that behavior.

My research shows several ways to disable a maximize button - but
none of these techniques seem to apply to resizable windows?

1. Prevent a window from resizing via the resizable( False, False
) method.

2. Remove all the window's controls (and border) via the
overrideredirect( True ) method.

3. Use the mysterious transient(1) method (this raises an
exception under Windows).

Is there a way I can trap the maximize event (what event to bind
to?) and return "break" to prevent the maximize from happening
(or better yet, substitute my own behavior instead)?

Thank you,
Malcolm
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tkinter-discuss/attachments/20101201/41c8fd5e/attachment.html>
Michael Lange
2010-12-02 10:21:19 UTC
Permalink
Hi,

Thus spoketh python at bdurham.com
unto us on Wed, 01 Dec 2010 23:31:00 -0500:

(...)
Post by python
Is there a way I can trap the maximize event (what event to bind
to?) and return "break" to prevent the maximize from happening
(or better yet, substitute my own behavior instead)?
The only thing I can think of is to catch the <Configure> event and try
to determine the current state of the window, like:

def on_configure(event):
if event.widget.wm_state() == 'zoomed':
...update the window geometry as desired...

root.bind('<Configure>`, on_configure)

The "zoomed" state seems to be valid only for windows and OSX, not X11,
so I cannot test this here on my linux box.
Alternatively, as a last resort, you might try to remove the title bar
with overrideredirect and create your own title bar; the maximize button
then should toggle between wm_state('zoomed') and wm_state('normal') on
the window.

I hope this helps

Michael


.-.. .. ...- . .-.. --- -. --. .- -. -.. .--. .-. --- ... .--. . .-.

Either one of us, by himself, is expendable. Both of us are not.
-- Kirk, "The Devil in the Dark", stardate 3196.1
python
2010-12-02 11:01:01 UTC
Permalink
Hi Michael,

<snipped>
The only thing I can think of is to catch the <Configure> event and try
to determine the current state of the window, like:

def on_configure(event):
if event.widget.wm_state() == 'zoomed':
...update the window geometry as desired...

root.bind('<Configure>`, on_configure)
</snipped>

Thanks for your help. Here's what I discovered (Python 2.7 under Windows
7):

Binding a toplevel window's <Configure> event traps <Configure> events
for all of the window's widgets, not just the window itself. So here's
how I coded my event handler:

def onFrmResize( event=None ):
if not hasattr( event.widget, 'state' ):
return

if event.widget.state() == 'zoomed':
# proves I'm trapping maximize event
print 'maximize detected'

# return 'break' <--- does not work
# event.widget.geometry( '+100+100' ) <--- does not work

I can confirm that my event handler is being called properly via the
print message, but both return 'break' and explicitly setting position
via the geometry method appear to be ignored when executed within the
event handler.

Any other ideas?

Thanks,
Malcolm
python
2010-12-02 11:24:20 UTC
Permalink
Michael,

Here's an updated version of my event handler that restores a window to
its previous size/position when a maximize event is detected. Apparently
all one can do within the <Configure> event is change the state of a
window - changes to a window's geometry (size/position) are ignored.

The following is not a perfect technique - users can still see their
window move to the upper left corner of the display and then return to
its original state.

def onFrmResize( event=None ):
if not hasattr( event.widget, 'state' ):
return

if event.widget.state() == 'zoomed':
event.widget.state( 'normal' )

I wonder if there's an event that comes *before* <Configure> when a
window is maximized?

Malcolm
Michael Lange
2010-12-02 11:27:26 UTC
Permalink
Hi,

Thus spoketh python at bdurham.com
unto us on Thu, 02 Dec 2010 06:01:01 -0500:

(...)
Post by python
Binding a toplevel window's <Configure> event traps <Configure> events
for all of the window's widgets, not just the window itself. So here's
return
# proves I'm trapping maximize event
print 'maximize detected'
# return 'break' <--- does not work
# event.widget.geometry( '+100+100' ) <--- does not work
I can confirm that my event handler is being called properly via the
print message, but both return 'break' and explicitly setting position
via the geometry method appear to be ignored when executed within the
event handler.
return "break" will not work, because the Configure event is triggered
*after* the maximizing occurs, I suppose.
I can confirm that maximing a window always moves it into the upper left
corner of the screen on X11 with IceWM, too. Maybe it's oddities like this
which drive some programmers to draw their own custom titlebars instead of
using the WM's default ones.
Post by python
Any other ideas?
Actually the first thought was to change the default behavior of the
maximize button somehow through wm_protocol(). The obvious
wm_protocol("WM_MAXIMIZE_WINDOW") does not work (at least here) though,
and it's hard to find documentation on this.

Regards

Michael

.-.. .. ...- . .-.. --- -. --. .- -. -.. .--. .-. --- ... .--. . .-.

We do not colonize. We conquer. We rule. There is no other way for us.
-- Rojan, "By Any Other Name", stardate 4657.5

Loading...