问题
I want to detect when the user finished re-sizing or moving the GTK window. Basically an equivalent of WM_EXITSIZEMOVE in windows.
I have looked at GTK detecting window resize from the user and am able to detect size/location changes using the configure-event; however because of how my other code is architect I want to know when the resizing is done. Almost like ValueChanged instead of ValueChanging event.
I was thinking if i could find out is the mouse button is released or not and then try to detect if it was the last event I got. But can't find a way to do that either for a window object.
回答1:
You could use a timeout function that gets called once the resizing is done. The timeout is in ms, you might want to play with the value to get a balance between the delay in calling resize_done and triggering it before the resize is really done.
#define TIMEOUT 250
gboolean resize_done (gpointer data)
{
guint *id = data;
*id = 0;
/* call your existing code here */
return FALSE;
}
gboolean on_configure_event (GtkWidget *window, GdkEvent *event, gpointer data)
{
static guint id = 0;
if (id)
g_source_remove (id);
id = g_timeout_add (TIMEOUT, resize_done, &id);
return FALSE;
}
回答2:
I implemented a solution (some would call it workaround) with PyGObject and Python 3. As Phillip Wood in this quesiton and ratchet freak in another question mentioned I also used a timer based solution.
In the example the size-allocate event is used to detected the beginning of the window resize. I assume the user drag the window border with its mouse here. There are other ways to detect a window resize event: see discussion here.
Next the event is disconnected and as a surrogate a timer event (GLib.timeout_add() with 500 milliseconds) is created handling the next stuff.
Here is the example code:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from gi.repository import GLib
class MyWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self)
# close event
self.connect('delete-event', self._on_delete_event)
# "resize" event
self._connect_resize_event()
def _connect_resize_event(self):
self._timer_id = None
eid = self.connect('size-allocate', self._on_size_allocated)
self._event_id_size_allocate = eid
def _on_delete_event(self, a, b):
Gtk.main_quit()
def _on_size_allocated(self, widget, alloc):
print('EVENT: size allocated')
# don't install a second timer
if self._timer_id:
return
# remember new size
self._remembered_size = alloc
# disconnect the 'size-allocate' event
self.disconnect(self._event_id_size_allocate)
# create a 500ms timer
tid = GLib.timeout_add(interval=500, function=self._on_size_timer)
# ...and remember its id
self._timer_id = tid
def _on_size_timer(self):
# current window size
curr = self.get_allocated_size().allocation
# was the size changed in the last 500ms?
# NO changes anymore
if self._remembered_size.equal(curr): # == doesn't work here
print('RESIZING FINISHED')
# reconnect the 'size-allocate' event
self._connect_resize_event()
# stop the timer
self._timer_id = None
return False
# YES size was changed
# remember the new size for the next check after 500ms
self._remembered_size = curr
# repeat timer
return True
if __name__ == '__main__':
window = MyWindow()
window.show_all()
Gtk.main()
来源:https://stackoverflow.com/questions/19058392/detecting-when-a-gtk-window-is-done-moving-resizing-by-the-user