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


Автор: kuvshinka 19.3.2010, 10:35
привет всем знатокам кути!!!
подскажите плиз как программно реализовать всплывающее меню на кнопке (появляется по щелчку на кнопке около нее) с несколькими подменю (с возможностью простановки галочки у выбранного подменю)?
Типа того:
кнопка1->меню1
                     ->подменю1
                     ->подменю2
              ->меню2
                      ->подменю1
              ->меню3
                      ->подменю1
                      ->подменю2
                      ->подменю3

и как задавать обработчики событий для этих подменюшек?

Автор: SABROG 19.3.2010, 13:36
Всё еще не читаешь документацию?

http://doc.trolltech.com/4.6/qpushbutton.html#setMenu

Автор: kuvshinka 20.3.2010, 00:35
а примерчик ?
 неужели всплывающие меню делаются через QMenu? я думала есть что-нить типа QPopupMenu...

Автор: SABROG 20.3.2010, 00:47
http://qt.nokia.com/doc/4.6/widgets-groupbox.html

$QTDIR/examples/widgets/groupbox

Автор: djamshud 20.3.2010, 00:48
Создавайте QMenu, забивайте ее как заблагорассудится, связывайте сигналы забитых в него QAction-ов с вашими обработчиками, вызывайте на кнопке setMenu и наслаждайтесь. Как забивать менюшку есть в разделе ассистента, посвященном QMenu.

Поддерживаю предыдущего оратора.  Милая барышня, читайте документацию, там все есть и даже примеры.

Автор: kuvshinka 20.3.2010, 01:15
 допустим меню такое:
Код

QMenu *menu = new QMenu(this);
    menu->addAction("m1");
    menu->addAction("m2");
    ui->my_button->setMenu(menu);


    QAction *my_Action = menu->addAction("m3");
    QMenu *subMenu = new QMenu("Popup Submenu");
    subMenu->addAction("Item 1");
    subMenu->addAction("Item 2");
    my_Action->setMenu(subMenu);


так как же мне все-таки сделать обработчики для Item 1 и Item 2 по клику на них мышкой с установкой галки у выбранного подменю?
и можно ли сделать этот список менюшек выпадающим, допустим, справа или слева от кнопки (не вниз)?

Автор: SABROG 20.3.2010, 15:44
Цитата(kuvshinka @  20.3.2010,  01:15 Найти цитируемый пост)
и можно ли сделать этот список менюшек выпадающим, допустим, справа или слева от кнопки (не вниз)?

Не вызывать setMenu(), а на нажатие вызывать статический метод QMenu::exec() передав нужный координаты.

Цитата(kuvshinka @  20.3.2010,  01:15 Найти цитируемый пост)
так как же мне все-таки сделать обработчики для Item 1 и Item 2 по клику на них мышкой с установкой галки у выбранного подменю?

Читайте описание класса QAction.

Автор: kuvshinka 20.3.2010, 19:17
 smile : 

1. подскажите пож-та какие параметры надо задавать вместо ??? (по описанию exec первый параметр нада задать какой-то action - но мне то надо все меню menu...):
Код

