медленный отклик контекстного меню правой кнопкой мыши в графической сцене Qt - PullRequest
0 голосов
/ 07 июня 2018

Я установил большое меню в фильтре событий по щелчку правой кнопкой мыши с 45-50 действиями внутри, и я обнаружил, что когда я щелкаю правой кнопкой мыши ответ, чтобы показать, что меню медленное, я пробовал тот же код с 5 действиями в меню иответ был в порядке.Что-то не так с этим способом кодирования в контекстном меню?

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

Ответы [ 2 ]

0 голосов
/ 07 июня 2018

Вместо создания нового QMenu каждый раз, когда вы вызываете showContextMenu, вы можете сделать его членом класса и создать его один раз.С другой стороны, нет необходимости использовать сигнал, вы можете просто использовать exec() метод 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);
}
0 голосов
/ 07 июня 2018

Есть две вещи, которые вы можете сделать для повышения скорости:

1 - itemAt (pos) является дорогостоящим, и вы делаете это дважды, один в событии и один в showContextMenu.Из того, что я понял из вашего кода, вам не нужен элемент в событии, только в showMenu.

2 - Создание меню, которое вы делаете, стоит дорого: все действия имеют растровые изображения.это выделяет память для QPixmap, загружает, выполняет, создает дампы.Поскольку вы сказали нам, что вы используете около 40 действий (и действительно, это слишком много для меню), это может дорого обойтись.

Мой совет: создайте класс для своего меню, создайте один экземпляр этого, добавьте установщик для текущего QGraphicsObject, над которым будет работать ваше меню, и всегда используйте этот один экземпляр.

...