Qt中使用eventFilter的鼠标右键单击选项
Mouse right click option using eventFilter in Qt
我有 QGraphicsView,它有很多 QGraphicsItem。我正在尝试在这些 QGraphicsItem 上创建右键单击菜单。右键单击菜单有多个选项。但只有第一个选项有效。这意味着,如果我点击第二个选项,它不起作用。如果我改变顺序(意味着第一个会到第二个位置,第二个会到第一个位置)那么第二个仍然不起作用。
bool myClass::eventFilter(QObject *watched, QEvent *event)
{
switch(event->type())
{
case QEvent::ContextMenu:
{
foreach(QGraphicsItem* pItem, _scene->items())
{
if(pItem->isUnderMouse())
{
QMouseEvent *mouseEvent = static_cast<QMouseEvent*> (event);
menu = new QMenu(this);
myMenu = menu->addMenu("Copy");
myMenu ->addAction(Name);
myMenu ->addAction(Address);
if(Name == menu->exec(mouseEvent->globalPos()))
{
// logic
}
if(Address == menu->exec(mouseEvent->globalPos()))
{
// logic
}
}
}
}
}
始终仅适用于第一个鼠标右键单击选项。为什么会这样?
执行此类操作的通常方法是覆盖项目 class 的 QGraphicsItem::mouseReleaseEvent()
或 QGraphicsItem::mousePressEvent()
功能。
这样,您无需执行任何操作(无需循环等...),它已由事件循环处理。
在这里你可以找到一个简单的例子:
void MyItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * event)
{
if(event->button() == Qt::RightButton)
{
QMenu my_menu;
// Build your QMenu the way you want
my_menu.addAction(my_first_action);
my_menu.addAction(my_second_action);
//...
my_menu.exec(event->globalPos());
}
}
Note that all signals are emitted as usual. If you connect a QAction to a slot and call the menu's exec(), you get the result both via the signal-slot connection and in the return value of exec().
您只需要 QObject::connect()
您添加到上下文菜单的 QAction
到适当的位置(这里是“逻辑”),工作就完成了。
如果您更喜欢自己检查返回值,您只需一劳永逸地获取返回的 QAction*
(只调用一次 QMenu::exec()
)并在其上进行分支。
例如:
void MyItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * event)
{
if(event->button() == Qt::RightButton)
{
QMenu my_menu;
// Build your QMenu the way you want
my_menu.addAction(my_first_action);
my_menu.addAction(my_second_action);
//...
QAction * triggered = my_menu.exec(event->globalPos());
if(triggered == my_first_action)
{
// Do something
}
else if(triggered == my_second_action)
{
// Do some other thing
}
//...
}
}
我个人更愿意坚持使用 signal-slot 连接而不是手动处理返回值,特别是因为每个 QAction
很可能已经连接到其相应的插槽。
我有 QGraphicsView,它有很多 QGraphicsItem。我正在尝试在这些 QGraphicsItem 上创建右键单击菜单。右键单击菜单有多个选项。但只有第一个选项有效。这意味着,如果我点击第二个选项,它不起作用。如果我改变顺序(意味着第一个会到第二个位置,第二个会到第一个位置)那么第二个仍然不起作用。
bool myClass::eventFilter(QObject *watched, QEvent *event)
{
switch(event->type())
{
case QEvent::ContextMenu:
{
foreach(QGraphicsItem* pItem, _scene->items())
{
if(pItem->isUnderMouse())
{
QMouseEvent *mouseEvent = static_cast<QMouseEvent*> (event);
menu = new QMenu(this);
myMenu = menu->addMenu("Copy");
myMenu ->addAction(Name);
myMenu ->addAction(Address);
if(Name == menu->exec(mouseEvent->globalPos()))
{
// logic
}
if(Address == menu->exec(mouseEvent->globalPos()))
{
// logic
}
}
}
}
}
始终仅适用于第一个鼠标右键单击选项。为什么会这样?
执行此类操作的通常方法是覆盖项目 class 的 QGraphicsItem::mouseReleaseEvent()
或 QGraphicsItem::mousePressEvent()
功能。
这样,您无需执行任何操作(无需循环等...),它已由事件循环处理。
在这里你可以找到一个简单的例子:
void MyItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * event)
{
if(event->button() == Qt::RightButton)
{
QMenu my_menu;
// Build your QMenu the way you want
my_menu.addAction(my_first_action);
my_menu.addAction(my_second_action);
//...
my_menu.exec(event->globalPos());
}
}
Note that all signals are emitted as usual. If you connect a QAction to a slot and call the menu's exec(), you get the result both via the signal-slot connection and in the return value of exec().
您只需要 QObject::connect()
您添加到上下文菜单的 QAction
到适当的位置(这里是“逻辑”),工作就完成了。
如果您更喜欢自己检查返回值,您只需一劳永逸地获取返回的 QAction*
(只调用一次 QMenu::exec()
)并在其上进行分支。
例如:
void MyItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * event)
{
if(event->button() == Qt::RightButton)
{
QMenu my_menu;
// Build your QMenu the way you want
my_menu.addAction(my_first_action);
my_menu.addAction(my_second_action);
//...
QAction * triggered = my_menu.exec(event->globalPos());
if(triggered == my_first_action)
{
// Do something
}
else if(triggered == my_second_action)
{
// Do some other thing
}
//...
}
}
我个人更愿意坚持使用 signal-slot 连接而不是手动处理返回值,特别是因为每个 QAction
很可能已经连接到其相应的插槽。