如何使用QT中的EventFilter单击菜单选项右键单击菜单选项?

发布于 2025-01-18 11:59:11 字数 817 浏览 7 评论 0原文

我有一个qgraphicsview,其中包含许多qgraphicsItem。如果我单击鼠标右键单击任何qgraphicSitem,则该项目应获得选择和正确的菜单选项,然后我将选择其中一个选项。 通过它,我使用contextMenu右键单击菜单。右键单击菜单正在正确地进行。但是,我没有得到如何将它们连接到某种功能的方法,以便我可以为其编写逻辑。

这意味着,如果我单击保存选项,特定的qgraphicsItem应该选择,我应该能够转到某个功能,我将写逻辑以保存。

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;
   }
}

I have a QGraphicsView which contains many QGraphicsItem. If I click mouse right click on any QGraphicsItem, the item should get select and right menu options should appear and then I will choose one of the options among them.To do that I have installed eventFilter and through it, I am using ContextMenu to create right click menu. Right click menu are getting cretaed properly. But propblem is I am not getting how to connect them to some function so that I can write logic for it.

It means if I clicked on save option that particular QGraphicsItem should get select and I should be able to go to some function where I will write logic for saving.

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;
   }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

审判长 2025-01-25 11:59:11

在您的方法中,当您没有选择任何项目时,您将显示上下文菜单。这是相当糟糕的主意。您不想在视图的任何位置显示上下文菜单。您必须检查光标鼠标是否在项目上。

为什么不从qgraphicsItem派生,而Orderload 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. 迭代在它们上面迭代,检查一个项目是否在鼠标下方 - &gt; qgraphicSitem具有iSunderMouse方法
  3. ,如果有任何项目在鼠标下,请创建qmenu并显示其
  4. 选中qaction,如果是保存调用做保存并标记为选定的项目的正确方法

In your approach you show a context menu when you have no information if any item is selected. It is rather bad idea. You don't want to show the context menu in any location of view. You have to check if a cursor mouse is over an item.

Why not to derive from QGraphicsItem and just overload mousePressEvent method. Inside this method check if right button of mouse is clicked. If so, show context menu and test which action is clicked. Minimal code would be:

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");
    }
};

All the job with checking is an item is under mouse is done by QT, mousePressEvent is invoked only if it is necessary.


Another approach would be override mousePressEvent on QGraphicsView. Inside which:

  1. get all items belonging to the scene
  2. iterate over them, checking if an item is under mouse -> QGraphicsItem has isUnderMouse method
  3. if any item is under mouse, create QMenu and show it
  4. check selected QAction, if it is save call a proper method which doing the save and mark the item as selected
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文