menu->exec( ???, QPoint( ui->my_button->geometry().x+ui->my_button->geometry().width(),
                                          ui->my_button->geometry().y
                 ???,???
               )

2.  так как же все-таки программно добраться до пунктов подменю Item 1 и Item 2, если указатель есть только на само меню m3? для коннекта какой надо использовать сигнал - changed ? 
и желательно иметь возможность работать с менюшками Item 1 и Item 2 как с массивом (потому как каждое из этих меню (их будет поболее, чем два) является выбираемым пользователем неким значением)...
дайте примерчик пож-та - по примеру намного быстрее можно разобраться что к чему......

Автор: kuvshinka 21.3.2010, 00:13
уже устала тыкаться с этими менюшками...вот например в билдере - взял компонент MainMenu, а лучше PopupMenu, вручную сформировал его состав, щелкнул по нужному пункту меню и получил его обработчик событий....а в кути....подскажите пож-та примером (см. сообщение выше)...

Автор: kuvshinka 21.3.2010, 18:49
с меню вроде разобралась:
Код

    QMenu *menu = new QMenu();
    QAction *m1 =  menu->addAction("меню1");
   
     QMenu *subMenu = new QMenu();
     QAction *sbm1= subMenu->addAction("10");
     QAction *sbm2= subMenu->addAction("15");
     QAction *sbm3= subMenu->addAction("27");
     QAction *sbm4= subMenu->addAction("48");
     QAction *sbm5= subMenu->addAction("64");
     m1->setMenu(subMenu);
     ui->my_button->setMenu(menu);

это все верно получилось...
вопрос теперь в следующем: каким оптимальным образом можно получить значение (записать его в переменную, например perem) выбранного пункта "10" (perem=10), "15" (perem=15), "27", "48" или "64" меню "меню1"? 

можно конечно так
Код

connect(sbm1, SIGNAL(triggered(bool)), this, SLOT(my_sl())); 


void ...::my_sl()
{
  perem=10;
}



но тогда придется делать аж 5 коннектов (для каждого sbm_i) и 5 своих слотов....что не есть хорошо и оптимально...

пробовала через QActionGroup:
 
Код

QActionGroup *gr1;
gr1 = new QActionGroup(this);
gr1->addAction(sbm1);
gr1->addAction(sbm2);
gr1->addAction(sbm3);
gr1->addAction(sbm4);
gr1->addAction(sbm5);

а какой будет тогда коннект?
то есть желательно все сделать через один слот, но как тогда узнать какой именно пункт меню (sbm1... sbm5) был выбран?
подскажите пож-та программную реализацию этого действия...

и еще по поводу
 
Код

menu->exec(какие параметры (особенно первый)???)













Автор: kuvshinka 21.3.2010, 22:34
неужели никто не работал с QActionGroup и методом exec у QMenu? подскажите как с ними правильно работать...

Автор: kuvshinka 22.3.2010, 19:38
товарищи, ну подскажите как с этими QActionGroup и QMenu.exec правильно управляться... см. мое пред-предыдущее сообщение...

Автор: SABROG 23.3.2010, 22:07
Цитата(kuvshinka @  21.3.2010,  18:49 Найти цитируемый пост)
каким оптимальным образом можно получить значение (записать его в переменную, например perem) выбранного пункта "10" (perem=10), "15" (perem=15), "27", "48" или "64" меню "меню1"? 

void QAction::setData ( const QVariant & userData  )

Код

QAction* sbm1= subMenu->addAction("10");
sbm1->setData(10);


Цитата(kuvshinka @  21.3.2010,  18:49 Найти цитируемый пост)
но тогда придется делать аж 5 коннектов (для каждого sbm_i) и 5 своих слотов....что не есть хорошо и оптимально...

Код

QObject::connect(actionGroup, SIGNAL(triggered(QAction*)), this, SLOT(mySlot(QAction*)));
...
void MyWidget::mySlot(QAction* action)
{
    if (action->isChecked()) {
        int per = action->data().toInt();
    }
    else {
        // do if unchecked or ignore
    }
}


Цитата(kuvshinka @  21.3.2010,  18:49 Найти цитируемый пост)
menu->exec(какие параметры (особенно первый)???)


Код

QPushButton* btn = ui->pushButton;
QPoint rightPos(btn->rect().topRight());
rightPos = btn->mapToGlobal(rightPos);
int desktopWidth = QApplication::desktop()->availableGeometry(btn).width();
if (rightPos.x() + menu->width() >= desktopWidth)
    rightPos.rx() = desktopWidth - menu->width();
menu->exec(rightPos);

Автор: kuvshinka 24.3.2010, 15:07
SABROG : спасибочки бальшое...теперь буду знать...
а каким образом можно в цикле добавить ку-экшены к меню
Код

 QAction *sbm1= subMenu->addAction("10");
 QAction *sbm2= subMenu->addAction("15");
....

 
а затем уже их (тоже в цикле) добавить к action-группе:
Код

QActionGroup *gr1;
gr1 = new QActionGroup(this);
gr1->addAction(sbm1);
gr2->addAction(sbm2);
...

а то прописывать действия для каждого объекта - как-то не очень хорошо....

Автор: SABROG 24.3.2010, 16:33
Цитата(kuvshinka @  24.3.2010,  15:07 Найти цитируемый пост)
а каким образом можно в цикле добавить ку-экшены к меню

Код

QActionGroup* gr1 = new QActionGroup(this);
for (int i = 0; i < 15; ++i) {
    QAction* act = subMenu->addAction(QString::number(i));
    act->setData(i);
    gr1->addAction(act);
}

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