Russian Qt Forum
Мая 10, 2025, 06:48 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Как узнать, какой пункт меню был выбран?  (Прочитано 9638 раз)
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« : Июня 23, 2011, 14:30 »

Формируется главное меню окна динамически.
К примеру, есть несколько клиентов, для каждого клиента свой пункт меню.
Все пункты меню нужно привязать к одному слоту этого окна, в котором нужно произвести некоторые предварительные настройки программы, а затем обратиться к конкретному клиенту.
Как это сделать?
Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #1 : Июня 23, 2011, 14:43 »

В слоте через sender() узнать, кто его вызвал и выполнять нужные действия.
Записан
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #2 : Июня 23, 2011, 17:13 »

sender у кого брать?
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #3 : Июня 23, 2011, 17:35 »

просто вызываешь sender() - он определён во всех классах-наследниках QObject. если слот mySlot() вызывается при нажатии на команду меню, то код будет примерно таким:
Код
C++ (Qt)
void mySlot()
{
   QAction *action = qobject_cast<QAction *>(sender());
   if (action)
   {
       // делаешь что нужно
   }
}
 
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Denjs
Гость
« Ответ #4 : Июня 23, 2011, 17:48 »

В слоте через sender() узнать, кто его вызвал и выполнять нужные действия.
это не совсем хороший путь.
Будет работать не для всех типов соединения (как я понимаю только для Qt::DirectConnection), и только в рамках одного потока.

При Qt::QueuedConnection или когда источник и приемник находятся в разных потоках - в общем случае - объект-источник может быть уже уничтожен к моменту, когда сигнал будет доставлен. Соответсвенно никакого "валидного" sender вы не получите.

Для сигналов с "пустой сигнатурой" (вида "clicked()") используйте QSignalMapper - он переиспускает полученный сигнал со строкой идентифицирующей тот или иной источник к нему подключенный т.е. (сигнал "clicked()" становится "activated(QString mySourceString)").
« Последнее редактирование: Июня 23, 2011, 17:51 от Denjs » Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #5 : Июня 23, 2011, 20:07 »

это не совсем хороший путь.
Это совсем хороший путь, просто со своей областью применения, зато в чём-то и более функциональный в смысле возможности предачи данных.
Поскольку всё будет работать в одном потоке, Qt::DirectConnection вполне применим и будет использоваться по умолчанию, если не указать иное (привязывается «пункт меню» к «слоту окна», а так как весь гуй обязан жить в одном потоке, то у источника и приёмника будет один поток).
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Июня 23, 2011, 21:49 »

По ходу дела вопрос - а как в подходящий момент получить управление чтобы сделать выбор меню enabled/disabled в зависимости от контекста? Напр. если у меня файл еще не открыт - то "Save" в меню должно быть greyed/disabled

Please "ткните носиком" на нужную страницу Assistant  Улыбающийся
Записан
twp
Гость
« Ответ #7 : Июня 23, 2011, 22:47 »

у борландов, насколько я помню, есть такая возможность. В Qt это не реализовано, так что все это нужно делать самому. Самое просто это сделать один метод или  слот типа updateStateActions и в нем устанавливать доступность/недоступность всего меню и дергать этот метод после некоторых операций
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #8 : Июня 23, 2011, 23:14 »

Ща сам с этим гемороюсь:) А ткните носом в доку дельфятников, может у них есть что-то приличное?
Записан
twp
Гость
« Ответ #9 : Июня 23, 2011, 23:54 »

в Делфи по идее вот это
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #10 : Июня 24, 2011, 02:54 »

в общем фигня, решается сигналом modifictionChanged(bool) в документе. Я думал там че-то умное...
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #11 : Июня 24, 2011, 09:32 »

в общем фигня, решается сигналом modifictionChanged(bool) в документе. Я думал там че-то умное...
это-то здесь причём Непонимающий
Записан

Qt 5.11/4.8.7 (X11/Win)
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #12 : Июня 24, 2011, 09:43 »

Через QAction::setData() вешаем на элемент меню указатель на клиента:
Код
C++ (Qt)
Q_DECLARE_METATYPE(QWidget*)
QAction* a = menu.addAction( ... );
a->setData( QVariant::fromValue( clientWidget ) );
 

и уже в слоте получаем clientWidget:
Код
C++ (Qt)
QAction* a = qobject_cast< QAction* >( sender() );
QWidget* clientWidget = a->data().value< QWidget* >();
Записан

Qt 5.11/4.8.7 (X11/Win)
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #13 : Июня 24, 2011, 10:04 »

По ходу дела вопрос - а как в подходящий момент получить управление чтобы сделать выбор меню enabled/disabled в зависимости от контекста? Напр. если у меня файл еще не открыт - то "Save" в меню должно быть greyed/disabled
Поисследовав исходники троллей понял, что QMenu они считают довольно-таки лёгким ресурсом и создают его только при нажатии на правую кнопку.
Поэтому заполнять само контекстное меню, "серить" его элементы и "исполнять" можно довольно-таки просто и линейно:
Код
C++ (Qt)
QMenu menu;
QAction* a = 0;
QMap< int, QAction* > al;
enum { Item1, Item2, ..., ItemN };
bool item_is_enabled = true;
 
al[Item1] = a = menu.addAction( tr( "Item 1" ) );
a->setEnabled( item_is_enabled );
...
if( a )
 menu.addSeparator();
 
al[ItemN] = a = menu.addAction( tr( "Item N" ) );
a->setEnabled( !item_is_enabled );
 
...
 
switch( al.key( menu.exec( QCursor::pos() ),  -1 ) )
{
case Item1:
break;
...
case ItemN:
break;
}
 
Записан

Qt 5.11/4.8.7 (X11/Win)
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #14 : Июня 24, 2011, 12:00 »

спасибо, буду пробовать!
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.046 секунд. Запросов: 20.