Russian Qt Forum

Компиляторы и платформы => Mac OS X => Тема начата: Igors от Январь 10, 2015, 11:08



Название: Клик в меню
Отправлено: Igors от Январь 10, 2015, 11:08
Добрый день

Когда юзер тычет мышей в меню мне нужно установить кое-какие айтемы меню в enabled/disabled и/или поменять их текст. Делать это в др месте накладно/хлопотно. На Вындоуз нема квешнзов, т.к. QMenuBar -рядовой виджет и MouseButtonPress доступен. А вот на OSX никаких Qt событий не приходит (проверял в notify). Ладно, навесил нативный фильтр, получил NSSystemDefined - и что с ним делать?  Ну конечно в гуглу - а там ответы типа таких

Цитировать
To understand this, you'll need to read up on the responder chain (https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/EventOverview/EventArchitecture/EventArchitecture.html). You'll want to pay particular attention to the section titled "Action Messages" at the bottom of the page I linked.

Не так себе "read", а "read up". Человек хотел по-быстрому проскочить, а ему по морде, концептуально :) Все-таки надо помягче с новичками  :)


Название: Re: Клик в меню
Отправлено: kambala от Январь 10, 2015, 20:18
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSMenu_Class/index.html#//apple_ref/c/data/NSMenuWillSendActionNotification вот это уведомление — не то, что нужно? по идее должно срабатывать при выборе любого элемента меню, даже верхнего уровня.
Цитировать
Posted just before the application dispatches a menu item’s action method to the menu item’s target.


Название: Re: Клик в меню
Отправлено: Igors от Январь 11, 2015, 10:36
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSMenu_Class/index.html#//apple_ref/c/data/NSMenuWillSendActionNotification вот это уведомление — не то, что нужно? по идее должно срабатывать при выборе любого элемента меню, даже верхнего уровня.
Не то, но нужное рядом

Цитировать
NSMenuDidBeginTrackingNotification

Posted when menu tracking begins. The notification object is the main menu bar ([NSApp mainMenu]) or the root menu of a popup button. This notification does not contain a userInfo dictionary.

Note

This notification is available in versions 10.3 and 10.4 of OS X, however it is not publicly declared so you must declare the name constant as an extern, for example:

    extern NSString *NSMenuDidBeginTrackingNotification;
Теперь надо разобраться как подсесть на это notification и отсеять попапки (интересен только main bar)

Спасибо


Название: Re: Клик в меню
Отправлено: kambala от Январь 11, 2015, 15:34
я думал это уведомление когда просто мышка наезжает на менюбар :)

повесить (пример):
Код
Objective-C
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(myHandler:) name:NSMenuDidBeginTrackingNotification object:nil];
...
- (void)myHandler:(NSNotification *)notification
{
}
селектор — обжсшный указатель на метод (типа SEL) грубо говоря (хотя вроде @selector() преобразовывает метод в некую особую строку...), но не знаю прокатит ли это в С++-классе; self — аналог this; object указан нулевым, что означает, что ловиться будет уведомление от любого объекта, который постит данное уведомление (в данном случае постит его лишь единственный экземпляр менюшки, поэтому можно и нил указать; если там указывать конкретный объект, то ловиться уведомления будут только от него). Когда обсервер удаляется, необходимо сделать
Код
Objective-C
[[NSNotificationCenter defaultCenter] removeObserver:self name:name:NSMenuDidBeginTrackingNotification object:nil];
чтобы не заработать краш при посылке уведомления на мертвый объект.

решение через блок (должно работать и в С++-классе):
Код
Objective-C
id<NSObject> observer = [[NSNotificationCenter defaultCenter] addObserverForName:NSMenuDidBeginTrackingNotification object:nil queue:nil usingBlock:(void (^)(NSNotification *note)) {
   // handler code
}];
// save the returned value `observer`
queue — объект типа NSOperationQueue (поток грубо говоря), в котором будет исполняться блок: nil означает, что блок будет выполняться в текущем потоке. Потом в деструкторе текущего класса надо отписаться от уведомления:
Код
Objective-C
[[NSNotificationCenter defaultCenter] removeObserver:observer]; // `observer` that was saved before

отсеять попапки (интересен только main bar)
отсеять - вероятно по highlightedItem (https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSMenu_Class/index.html#//apple_ref/occ/instm/NSMenu/highlightedItem)


Название: Re: Клик в меню
Отправлено: Igors от Январь 11, 2015, 19:30
Тут нужно время, освою - отпишусь


Название: Re: Клик в меню
Отправлено: Igors от Январь 28, 2015, 16:42
Тупенько передрал отсюда (http://lists.qt-project.org/pipermail/interest/2012-November/004797.html)
(по душе хорошо проверенные решения и.т.п.  :))


Название: Re: Клик в меню
Отправлено: kambala от Январь 28, 2015, 23:39
ну так оно ничем и не отличается от того, что я написал, за исключением того, что там от уведомления отписываются с помощью
Код
Objective-C
[[NSNotificationCenter defaultCenter] removeObserver:self];
хотя рекомендуется всегда отписываться от конкретных уведомлений: на что в своем коде подписался — от того и отписывайся. но в данном случае все равно т.к. объект статический и dealloc все равно вызван не будет.