Russian Qt Forum

Qt => Общие вопросы => Тема начата: mozgofil от Июль 08, 2009, 19:23



Название: actionTriggered(QAction * action ) много раз
Отправлено: mozgofil от Июль 08, 2009, 19:23
соединяю slot actTriggered(QAction *) главного окна
с сигналом actionTriggered(QAction *)  тулбара.
в результате при нажатии на кнопочку тулбара сигнал посылается несколко раз вместо одного!!!
Как правильно сделать?


Название: Re: actionTriggered(QAction * action ) много раз
Отправлено: Авварон от Июль 09, 2009, 10:14
код в студию, так как ты написал, должно работать... мб у тебя есть лишние коннекты (например забыл закомментить)?


Название: Re: actionTriggered(QAction * action ) много раз
Отправлено: mozgofil от Июль 09, 2009, 19:10
код в студию, так как ты написал, должно работать... мб у тебя есть лишние коннекты (например забыл закомментить)?

Хм.. ну лишних коннектов точно нет, всё вроде впорядке, разве что имеется промежуточный класс :
Код
C++ (Qt)
class PrimaryFrm: public QMainWindow
{
 
};
class CMainFrm:public PrimaryFrm
{
 Q_OBJECT
......
public slots:
  void actionTriggered(QAction *);
};
 
Избавлюсь от него, потом отпишу что получилось:)
Спасибо за внимание


Название: Re: actionTriggered(QAction * action ) много раз
Отправлено: mozgofil от Июль 11, 2009, 09:42
Bug, господа!
QT4.5
Код
C++ (Qt)
void MainFrm::CreateMainMenuAndToolbar()
{
QToolBar* ptb = new QToolBar("Sample ToolBar");
QMenu* pmFile = new QMenu("&File");
QMenu* pmHelp = new QMenu("&Help");
this->addToolBar(ptb);
menuBar()->addMenu(pmFile);
menuBar()->addMenu(pmHelp);
 
QAction* a= new QAction("Caption",0);
pmFile->addAction(a);
ptb->addAction(a);
QObject::connect(ptb,SIGNAL(actionTriggered(QAction*)),this,SLOT(frm_actionTriggered(QAction*)));
QObject::connect(pmFile,SIGNAL(triggered(QAction*)),this,SLOT(frm_actionTriggered(QAction*)));
}
 
void MainFrm::frm_actionTriggered(QAction *A)
{
................//2 раза
}
 
при присоединении в 1 слот сигналов от меню и от тулбара ,
к которым добавлен одинаковый QAction, генерируются по 2 сигнала за раз!!!


Название: Re: actionTriggered(QAction * action ) много раз
Отправлено: f-r-o-s-t от Июль 11, 2009, 09:51
А ты попробуй соединить один раз вот так:
Код
C++ (Qt)
connect( a , SIGNAL(triggered()) , SLOT(someSlot()) );
 
void MainFrm::someSlot()
{
//он выполнится один раз, если надо узнать экшион который послал то так
QAction *a = qobject_cast<QAction*>(sender());
}
 


Название: Re: actionTriggered(QAction * action ) много раз
Отправлено: spectre71 от Июль 11, 2009, 10:56
Bug, господа!
QT4.5
...
...
при присоединении в 1 слот сигналов от меню и от тулбара ,
к которым добавлен одинаковый QAction, генерируются по 2 сигнала за раз!!!

Если что-то не получается, надо заглянуть в доку и прочитать, что там написано!

Цитировать
void QToolBar::actionTriggered ( QAction * action )   [signal]

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 tool bar. The parameter holds the triggered action.


Название: Re: actionTriggered(QAction * action ) много раз
Отправлено: mozgofil от Июль 11, 2009, 11:40
А ты попробуй соединить один раз вот так:
Код
C++ (Qt)
connect( a , SIGNAL(triggered()) , SLOT(someSlot()) );
 
void MainFrm::someSlot()
{
//он выполнится один раз, если надо узнать акшион который послал то так
QAction *a = qobject_cast<QAction*>(sender());
}
 
если соединять 1 раз или 1 экшн -то проблем нет


Название: Re: actionTriggered(QAction * action ) много раз
Отправлено: f-r-o-s-t от Июль 11, 2009, 11:41
а в чем тогда проблема ?


Название: Re: actionTriggered(QAction * action ) много раз
Отправлено: mozgofil от Июль 11, 2009, 11:43
Если что-то не получается, надо заглянуть в доку и прочитать, что там написано!

