问题
In GTK (or pygtk or gtkmm...)
How can I detect that an application window has been manually resized by the user, as is typically done by dragging the window's edge?
I need to find a way to differentiate manual resizes from resizes that originate from gtk, such as changes in window content.
回答1:
Have you tried connecting to the GDK_CONFIGURE event?
Check out this example under the "Moving window" section. The example shows a callback doing something when the window is moved, but the configure event is a catch-all for moving, resizing and stack order events.
回答2:
I managed to pull this off by watching for size_allocate
and size_request
signals on the GtkWindow
. If size_request
ever got smaller, I called resize(1,1)
. If size_allocate
was ever bigger than expected, I turned the system off.
One thing I made sure to handle was size_request
returning big, then small, and having size_allocate
be big and then small. I don't know if this is possible, but I fixed it by making sure to only decrease the expected values for size_allocate
when I got a smaller size_allocate
, not when I got a smaller size_request
.
Make sure that your size_request
handler comes after the base class' handler so that you get the right values. I did this by overriding the method and then calling the base class method first.
I've tried this in both 1 and 2 dimensions and it seems to work either way.
回答3:
In PyGTK, I've always watched for the expose_event
for a window resize, then use the get_allocation
method to get the new size.
回答4:
In my case I was trying to distinguish between a user resizing a Gtk.Paned from the user resizing the whole window. Both emitted the notify::position
signal.
My solution was, since I can't know if the user is resizing the window from the widget, reverse what I wanted to know. Record if the user has re-positioned the widget and ignore updates if the user didn't initiate them on my widget.
That is to say, instead of testing "if window being resized" I recorded the button-press-event
and button-release-event
's locally so I could instead test "if widget being re-positioned"
from gi.repository import Gtk
class MyPaned(Gtk.Paned):
_user_activated = False
def on_position(self, _, gparamspec):
if self._user_activated:
# widget touched
else:
# window resized (probably)
def on_button_press(self, *_):
self._user_activated = True
def on_button_release(self, *_):
self._user_activated = False
dev __init__(self, *args):
super(MyPaned, self).__init__(*args)
self.connect('notify::position', self.on_position)
self.connect('button-press-event', self.on_button_press)
self.connect('button-release-event', self.on_button_release)
Effectively by recorded when the user started and ended interacting with my widget directly, I could assume the rest of the time was due to the window being resized. (Until I find more cases)
回答5:
You may be able to throw something together by using gdk_window_get_root_origin to get the top left corner of the window and gdk_window_get_geometry to get the width and height. Then you could hook a callback into the GDK_BUTTON_PRESS_MASK and check to see if the button press occurs near/on one of the edges of the window.
Of course, this seems quite hackish and it really bothers me that I couldn't find some simple way in the documentation for GdkWindow to do this. There is a gdk_window_begin_resize_drag function which really makes me think there's a cleaner way to do this, but I didn't see anything more obvious than my answer.
来源:https://stackoverflow.com/questions/1060039/gtk-detecting-window-resize-from-the-user