Search code examples
c++qtqt5qgraphicsviewqgraphicsscene

slow response on right click contex menu in graphic scene Qt


I have set a large menu in event filter on right click with 45-50 actions inside and I find that when I right click the response to show the menu is slow I did try the same code with 5 actions in the menu and the response was fine. Is there something wrong with this way of coding on a contex menu ?

eventFilter

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

Solution

  • Instead of creating a new QMenu each time you call showContextMenu you could make it a member of the class and build it once. On the other hand it is not necessary to use a signal, you could simply use the exec() method of QMenu:

    *.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);
    }