2012-02-12 2 views
6

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

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

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

QApplication::postEvent(obj_target, QEvent myevent); 

Это означает, что я пытаюсь поймать «MyEvent» событие в obj_target делать некоторые вещи.

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

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

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

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

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

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

+0

http://stackoverflow.com/questions/8729508/qt-qcoreapplicationpostevent должен ответить на ваш вопрос, я думаю. – Mat

+0

Спасибо, Мат, это хорошее начало, но мне нужно знать, можно ли зарегистрировать объекты для «прослушивания» определенного события. Я имею в виду, если я отправлю событие «привет», у меня есть или зарегистрируйте объекты, которые отвечают на это событие. – Herman

+0

В Qt нет смысла иметь событие без получателя. Возможно, вы могли бы сказать, что вы на самом деле пытаетесь сделать здесь? Из того, что вы описываете, кажется, что вы должны использовать сигналы/слоты, а не отправлять QEvents. –

ответ

0

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

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

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

  2. Есть QEvents.

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

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

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

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

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

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

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

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

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

+0

У меня такая же проблема на данный момент. Я хочу опубликовать событие в своем приложении с верхнего уровня (т. Е. Как будто он пришел извне), поэтому я не хочу указывать конкретный объект, кроме, быть может, самого приложения? –

+0

@code_fodder Это глупость, если вы не говорите о синтезе событий GUI. Если это то, что вы хотите, тогда вы должны посмотреть на тестовую структуру, которая является частью Qt. –

+0

@code_fodder Или, если вы заявляете, что это имеет смысл, то, пожалуйста, разъясните точный сценарий, который вам нужен, и точный пример «события», который вы хотите отправить. –

1

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

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