Russian Qt Forum

Qt => Model-View (MV) => Тема начата: sq_vasya от Июля 19, 2010, 18:28



Название: Аналог System Message Query
Отправлено: sq_vasya от Июля 19, 2010, 18:28
Всем привет!
Столкнулся с проблемой и никак не могу найти решение. Аскал гугл, курил доки но прогрессу не много.

Есть два класса, которые друг о друге не знают Application и MyController.
MyController создаётся независимо от Application на основании одного из ответов сервера. По сути, это не очень важно, важен лишь факт, что классы ничего не знают друг о друге и не имеют понятия о моменте возникновения друг друга, чтобы поделится указателем на себя. Более того, очень бы нехотелось их друг на друга завязывать, поскольку мне выпало счастье саппортить чужой код и переделывать архитектуру, в которой я пока не сильно разбираюсь, не хочется.
Есть метод Application::notify() в который приходят уведомления о событиях клавиатуры (это то, что меня интересует). Мне нужно каким-то образом уведомить мой контроллер, который является потомком QWidget-a о том, что была нажата интересующая меня клавиша.
Прехватывать в самом контроллере события клавиатуры не получается, т.к. он не всегда в фокусе.
Раньше в Симбиане для подобных целей я использовал паблишинг RProperty что (очень грубо говоря) есть работа с очередью системных сообщений. Вот хотелось бы использовать нечто подобное на Qt, чтоб оно работало на всех платформах.
Не пинайте сильно, я только начинаю осваивать Qt, так что вполне могну не видеть решений, которые кажутся очевидными с точки зрения Qt разработчика.
Если есть какие-то другие пути решения данной проблемы - говорите. Мне важно только одно - чтобы нажатие кнопки всегда обрабатывалось внутри моего контроллера.


Название: Re: Аналог System Message Query
Отправлено: BRE от Июля 19, 2010, 19:02
Посмотри на:
void QObject::installEventFilter ( QObject * filterObj )
и пример в его описании.

Установить фильтр событий можно в самом MyController, а можно сделать отдельный класс, объект которого будет перехватывать сообщения и при возникновении нужного посылать сигнал. А этот сигнал уже ловить в MyController.


Название: Re: Аналог System Message Query
Отправлено: sq_vasya от Июля 20, 2010, 12:20
BRE, спасибо за ответ.

Я пробовал использовать QObject::installEventFilter ( QObject * filterObj ) ранее. После твоего совета попробовал это сделать ещё раз. Пробовал и через отельный класс, как это предлагается в документации, и пробовал перехватывать в самом MyController. Результат, как и прежде меня не удовлетворил. Контроллер перехватывает события только в том случае, если на нём установлен фокус. Если фокус не установлен, нотификаций я не получаю.

А вот в Application::notify() нотификации приходят всегда. Мне бы хотелось из Application уведомлять контроллер о возникновении интересующего меня события.

Есть ли в Qt какая-то очередь сообщений, на которую объекты могут подписываться и получать уведомления если кто-то запаблишил некое событие?


Название: Re: Аналог System Message Query
Отправлено: sq_vasya от Июля 20, 2010, 12:37
Из документации

Цитировать
bool QCoreApplication::notify ( QObject * receiver, QEvent * event )   [virtual]
...

5. Installing an event filter on the object. Such an event filter gets all the events, including Tab and Shift+Tab key press events, as long as they do not change the focus widget.
...

void QObject::installEventFilter ( QObject * filterObj )
...
event filter is an object that receives all events that are sent to this object.
...

Из первой цитаты можно сделать вывод, что обработка событий будет работать только в том случае, если на объекте установлен фокус. Вторая же говорит о том, что будут обработаны сообщения посланые только ЭТОМУ объекту. В постановке задачи было оговорено, что объекты Application и MyController о существовании друг друга не знают.

Может быть я что-то не совсем правильно понимаю? Или что-то делаю не так? Объясните, плз.

То, что я хочу, напоминает бродкастинг. Кто-то (Application в данном случае) вещает на весь мир, о чём-то, а заинтересованная сущность (MyController) подписывается на это вещание и в последствии обрабатывает интересующее его содержимое.


Название: Re: Аналог System Message Query
Отправлено: BRE от Июля 20, 2010, 15:18
Если сделать
Код
C++ (Qt)
qApp->installEventFilter( object );
 
то все сообщения будут сначала поступать в метод eventFilter объекта object.
Кто будет выступать этим объектом решать тебе, это может быть сам объект класса MyController, а может быть объект специального класса, который будет следить за необходимыми событиями и испускать сигналы, которые и будут ловиться MyController.


Название: Re: Аналог System Message Query
Отправлено: Igors от Июля 20, 2010, 19:40
В постановке задачи было оговорено, что объекты Application и MyController о существовании друг друга не знают.
Значит надо сделать небольшой класс доступный для обeих сторон, напр

Код
C++ (Qt)
class NotifyListener {
virtual bool notify( QObject * receiver, QEvent * event )  = 0;
 
static void Register( NotifyListener * ls ); // добавить ls в список слушателей для которых qApp вызовет их notify
};
 

И долить его в MyController
Код
C++ (Qt)
class MyController : public BaseController, public NotifyListener {
...
// from NotifyListener
virtual bool notify( QObject * receiver, QEvent * event );
};