2

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用作我的类上下文菜单的 a 中。

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

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

当然,如果 SLOT 被调用contextMenuEvent或类似的东西,我可以做一些小技巧来标记,但我想知道的是:

有什么方法可以找出是什么在连接的 SLOT 内QAction发出信号?triggered()这样,当我应该将新项目放置在光标位置以及在 SLOT 实现内的上下文菜单位置时,我可以处理。

4

5 回答 5

4

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

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

void MyGraphicsView::addNew() {
    QAction* pAction = qobject_cast<QAction*>(sender());
    Q_ASSERT(pAction);
    // do something with pAction
}
于 2013-01-20T17:21:57.813 回答
1

我通过将菜单连接到类似的功能来管理类似的东西connect (menu, SIGNAL( triggered(QAction*) ), this, SLOT( menuAction_triggered(QAction*) ));

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

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

苏龙仔

于 2013-01-18T09:01:42.703 回答
1

我认为您可以使用 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
}
于 2013-01-18T12:43:36.003 回答
1

您可以在 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")

这有点小技巧,但是一种简单而可靠的方法可以知道您的操作是从哪个小部件调用的。

于 2020-02-19T00:36:24.073 回答
-1

您可能能够在接收呼叫的插槽中使用 QObject::sender() 。虽然没有尝试过这个动作。它可能比您提出的“hack”(您实际上可以使用作用域类很好地实现它)更难看。

于 2013-01-17T22:20:30.390 回答