Цитировать
void QToolBar::actionTriggered ( QAction * action )   [signal]

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 tool bar. The parameter holds the triggered action.
действительно.Тролли здесь сплоховали :(


Название: Re: actionTriggered(QAction * action ) много раз
Отправлено: f-r-o-s-t от Июль 11, 2009, 11:46
В чем сплоховали ?
Если action находится на тулбаре, но вызван был с помощью шорката, то что нелогичного, непонятного
или плохого в том что произойдет вызов QToolBar::actionTriggered ?


Название: Re: actionTriggered(QAction * action ) много раз
Отправлено: mozgofil от Июль 11, 2009, 11:48
а в чем тогда проблема ?
В данном случае всё работает не так, как должно было бы.
Разумеется, можно обойти, но всё же я негодую по этому поводу.


Название: Re: actionTriggered(QAction * action ) много раз
Отправлено: f-r-o-s-t от Июль 11, 2009, 11:49
а в чем тогда проблема ?
В данном случае всё работает не так, как должно было бы.
Разумеется, можно обойти, но всё же я негодую по этому поводу.

а как должно было быть ?


Название: Re: actionTriggered(QAction * action ) много раз
Отправлено: mozgofil от Июль 11, 2009, 12:01
При нажатии кнопочки тулбара посылается 1 сигнал QToolBar::actionTriggered(QAction*)
При нажатии пункта меню посылается 1 сигнал QMenu::triggered(QAction*)
При нажатии кнопочки тулбара, либо пункта меню, либо шортката соответствующего экшну посылается 1 сигнал QAction::triggered
--
А так как есть - сигнал просто опосредованно конектится к экшну


Название: Re: actionTriggered(QAction * action ) много раз
Отправлено: f-r-o-s-t от Июль 11, 2009, 12:09
При нажатии кнопочки тулбара посылается 1 сигнал QToolBar::actionTriggered(QAction*)
При нажатии пункта меню посылается 1 сигнал QMenu::triggered(QAction*)
При нажатии кнопочки тулбара, либо пункта меню, либо шортката соответствующего экшну посылается 1 сигнал QAction::triggered
--
А так как есть - сигнал просто опосредованно конектится к экшну

А чем не устраивает такой вариант, ведь action один, какая вообще разница каким путем он был вызван ?
Нажат шоркат, пункт меню или тулбар реакция одинаковая, это как раз преимущество экшенов, что бы не писать
много раз один код.


Название: Re: actionTriggered(QAction * action ) много раз
Отправлено: ритт от Июль 11, 2009, 15:11
mozgofil, докажи, что это баг


Название: Re: actionTriggered(QAction * action ) много раз
Отправлено: mozgofil от Июль 12, 2009, 09:54
mozgofil, докажи, что это баг
это не баг, Spectre уже цитировал документацию по этому поводу


Название: Re: actionTriggered(QAction * action ) много раз
Отправлено: mozgofil от Июль 12, 2009, 10:06
При нажатии кнопочки тулбара посылается 1 сигнал QToolBar::actionTriggered(QAction*)
При нажатии пункта меню посылается 1 сигнал QMenu::triggered(QAction*)
При нажатии кнопочки тулбара, либо пункта меню, либо шортката соответствующего экшну посылается 1 сигнал QAction::triggered
--
А так как есть - сигнал просто опосредованно конектится к экшну

А чем не устраивает такой вариант, ведь action один, какая вообще разница каким путем он был вызван ?
Нажат шоркат, пункт меню или тулбар реакция одинаковая, это как раз преимущество экшенов, что бы не писать
много раз один код.
приведу пример :
Код
C++ (Qt)
 
QToolBar* ptb = new QToolBar("Sample ToolBar");
QMenu* pmFile = new QMenu("&File");
this->addToolBar(ptb);
menuBar()->addMenu(pmFile);
       QAction* actions[3]={.....};
       pmFile->addAction(actions[0]);/// 1 экшн в меню
       ptb->addAction(actions[1]);/// 1 экшн на тулбаре
///1 экшн и в меню и на тулбаре :
       pmFile->addAction(actions[2]);
       ptb->addAction(actions[2]);
 

Чтобы работали actions[0] и actions[1] нужно коннектить и к меню и к тулбару,
но в этом случае actions[2] будет сигналить 2 раза.



Название: Re: actionTriggered(QAction * action ) много раз
Отправлено: ритт от Июль 12, 2009, 10:21
чушь. коннектить нужно к акшену или к акшенгрупу.
или я не понимаю сути проблемы...


Название: Re: actionTriggered(QAction * action ) много раз
Отправлено: f-r-o-s-t от Июль 12, 2009, 10:54
приведу пример :
Код
C++ (Qt)
 
QToolBar* ptb = new QToolBar("Sample ToolBar");
QMenu* pmFile = new QMenu("&File");
this->addToolBar(ptb);
menuBar()->addMenu(pmFile);
       QAction* actions[3]={.....};
       pmFile->addAction(actions[0]);/// 1 экшн в меню
       ptb->addAction(actions[1]);/// 1 экшн на тулбаре
///1 экшн и в меню и на тулбаре :
       pmFile->addAction(actions[2]);
       ptb->addAction(actions[2]);
 

Чтобы работали actions[0] и actions[1] нужно коннектить и к меню и к тулбару,
но в этом случае actions[2] будет сигналить 2 раза.

action[0] & action[1] и так будут работать если приконнектить прямо к ним, а не к тулбару и.т.п.
Помоему просто автор плохо понимает зачем и как использовать actions.


Название: Re: actionTriggered(QAction * action ) много раз
Отправлено: spectre71 от Июль 12, 2009, 11:05
Вообще-то, в нормальном интерфейсе, в случае когда присутствует главное меню, все комманды(actions) на тулбарах, должны быть и в главном меню.


Название: Re: actionTriggered(QAction * action ) много раз
Отправлено: mozgofil от Июль 12, 2009, 19:55
Вообще-то, в нормальном интерфейсе, в случае когда присутствует главное меню, все комманды(actions) на тулбарах, должны быть и в главном меню.
А в ещё более "нормальном" интерфейсе состав меню и тулбаров можно изменять(Customize).


Название: Re: actionTriggered(QAction * action ) много раз
Отправлено: mozgofil от Июль 12, 2009, 20:00
приведу пример :
Код
C++ (Qt)
 
QToolBar* ptb = new QToolBar("Sample ToolBar");
QMenu* pmFile = new QMenu("&File");
this->addToolBar(ptb);
menuBar()->addMenu(pmFile);
       QAction* actions[3]={.....};
       pmFile->addAction(actions[0]);/// 1 экшн в меню
       ptb->addAction(actions[1]);/// 1 экшн на тулбаре
///1 экшн и в меню и на тулбаре :
       pmFile->addAction(actions[2]);
       ptb->addAction(actions[2]);
 

Чтобы работали actions[0] и actions[1] нужно коннектить и к меню и к тулбару,
но в этом случае actions[2] будет сигналить 2 раза.
action[0] & action[1] и так будут работать если приконнектить прямо к ним, а не к тулбару и.т.п.
Помоему просто автор плохо понимает зачем и как использовать actions.
ну, просветите меня как в вышеприведённом "правильно" сделать


Название: Re: actionTriggered(QAction * action ) много раз
Отправлено: mozgofil от Июль 12, 2009, 20:05
чушь. коннектить нужно к акшену или к акшенгрупу.
или я не понимаю сути проблемы...
да, вы неправильно понимаете.
суть в том что ВСЕ эшны обрабатываются ОДНОЙ функцией, на вход которой поступает
указатель на  экшн. (этого требует мой фрэймворк, который  поддерживает плагины).


Название: Re: actionTriggered(QAction * action ) много раз
Отправлено: BRE от Июль 12, 2009, 20:08
А в ещё более "нормальном" интерфейсе состав меню и тулбаров можно изменять(Customize).
Есть набор действия (action). Ты их создал и приконнектил к нужным слотам. А где ты их будешь располагать это уже твое дело. Хочешь часть в меню, часть на тулбаре, часть и там и там. И вызываться они будут один раз, не важно откуда они активировались.

Код
C++ (Qt)
QAction *act1 = new QAction(...);
QAction *act2 = new QAction(...);
QAction *act3 = new QAction(...);
 
connect( act1, SIGNAL( triggered() ), SLOT( slot_act1() ) );
connect( act2, SIGNAL( triggered() ), SLOT( slot_act2() ) );
connect( act3, SIGNAL( triggered() ), SLOT( slot_act3() ) );
 
pmFile->addAction( act1 );
pmFile->addAction( act3 );
 
ptb->addAction( act2 );
ptb->addAction( act3 );
 


Название: Re: actionTriggered(QAction * action ) много раз
Отправлено: BRE от Июль 12, 2009, 21:33
да, вы неправильно понимаете.
суть в том что ВСЕ эшны обрабатываются ОДНОЙ функцией, на вход которой поступает
указатель на  экшн. (этого требует мой фрэймворк, который  поддерживает плагины).
Соединяй все сигналы triggered всех действий с одним слотов и используй sender() для определения какое действие активировало слот.


Название: Re: actionTriggered(QAction * action ) много раз
Отправлено: f-r-o-s-t от Июль 12, 2009, 21:52
ну, просветите меня как в вышеприведённом "правильно" сделать

Я думаю из того что написал  BRE , должно было стать понятно как это сделать =)


Название: Re: actionTriggered(QAction * action ) много раз
Отправлено: ритт от Июль 12, 2009, 22:42
похоже, я всё-таки правильно понимаю "проблему"...


Название: Re: actionTriggered(QAction * action ) много раз
Отправлено: mozgofil от Июль 13, 2009, 19:45
да, вы неправильно понимаете.
суть в том что ВСЕ эшны обрабатываются ОДНОЙ функцией, на вход которой поступает
указатель на  экшн. (этого требует мой фрэймворк, который  поддерживает плагины).
Соединяй все сигналы triggered всех действий с одним слотов и используй sender() для определения какое действие активировало слот.
- то что надо, спасибо огромное  :)


Название: Re: actionTriggered(QAction * action ) много раз
Отправлено: mozgofil от Июль 13, 2009, 19:47
благодарю всех за внимание , тему можно закрыть