如何在 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。其中:

  1. 获取属于场景的所有物品
  2. 遍历它们,检查一个项目是否在鼠标下 -> QGraphicsItemisUnderMouse 方法
  3. 如果任何项目在鼠标下,创建 QMenu 并显示它
  4. 检查选中的 QAction,如果是 save 调用正确的方法进行保存并将项目标记为选中