Search code examples
c++qtqt4signals-slots

Is there a way to know what activated QAction?


I have created instance of QAction inside QGraphicsView child class and connected it to my slot in the same class.

QAction *action   = new QAction(tr("New"), this);
action->setObjectName("addStopAction");
action->setShortcut(QKeySequence(Qt::ControlModifier | Qt::Key_N));
connect(action, SIGNAL(triggered()), this, SLOT(addNew()));
addAction(action);

Slot is a function creating new instance of QGraphicsItem on scene assigned to QGraphicsView.

void MyGraphicsView::addNew() {
    // Insert new item at cursor position
}

I also add this action to a QMenu which serves as my class context menu.

QMenu *contextMenu = new QMenu(this);
contextMenu->addAction(action);

Everything works fine. When I press Command/Ctrl + N new item is created at cursor position. But when I right-click and select action from context menu I want new item to be created at menu positon.

I can, of course, do some little hack to flag if SLOT was called after contextMenuEvent or something like that, but what I would like to know is:

Is there any way to find out what made QAction emit its triggered() signal inside connected SLOT? That way I could handle when I should place new item at cursor position and when at context menu position inside SLOT implementation.


Solution

  • I think you can use custom data that a QAction object can contain. You can set it when you create a context menu:

    void showContextMenu(const QPoint &pos)
    {
        ...
        action->setData(pos);
        ...
    }
    

    And in the addNew() function you check if data exists and reset it in the end:

    void addNew()
    {
        QPoint pos;
        QPoint posFromAction = action->data()->toPoint();
        if (posFromAction.isNull())
        {
            pos = QCursor::pos(); ///< pos will be current cursor's position
        }
        else
        {
            pos = posFromAction; ///< pos will be menu's position
        }
    
        doYourStuffAt(pos)
    
        action->setData(QPoint()); ///< reset action's data
    }