Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > QMenu


Автор: Riviero 2.6.2016, 14:37
Создаётся QMenu в стиле:
Пункт 1,
Пункт 2
....
Пункт Х.
Как определить на какой нажали. Или как передать параметр от Action(а)?

Автор: baldman88 2.6.2016, 16:12
Пункты в меню добавляются двумя способами:
1. Прямое добавление QAction;
2. Создание QAction при добавлении пункта в меню.
В первом случае Вы создаете QAction и соединяете его сигнал (triggered) с нужным слотом.
Во втором случае QMenu возвращает созданный QAction, сигналы которого также соединяются с нужными слотами.
Получилось сумбурно. Вот пример:
Код

QMenu nemu;
QAction* foo = new QAction("foo");
menu.addAction(foo);
QAction* bar = menu.addAction("bar");
connect(foo, SIGNAL(triggered()), this, SLOT(fooFunc()));
connect(bar, SIGNAL(triggered()), this, SLOT(barFunc()));

Автор: Riviero 2.6.2016, 17:45
Цитата(baldman88 @  2.6.2016,  16:12 Найти цитируемый пост)
1. Прямое добавление QAction;
2. Создание QAction при добавлении пункта в меню.


А если мне заранее неизвестно, сколько будет пунктов в меню, как в таком случае быть?

Автор: baldman88 2.6.2016, 18:29
Цитата(Riviero @ 2.6.2016,  17:45)
Цитата(baldman88 @  2.6.2016,  16:12 Найти цитируемый пост)
1. Прямое добавление QAction;
2. Создание QAction при добавлении пункта в меню.


А если мне заранее неизвестно, сколько будет пунктов в меню, как в таком случае быть?

Лучше опишите более конкретно задачу. Чего Вы хотите добиться? А то как-то не очень понятно в чем именно проблема  smile 

Автор: ss 2.6.2016, 19:33
Цитата

А если мне заранее неизвестно, сколько будет пунктов в меню, как в таком случае быть?


делаешь функцию добавления пункта 
напр.
Код


QAction * addItem(ЗНАЧЕНИЕ НУЖНЫХ ПАРАМЕТРОВ)
{
   QAction *result = menu->addAction("ЗНАЧЕНИЕ НУЖНЫХ ПАРАМЕТРОВ");
   connect(result, SIGNAL(triggered()), this, SLOT( ОБРАБОТЧИК) )
return result;
}


и используешь ее в коде, где нужно добавить очередной пункт
addItem(ЗНАЧЕНИЕ НУЖНЫХ ПАРАМЕТРОВ);


или (ООП)

можно переопределить QAction.  и в методе Event (или свой метод написать) написать свой обработчик
тогда после вызова QAction *a = menu.exec(x,y) получим ссылку на объект со своим обработчиком.


Автор: Riviero 7.6.2016, 15:57
Цитата(baldman88 @  2.6.2016,  18:29 Найти цитируемый пост)
Лучше опишите более конкретно задачу. Чего Вы хотите добиться? А то как-то не очень понятно в чем именно проблема   


Пункты меню загружаются из БД, те мне надо знать в конечном итоге ID пункта меню, на который я нажал.

Код

   QAction *result = menu->addAction("ЗНАЧЕНИЕ НУЖНЫХ ПАРАМЕТРОВ");
   connect(result, SIGNAL(triggered()), this, SLOT( Вот тут должен быть слот, в который надо передать параметр (ы)) )

Автор: baldman88 7.6.2016, 16:22
Цитата(Riviero @ 7.6.2016,  15:57)
Цитата(baldman88 @  2.6.2016,  18:29 Найти цитируемый пост)
Лучше опишите более конкретно задачу. Чего Вы хотите добиться? А то как-то не очень понятно в чем именно проблема   


Пункты меню загружаются из БД, те мне надо знать в конечном итоге ID пункта меню, на который я нажал.

Код

   QAction *result = menu->addAction("ЗНАЧЕНИЕ НУЖНЫХ ПАРАМЕТРОВ");
   connect(result, SIGNAL(triggered()), this, SLOT( Вот тут должен быть слот, в который надо передать параметр (ы)) )

Это Вы что-то эдакое придумали ... Тогда можно попробовать сделать так:
Код

menu->addAction("ЗНАЧЕНИЕ НУЖНЫХ ПАРАМЕТРОВ");
connect(menu, SIGNAL(triggered(QAction*)), this, SLOT(someSlot(QAction*)));

В данном случае слот someSlot просто обертка, которая будет принимать в качестве параметра QAction, соответствующий нажатому пункту, и, исходя из "ЗНАЧЕНИЯ НУЖНЫХ ПАРАМЕТРОВ" (например text), вызывать соответствующую функцию. Что-то вроде:
Код

void MainWindow::someSlot(QAction* action)
{
    if (action->text() == "Do foo") {
        doFoo();
    } else if (action->text() == "Do bar") {
        doBar();
    }
}

Автор: Riviero 7.6.2016, 17:00
Цитата(baldman88 @  7.6.2016,  16:22 Найти цитируемый пост)


void MainWindow::someSlot(QAction* action)
{
    if (action->text() == "Do foo") {
        doFoo();
    } else if (action->text() == "Do bar") {
        doBar();
    }
}

Спасибо, то что надо.

Автор: borisbn 8.6.2016, 19:03
У QAction, как и у любого QObject есть http://doc.qt.io/qt-5/qobject.html#setProperty и http://doc.qt.io/qt-5/qobject.html#property.

Код
QAction *result = menu->addAction("Название пункта 1");
result->setProperty( "prop_name_1", int_value_1 );
result->setProperty( "prop_name_2", str_value_2 );
connect(menu, SIGNAL(triggered(QAction*)), this, SLOT(someSlot(QAction*)));

result = menu->addAction("Название пункта 2");
result->setProperty( "prop_name_1", int_value_3 );
result->setProperty( "prop_name_2", str_value_4 );
connect(menu, SIGNAL(triggered(QAction*)), this, SLOT(someSlot(QAction*)));

void MainWindow::someSlot(QAction* action)
{
    int int_value = action->property( "prop_name_1" ).toInt();
    QString str_value = action->property( "prop_name_2" ).toString();
    if ( условие с int_value ) {
        doFoo();
    } else if ( условие c str_value ) {
        doBar();
    }
}

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)