Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Context menu QMenu not showing up when using popup(). Only showing on exec().



  • I've been doing research to solve this for a while now to no avail. I need to use the popup() function so I can highlight the first action on my context menu after it pops up, using setActiveAction(). I can't use exec() because it's synchronous and it won't let me call any more functions until the menu is closed (I might be wrong on this, but I haven't been able to think of any other way of doing it with exec()).

    It's all executed in an eventFilter method, so I figured that might be a potential factor contributing to this problem. What I'm trying to do is show a context menu on the bottom of the window when the user presses the down arrow or the enter key while focused on the last input widget that gives you the option to print the form. I'm using the whatsThis parameter to identify the last item.

    My code:

    bool MainWindow::eventFilter(QObject *obj, QEvent *event) {
        QWidget *arg = qobject_cast<QWidget *>(obj);
        if (event->type() == QEvent::KeyPress) {
            QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
            if(keyEvent->key() == Qt::Key_Up) {
                lineEditPrev(arg);
                return true;
            }
            else if(keyEvent->key() == Qt::Key_Down || keyEvent->key() == Qt::Key_Return) {
                lineEditNext(arg);
                if(arg->whatsThis() == "last") {
                    QMenu endMenu(this);
                    QAction *actionPrintCont = new QAction("Print and continue",this);
                    QAction *actionPrintExit = new QAction("Print and exit",this);
                    endMenu.addAction(actionPrintCont);
                    endMenu.addAction(actionPrintExit);
                    endMenu.setDefaultAction(actionPrintCont);
                    endMenu.setActiveAction(actionPrintCont);
                    //endMenu.exec(QPoint(MainWindow::x() + MainWindow::width() - endMenu.sizeHint().width(), MainWindow::y() + MainWindow::height() - endMenu.sizeHint().height()));
                    endMenu.popup(QCursor::pos(),actionImpCont);
                }
                return true;
            }
        }
        return QObject::eventFilter(obj, event);
    }
    

    The reason why the application works like this is because I'm attempting to recreate the workflow of an older DOS program so I'm trying to make it as precise as possible. This means that when the last input is completed, a menu has to pop up with the first option highlighted. Currently, with the ´´´exec()´´´ function, the menu pops up but has no highlighted options, so the user has to press the ENTER key once to highlight the first option. Only then, they can cycle through the menu list. This is what I'm trying to avoid.

    Thanks in advance!


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    You create your QMenu object on the stack hence it get destroyed at the end of the function. The call to exec is blocking, hence you see the menu.



  • Thank you @SGaist ! I figured it was something along those lines but couldn't put my finger on it.