我在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
在连接的插槽内发出triggered()
信号的原因?这样,当我应该将新项目放置在光标位置以及何时在SLOT实现中的上下文菜单位置时,我就可以进行处理。
我认为您可以使用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
}
当然,您可以找出连接的插槽中发出了什么信号。
只需使用QObject :: sender()。您的情况:
void MyGraphicsView::addNew() {
QAction* pAction = qobject_cast<QAction*>(sender());
Q_ASSERT(pAction);
// do something with pAction
}
我通过将菜单连接到connect (menu, SIGNAL( triggered(QAction*) ), this, SLOT( menuAction_triggered(QAction*) ));
之类的功能来管理相似的事物>
当执行上下文菜单时,QMenu::exec(QPoint)
将使您返回到该动作的指针,因此您可能不需要额外的功能/插槽。
您可以通过文本QAction::text()
来检查动作的名称,或者通过比较地址是否将指针存储在某处。
soo long zai
您可以在由customContextMenuRequested信号调用的函数中引用self.sender()。
您可以在接收呼叫的插槽中使用QObject :: sender()。虽然没有尝试此操作。它可能比您提议的“ hack”(在这里您实际上可以通过作用域类很好地实现)更难看。