有没有办法知道什么激活QAction?

时间:2013-01-17 22:10:57

标签: c++ qt qt4 signals-slots

我在QAction子类中创建了QGraphicsView的实例,并将其连接到同一类中的插槽。

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是在分配给QGraphicsItem的场景上创建QGraphicsView的新实例的函数。

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

我还将此操作添加到QMenu,作为我的班级上下文菜单。

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

一切正常。按下Command / Ctrl + N时,在光标位置创建新项目。但是当我右键单击并从上下文菜单中选择操作时,我希望在菜单位置创建新项目。

当然,如果在contextMenuEvent或类似之后调用SLOT,我可以做一些小的破解,但我想知道的是:

有没有办法找出让QAction在连接的SLOT内发出triggered()信号的原因?这样我可以处理何时应该在光标位置放置新项目以及何时在SLOT实现中的上下文菜单位置。

5 个答案:

答案 0 :(得分:2)

当然,你可以找出连接的SLOT内发出的信号。

只需使用QObject :: sender()。在你的情况下:

void MyGraphicsView::addNew() {
    QAction* pAction = qobject_cast<QAction*>(sender());
    Q_ASSERT(pAction);
    // do something with pAction
}

答案 1 :(得分:1)

我通过将菜单连接到connect (menu, SIGNAL( triggered(QAction*) ), this, SLOT( menuAction_triggered(QAction*) ));

等功能来管理类似的内容

执行上下文菜单时,QMenu::exec(QPoint)会返回指向操作的指针,因此您可能不需要额外的函数/插槽。

您可以使用文本QAction::text()检查操作的名称,或者您是否通过比较地址将指针存储在某处。

soo long zai

答案 2 :(得分:0)

您可以在接收呼叫的插槽中使用QObject :: sender()。虽然没有试过这个动作。它可能比你提出的&#39; hack&#39; (你可以用scoped类实际上很好地实现它。)

答案 3 :(得分:0)

我认为您可以使用QAction对象可以包含的自定义数据。 您可以在创建上下文菜单时进行设置:

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

addNew()函数中,您检查数据是否存在并在最后重置它:

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
}

答案 4 :(得分:0)

您可以在customContextMenuRequested信号调用的函数中引用self.sender()。

self.tree1.customContextMenuRequested.connect(self.menu1pop)  # rightclick menu signal

...

def menu1pop(self, pos):

    widget = self.sender()

    item = widget.itemAt(pos)
    if item is None: return            # only show contextmenu if on an item
    self.setProperty("mywidget", widget)  # pass current widget 
    self.menu1.popup(QCursor.pos())    # show menu at right click cursor position

self.sender()将返回您的窗口小部件对象,然后您可以在属性内设置窗口小部件对象。

然后,在调用动作函数时,您可以通过读取属性来调用小部件对象。

widget = self.property("mywidget")

这有点hack,但是一种简单可靠的方法来知道您的操作是从哪个窗口小部件调用的。