如何在 Qt 中使用 eventFilter 创建鼠标右键单击菜单选项?
How to create Mouse right click menu option using eventFilter in Qt?
我有一个 QGraphicsView
,其中包含许多 QGraphicsItem
。如果我单击鼠标右键单击任何 QGraphicsItem
,该项目应该得到 select 并且应该出现正确的菜单选项,然后我将选择 them.To 中的选项之一,我已经安装了 eventFilter
并通过它,我使用 ContextMenu
创建右键菜单。右键单击菜单已正确创建。但问题是我不知道如何将它们连接到某个函数,以便我可以为其编写逻辑。
这意味着如果我单击 save
选项,特定的 QGraphicsItem
应该得到 select 并且我应该能够转到某个函数,我将在其中编写用于保存的逻辑。
bool myClass::eventFilter(QObject *watched, QEvent *event)
{
switch(event->type())
{
case QEvent::ContextMenu:
{
QMouseEvent *mouseEvent = static_cast<QMouseEvent*> (event);
menu = new QMenu(this);
option = menu->addMenu("CopyOption");
option->addAction("save");
menu->exec(mouseEvent->globalPos());
break;
}
default:
break;
}
}
在您的方法中,当您不知道是否选择了任何项目时,您会显示一个上下文菜单。这是个坏主意。您不想在任何视图位置显示上下文菜单。您必须检查鼠标光标是否在某个项目上。
为什么不派生自 QGraphicsItem
而只是重载 mousePressEvent
方法。在此方法中检查是否单击了鼠标右键。如果是这样,显示上下文菜单并测试单击了哪个操作。最小代码为:
class TItem : public QGraphicsItem
{
bool _selected = false;
public:
TItem(QGraphicsItem* parent = nullptr) : QGraphicsItem(parent) {}
QRectF boundingRect() const override { return QRectF(0,0,20,20); }
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override {
painter->fillRect(QRectF(0,0,20,20),_selected ? QColor(0,255,255) : QColor(255,255,0));
}
void mousePressEvent(QGraphicsSceneMouseEvent* e) override {
QGraphicsItem::mousePressEvent(e);
if (e->button() & Qt::RightButton) {
QMenu menu;
QAction* a1 = menu.addAction(QString("test1"));
QAction* a2 = menu.addAction(QString("test2"));
if(a2 == menu.exec(e->screenPos())) {
test2();
_selected = true;
update();
}
}
}
void test2() {
QMessageBox::information(nullptr,"test2","test2");
}
};
所有检查鼠标下的项目的工作都是由 QT 完成的,mousePressEvent
仅在必要时调用。
另一种方法是覆盖 QGraphicsView 上的 mousePressEvent
。其中:
- 获取属于场景的所有物品
- 遍历它们,检查一个项目是否在鼠标下 ->
QGraphicsItem
有 isUnderMouse
方法
- 如果任何项目在鼠标下,创建
QMenu
并显示它
- 检查选中的
QAction
,如果是 save
调用正确的方法进行保存并将项目标记为选中
我有一个 QGraphicsView
,其中包含许多 QGraphicsItem
。如果我单击鼠标右键单击任何 QGraphicsItem
,该项目应该得到 select 并且应该出现正确的菜单选项,然后我将选择 them.To 中的选项之一,我已经安装了 eventFilter
并通过它,我使用 ContextMenu
创建右键菜单。右键单击菜单已正确创建。但问题是我不知道如何将它们连接到某个函数,以便我可以为其编写逻辑。
这意味着如果我单击 save
选项,特定的 QGraphicsItem
应该得到 select 并且我应该能够转到某个函数,我将在其中编写用于保存的逻辑。
bool myClass::eventFilter(QObject *watched, QEvent *event)
{
switch(event->type())
{
case QEvent::ContextMenu:
{
QMouseEvent *mouseEvent = static_cast<QMouseEvent*> (event);
menu = new QMenu(this);
option = menu->addMenu("CopyOption");
option->addAction("save");
menu->exec(mouseEvent->globalPos());
break;
}
default:
break;
}
}
在您的方法中,当您不知道是否选择了任何项目时,您会显示一个上下文菜单。这是个坏主意。您不想在任何视图位置显示上下文菜单。您必须检查鼠标光标是否在某个项目上。
为什么不派生自 QGraphicsItem
而只是重载 mousePressEvent
方法。在此方法中检查是否单击了鼠标右键。如果是这样,显示上下文菜单并测试单击了哪个操作。最小代码为:
class TItem : public QGraphicsItem
{
bool _selected = false;
public:
TItem(QGraphicsItem* parent = nullptr) : QGraphicsItem(parent) {}
QRectF boundingRect() const override { return QRectF(0,0,20,20); }
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override {
painter->fillRect(QRectF(0,0,20,20),_selected ? QColor(0,255,255) : QColor(255,255,0));
}
void mousePressEvent(QGraphicsSceneMouseEvent* e) override {
QGraphicsItem::mousePressEvent(e);
if (e->button() & Qt::RightButton) {
QMenu menu;
QAction* a1 = menu.addAction(QString("test1"));
QAction* a2 = menu.addAction(QString("test2"));
if(a2 == menu.exec(e->screenPos())) {
test2();
_selected = true;
update();
}
}
}
void test2() {
QMessageBox::information(nullptr,"test2","test2");
}
};
所有检查鼠标下的项目的工作都是由 QT 完成的,mousePressEvent
仅在必要时调用。
另一种方法是覆盖 QGraphicsView 上的 mousePressEvent
。其中:
- 获取属于场景的所有物品
- 遍历它们,检查一个项目是否在鼠标下 ->
QGraphicsItem
有isUnderMouse
方法 - 如果任何项目在鼠标下,创建
QMenu
并显示它 - 检查选中的
QAction
,如果是save
调用正确的方法进行保存并将项目标记为选中