图形场景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
,您可以将其设为类的成员并构建一次。另一方面,不需要使用信号,您可以简单地使用QMenu
的exec()
方法:
*.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中右键单击上下文菜单响应缓慢的主要内容,如果未能解决你的问题,请参考以下文章