Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: Racheengel от Октябрь 13, 2015, 12:46



Название: actionTriggered... так надо или Баг?
Отправлено: Racheengel от Октябрь 13, 2015, 12:46
Всем Привет,

вот сегодня ВНЕЗАПНО заметили такую ВЕСЧъ:

Есть QMenu, и есть QToolBar. И туда, и туда пакуется один и тот же QAction.
И меню, и тулбар подключены сигналом actionTriggered() к слоту.
Теперь внимание: если кликаем по кнопке экшина на тулбаре - вызывается И actionTriggered тулбара, И actionTriggered меню.
Т.е. в слот мы попадаем 2 (ДВА) раза.
То же самое происходит, если выбрать экшин в меню. Сначала вызовется actionTriggered меню, потом - тулбара.

Это так и надо? Или БАГъ? В доке про подобное поведение ни слова...


Название: Re: actionTriggered... так надо или Баг?
Отправлено: Bepec от Октябрь 13, 2015, 19:06
Ну это логично. Экшен то один, к нему 2 сигнала подсоединены. То есть надо было только один раз соединять и всё.
Это фича.
Т.е. подцепил один раз в меню, потом хоть куда его суй - он нужный слот вызовет )


Название: Re: actionTriggered... так надо или Баг?
Отправлено: Racheengel от Октябрь 13, 2015, 19:34
То, что слот экшена вызовется - логично.
А то, что слот ТУЛБАРА actionTriggered(QAction*) вызывается, когда экшин из МЕНЮ вызван - как-то имхо не очень...
Проблема в том, что один и тот же экшин несколько раз триггеруется в таком случае.
Поэтому непонятно пока, как это расценивать.


Название: Re: actionTriggered... так надо или Баг?
Отправлено: Bepec от Октябрь 13, 2015, 19:45
Это один объект, в тулбаре и в меню. Т.е. обращаясь тулбар-экшен и меню-экшан, вы получаете один указатель. Так что вы просто неправильно делаете, один слот и одна привязка на один экшн должны быть.
А вы ему 2 сигнала навесили :)


Название: Re: actionTriggered... так надо или Баг?
Отправлено: Racheengel от Октябрь 13, 2015, 21:34
Мы как полагали изначально - есть тулбар, на котором Х экшнов. Часть из них плюс некоторые другие размещены параллельно в меню. Конечно, можно каждый экшн тупо связать через сигнал QAction::triggered с соответствующими слотами - и это будет работать. Но по архитектурным причинам (местами используются шаблоны, которые не кушает мок) представлялось оптимальным использовать сигналы QToolBar::actionTriggered(QAction*) и QMenu::actionTriggered(QAction*). Далее каждый из них связывается с центральным слотом-диспетчером, который и обрабатывает тригерованный экшн.

В документации Qt НИКАК не акцентировано то, что actionTriggered-сигналы будут эмитироваться ОДНОВРЕМЕННО ВСЕМИ виджетами, с которыми связан конкретный экшн. Т.е. эта связь абсолютно не очевидна пользователю классов QToolBar и QMenu. Про детали внутренней реализации механизма actionTriggered нигде не сказано. Ведь пользователь ожидает, что при нажатии кнопки на тулбаре будет вызван сигнал QToolBar::actionTriggered, но никак не QMenu::actionTriggered.

А получается по сути, если один и тот же экшен посажен в N виджетов - то при его вызове "сдетонирует" каждый из этих виджетов, даже если он не был тригерован пользователем.


Название: Re: actionTriggered... так надо или Баг?
Отправлено: __Heaven__ от Октябрь 14, 2015, 07:03
Цитировать
void QToolBar::actionTriggered(QAction * action)
This signal is emitted when an action in this toolbar is triggered. This happens when the action's tool button is pressed, or when the action is triggered in some other way outside the toolbar. The parameter holds the triggered action.



Название: Re: actionTriggered... так надо или Баг?
Отправлено: Racheengel от Октябрь 14, 2015, 09:30
Хм, интересно. У нас Qt 5.3, надо будет еще раз посмотреть, спасибо...