How to access dynamically created QMenu for tests purposes



  • Hi, I have a QwtPlot object and I'm providing a way to save the graph as an image.

    In the constructor, I'm defining this:

    qwtPlot->setContextMenuPolicy(Qt::CustomContextMenu);
    connect(qwtPlot, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(popUpMenu(QPoint)));
    

    Then, I have created the popUpMenu function:

    void MyClass::popUpMenu(QPoint pos)
    {
        QMenu menu;
        QAction* actionSave = menu.addAction(QIcon(":/prefix/SaveImageIcon.png"), tr("Save Image"));
        connect(actionSave, SIGNAL(triggered()), this, SLOT(saveAsImage()));
        menu.popup(pos);
        menu.exec(QCursor::pos());
    }
    

    And the saveAsImage function:

    void MyClass::saveAsImage()
    {
        if( qwtPlot->itemList().isEmpty() )
        {
            return;
        }
    
        saveWidgetAsImage(qwtPlot);
    }
    

    Now, I'm developing another Qt application to test this one. It accesses the MainWindow and all its widgets to test the graphical user interface.

    As I have access to the widgets I can emit the customContextMenuRequested signal as follows:

    emit qwtPlot->customContextMenuRequested(QPoint(10,10));
    

    It works and shows the QMenu, but now I want to access the QMenu to call the QAction responsible for saving the widget as an image. Is it possible? How can I do that?


  • Qt Champions 2016

    Hi
    Im not sure I understand.

    If you can call the
    qwtPlot->customContextMenuRequested(QPoint(10,10));
    wont it call void MyClass::popUpMenu(QPoint pos)
    that will show menu and the action already there , ready to call void MyClass::saveAsImage() when clicked?

    Also do you mean access to the local variable ?
    void MyClass::popUpMenu(QPoint pos)
    {
    QMenu menu; <<< this QMenu ?



  • @mrjj thanks.

    Yes, the popUpMenu is being called, and the QMenu is also being shown. Now I need to find a way to trigger the QAction (actionSave) programmatically.

    I think I found a workaround to do it. I will post it here.



  • The Qt documentation says:

    ...a popup menu is always a top-level widget, if a parent is passed the popup menu will be deleted when that parent is destroyed...
    

    So, I have added a parent for the QMenu and assigned an object name:

    QMenu *menu = new QMenu(this);
    menu->setObjectName("PopUpMenu");
    QAction* actionSave = menu->addAction(QIcon(":/prefix/SaveAsImageIcon.png"), tr("Save as image"));
    connect(actionSave, SIGNAL(triggered()), this, SLOT(saveAsImage()));
    menu->popup(pos);
    menu->exec(QCursor::pos());
    

    Now, I can search for the QMenu widget and find the correct menu using the objectName. Finding the QMenu I can trigger the action:

    QWidgetList allToplevelWidgets = QApplication::topLevelWidgets();
    foreach(QWidget *w, allToplevelWidgets)
    {
        if( w->inherits("QMenu") )
        {
            QMenu *menu = qobject_cast<QMenu *>(w);
            if( menu->objectName() == "PopUpMenu" )
            {
                menu->actions().at(0)->trigger();
                break;
            }
        }
    }
    

  • Qt Champions 2016

    Hi
    So the goal is to make it save image without user clicking the action?
    Ahh, i missed the testing part. So its do module test.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.