图形场景Qt中右键单击上下文菜单响应缓慢

Posted

技术标签:

【中文标题】图形场景Qt中右键单击上下文菜单响应缓慢【英文标题】:slow response on right click contex menu in graphic scene Qt 【发布时间】:2018-06-07 05:44:10 【问题描述】:

我在右键单击事件过滤器中设置了一个大菜单,包含 45-50 个操作 在里面,我发现当我右键单击显示菜单的响应时很慢 我确实在菜单中尝试了具有 5 个操作的相同代码,并且响应很好。 这种在上下文菜单上编码的方式有什么问题吗?

事件过滤器

 bool Editor::eventFilter(QObject *o, QEvent *e)
  
  Q_UNUSED (o);
 QGraphicsSceneMouseEvent *me = (QGraphicsSceneMouseEvent*) e;
 switch ((int) e->type())

  case QEvent::GraphicsSceneMousePress:
     switch ((int) me->button())
         case Qt::RightButton:
           QGraphicsItem *item = itemAt(me->scenePos());
           showContextMenu(item->scenePos().toPoint());
           return true;
         
        //more cases here//
     
    break;
   
  
  return QObject::eventFilter(o, e);
 

showContextMenu

 void Editor::showContextMenu(const QPoint &pos)
 
 QGraphicsItem *item =itemAt(pos);
 // Create main effe menu
 effeMenu= new QMenu("Menu");
 QString  menuStyle(
           "QMenu "
           "border:10px ;"
             //more code here
            );

effeMenu->setStyleSheet(menuStyle);

AmpMenu=effeMenu->addMenu(QIcon(":/effectImg/img/effePng/amp.png"),"Amp");
Amp1 =AmpMenu->addAction(QIcon(":/effectImg/img/effePng/amp.png"),"Amp 1");
Amp2 =AmpMenu->addAction(QIcon(":/effectImg/img/effePng/amp.png"),"Amp 2");
CabMenu=effeMenu->addMenu(QIcon(":/effectImg/img/effePng/cab.png"),"Cab");
Cab1 =CabMenu->addAction(QIcon(":/effectImg/img/effePng/cab.png"),"Cab 1");
Cab2 =CabMenu->addAction(QIcon(":/effectImg/img/effePng/cab.png"),"Cab 2"); 
.
.
.
.
//45 actions more
 connect(effeMenu, &QMenu::triggered,this,[this,&item](QAction * k)
 menuSelection(k,item);
 );

【问题讨论】:

为什么不做QMenu类的成员,创建一次,这样可以节省资源。 你能给我一个小例子吗? 【参考方案1】:

不用每次调用showContextMenu 时都创建一个新的QMenu,您可以将其设为类的成员并构建一次。另一方面,不需要使用信号,您可以简单地使用QMenuexec() 方法:

*.h

class Editor: ...
   ...
private:
   QMenu effeMenu;

*.cpp

Editor::Editor(...)

   effeMenu.setTitle("Menu");
   QString  menuStyle(
           "QMenu "
           "border:10px ;"
             //more code here
            );

    effeMenu.setStyleSheet(menuStyle);

    AmpMenu=effeMenu.addMenu(QIcon(":/effectImg/img/effePng/amp.png"),"Amp");
    Amp1 =AmpMenu->addAction(QIcon(":/effectImg/img/effePng/amp.png"),"Amp 1");
    Amp2 =AmpMenu->addAction(QIcon(":/effectImg/img/effePng/amp.png"),"Amp 2");
    CabMenu=effeMenu.addMenu(QIcon(":/effectImg/img/effePng/cab.png"),"Cab");
    Cab1 =CabMenu->addAction(QIcon(":/effectImg/img/effePng/cab.png"),"Cab 1");
    Cab2 =CabMenu->addAction(QIcon(":/effectImg/img/effePng/cab.png"),"Cab 2"); 
    ...


void Editor::showContextMenu(const QPoint &pos)
     QGraphicsItem *item =itemAt(pos);
     QAction *action = menu.exec(pos);
     menuSelection(action, item);

【讨论】:

【参考方案2】:

您可以做两件事来提高速度:

1 - itemAt(pos) 代价高昂,您要执行两次,一次在事件中,一次在 showContextMenu 中。根据我从您的代码中了解到的情况,您不需要事件中的项目,只需在 showMenu 中即可。

2 - 您所做的菜单创建成本很高:所有操作都有像素图。这会为 QPixmap、加载、执行、转储分配内存。因为您告诉我们您使用了大约 40 个操作(实际上,这对于一个菜单来说太多了),这可能会变得很昂贵。

我的建议: 为您的菜单创建一个类,创建它的 一个 实例,为您的菜单将处理的当前 QGraphicsObject 添加一个设置器,并始终使用该实例。

【讨论】:

以上是关于图形场景Qt中右键单击上下文菜单响应缓慢的主要内容,如果未能解决你的问题,请参考以下文章

在java中右键单击上下文菜单获取目标名称div变量

闪亮:在numericInput中右键单击提供上下文菜单?

如何保证我获得用户在 CTreeControl 中右键单击的项目的“HTREEITEM”

Delphi在Windows资源管理器中右键单击添加菜单项

单击上下文菜单项后验证当前 URL

在IE8中右键单击取消选择文本