Обнаружение, когда пользователь перемещает/изменяет размер окна GTK

Я хочу определить, когда пользователь закончил изменять размер или перемещать окно GTK. В основном эквивалент WM_EXITSIZEMOVE в окнах.

Я просмотрел GTK, определяющий изменение размера окна пользователем, и могу для обнаружения изменений размера/местоположения с помощью события configure; однако из-за того, что мой другой код является архитектором, я хочу знать, когда будет выполнено изменение размера. Почти как ValueChanged вместо события ValueChanging.

Я думал, смогу ли я узнать, отпущена ли кнопка мыши или нет, а затем попытаться определить, было ли это последнее событие, которое я получил. Но не могу найти способ сделать это и для оконного объекта.


person Manny    schedule 27.09.2013    source источник
comment
Возможный дубликат Gtk/GtkD Обнаружение отпускания кнопки мыши на изменить размер окна?   -  person buhtz    schedule 15.02.2019


Ответы (2)


Вы можете использовать функцию тайм-аута, которая вызывается после изменения размера. Тайм-аут в мс, вы можете поиграть со значением, чтобы получить баланс между задержкой вызова resize_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;
}
person Phillip Wood    schedule 29.09.2013
comment
Спасибо! Это работает нормально. Однако я беспокоюсь, что ввожу код, зависящий от времени. Есть ли способ определить, что изменение размера выполняется иначе, чем в зависимости от некоторого тайм-аута. - person Manny; 30.09.2013
comment
Насколько я знаю, я боюсь :-( Я не уверен, что X подает сигнал при изменении размера, только тогда, когда он запрашивается. Если вы беспокоитесь о задержке функции тайм-аута, вы можете использовать g_timeout_add_full и установить высокий приоритет. - person Phillip Wood; 30.09.2013

Я реализовал решение (некоторые назвали бы его обходным путем) с PyGObject и Python 3. Как Phillip Wood в этом вопросе и уродец с храповым механизмом в другом упомянутом вопросе я также использовал решение на основе таймера.

В примере size-allocate Событие используется для обнаружения начала изменения размера окна. Я предполагаю, что пользователь перетащит сюда границу окна с помощью мыши. Существуют и другие способы обнаружения события изменения размера окна: см. обсуждение здесь.

Затем событие отключается и в качестве суррогатного события таймера (GLib.timeout_add() с 500 миллисекундами) создается для обработки следующего материала.

Вот пример кода:

#!/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()
person buhtz    schedule 15.02.2019