Публиковать события без указания целевого объекта в Qt - PullRequest
6 голосов
/ 12 февраля 2012

Мне нужна помощь, чтобы понять, как использовать QEvents в QT, это сводит меня с ума.

Я пишу приложение, используя пользовательские события, но, как и в функции QApplication::postEvent, необходимо указать целевой объект.

Как я понимаю, можно публиковать события в цикле событий Qt с помощью

QApplication::postEvent(obj_target, QEvent myevent);

Это означает, что я пытаюсь перехватить событие "myevent" в obj_target и выполнить некоторые действия.

Но мне нужно публиковать события без указания целевого объекта, как это делают QMouseEvent или QKeyEvent

  • Я имею в виду, как при нажатии в QMainWindow с большим количеством кнопокэто то, что я могу нажать любую кнопку, и эта кнопка нажата?

  • Что такое целевой объект при публикации события щелчка?

  • Можно ли зарегистрировать объекты для "прослушивания" определенного события?

Я действительно запутался, возможно опубликовать событиебез указания целевого объекта?

Большое спасибо заранее

Ответы [ 2 ]

1 голос
/ 27 февраля 2017

Для этой цели у меня есть определенный одноэлементный класс, который я называю GuiSignalHub.Он группирует все сигналы приложения.

Объекты, которые хотят вызвать действие уровня приложения (например, открытие контекстной справки), просто подключают свой сигнал к сигналу GuiSignalHub.Приемники просто подключают GuiSignalHub к своему слоту.

1 голос
/ 05 июня 2012

Нет никакого тривиального способа опубликовать события "глобально", как сказал Дэн. Вся отправка событий собственных событий выполняется с помощью закрытого кода реализации Qt.

Важное различие:

  1. Существуют собственные сообщения / события, доставляемые операционной системой, обычно получаемые циклом событий для конкретного окна.

  2. Есть QEvents.

Внутренне, Qt отслеживает виджеты верхнего уровня (в действительности, windows), поэтому, когда он получает событие от ОС, он знает, в какое окно он должен перейти - он может сопоставить его, используя идентификатор окна платформы, для пример.

QEvent доставка не имеет смысла без принимающего объекта, поскольку отправка события объекту на самом деле означает только то, что метод QObject::event(QEvent*) вызывается для этого объекта. Невозможно вызвать этот метод без экземпляра объекта!

Если вы хотите синтезировать глобальное нажатие клавиши или событие щелчка мышью, то вам нужно выяснить, к какому объекту относится это событие. А именно:

  1. Укажите, в какое окно верхнего уровня (виджет) должно перейти событие. Вы можете перечислить виджеты верхнего уровня через qApp->topLevelWidgets().

  2. Определите дочерний виджет, к которому должно перейти событие. Если это событие клавиатуры, то достаточно отправить событие в текущий виджет с помощью qApp->focusWidget(). Вам нужно перечислить дочерние виджеты, чтобы найти самый глубокий в дереве, который перекрывает координаты мыши.

  3. Отправьте правильный подкласс QEvent на виджет, который вы только что определили. События, доставленные виджетам верхнего уровня, будут перенаправлены на правильный дочерний виджет.

При отправке событий мыши вам также необходимо синтезировать соответствующие события входа и выхода, иначе вы рискуете оставить виджеты в недопустимом состоянии. Исходный файл application.cpp должен дать вам некоторые идеи.

Это не дает вам доступа к собственным графическим элементам, таким как меню в OS X.

Пожалуйста, сообщите нам точно , что вы пытаетесь сделать. Почему вы хотите опубликовать трансляцию? Кто это получает? Поскольку ваши собственные классы, производные от QObject, будут получать эти широковещательные сообщения, я полагаю, достаточно просто использовать механизм сигнальных слотов. Вы просто connect(...) получили бы эти классы приемника для сигнала (-ов) какого-то глобального вещателя QObject.

...