2015-09-01 4 views
4

У меня довольно конкретная ситуация. Я хочу, чтобы поместить QAction в QToolbar и достичь следующее поведение:Как программно закрыть QMenu

  1. Checkable QAction с иконкой.
  2. Классическая стрелка на правой стороне, которая используется для отображения меню
  3. При нажатии на эту стрелку мой QDialog РЕКОМЕНДУЕМЫМ на экране вместо QMenu -как один

появляется Теперь я немного запутался с реализацией всех все это вместе.

На данный момент я создал QAction, добавив его на панель инструментов, а также создал пустой QMenu, потому что у меня не было понятия, как добавить «выпадающий список» в другую сторону.
Итак, я также подключил свой слот к QMenuaboutToShow() сигнал, и теперь я могу создать свой диалог и exec() он перед QMenu показывает. Но вот основная проблема: после того, как я сделал все с моим диалогом, нажмите кнопку OKQMenu, пытаясь появиться, но поскольку он пуст, он ничего не показывает, и дальнейшие действия становятся доступными только после того, как я щелкнул левой кнопкой мыши, чтобы «закрыть» это меню.

Есть ли способ заставить QMenu не показывать или могут наследовать от QMenu и reimplemnt его поведения (я попытался сделать такой трюк с exec()show()popup() методов QMenu после подклассов от него, но ни один из них не является когда появляется меню на экране)?

ответ

6

Вот решение, которое сработало для меня.

class QCustomMenu : public QMenu 
{ 
    Q_OBJECT 
public: 
    QCustomMenu(QObject *parent = 0):QMenu(parent){}; 
}; 

В коде:

QAction* myActionWithMenu = new QAction ("ActionText", toolbar); 
QCustomMenu* myMenu = new QCustomMenu(toolbar); 
connect(myMenu, SIGNAL(aboutToShow()), this, SLOT(execMyMenu())); 

execMyMenu() реализация:

void execMyMenu(){ 
    m_activeMenu = (QCustomMenu*)sender(); // m_activeMenu -- private member of your head class, needs to point to active custom menu 
    QMyDialog* dlg = new QMyDialog(); 
    // setup your dialog with needed information 
    dlg->exec(); 
    // handle return information 
    m_myTimer = startTimer(10); // m_myTimer -- private member of your head(MainWindow or smth like that) class 
} 

Теперь мы должны обрабатывать TimerEvent и закрываем меню:

void MyHeadClass::timerEvent(QTimerEvent *event) 
{ 
    // Check if it is our "empty"-menu timer 
    if (event->timerId()==m_myTimer) 
    { 
     m_activeMenu->close(); // closing empty menu 
     killTimer(m_myTimer); // deactivating timer 
     m_myTimer = 0;   // seting timer identifier to zero 
     m_activeMenu = NULL; // as well as active menu pointer to NULL 
    } 
} 

Он отлично работает на каждый платформу и делает то, что я хотел. Надеюсь, это помогло бы кому-то. Я потратил неделю, пытаясь найти это решение.

+1

У вас там утечка памяти. Вы должны вызывать 'QMenu (parent)' в инициализации вашего конструктора. –

+0

Спасибо большое! Я абсолютно забыл об этой вещи – tema

+0

@SaZ странные вещи, происходящие сейчас: в Windows это работает отлично, но в меню закрытия Linux-меню заставляет замолчать любую панель инструментов. Может быть, я что-то забыл? – tema

Смежные вопросы