如何解决嵌套QGraphicsScenes中的选择排除
我有一个包含项目的QGraphicsScene(我们称之为母场景),其中一些还包含一个QGraphicsScene(我们将它们称为子场景)。
观察:子场景和母场景中的选择不会互相干扰。这意味着,如果我在母场景中选择一个项目,则可以在子场景中选择一个项目,而母场景中的项目将保持选中状态。
我的预期结果:我希望在一个场景中进行选择以清除其他任何场景中的选择。
[为清晰起见,进行编辑]当我在一个场景中选择一个项目时,我想取消选择其他场景中的所选项目,而不是在不同场景中具有多个焦点。
我的动力:我想这样做是因为当我使用键盘快捷键时,我不知道Qt将选择哪个场景。当我只有一个女儿时,就选择了母亲(我希望女儿)。
到目前为止我的解决方案:在子场景容器项中,mousepressEvent清除了母场景的选择。我发现此解决方案非常丑陋,我想知道是否有人知道使用某些内部Qt功能的更好解决方案。现在,它看起来像一个糟糕的DIY解决方案,将会带来很多问题。
提前谢谢!
[编辑:最小示例] 在此示例中,我们可以同时选择两个嵌套元素。我宁愿整个场景中一次只能选择一个。
#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QMainWindow>
#include <QGraphicsItem>
#include <QGraphicslinearLayout>
#include <QGraphicsWidget>
#include <QGraphicsProxyWidget>
// Item that gets red contour when selected
class SimpleItem : public QGraphicsItem
{
public :
SimpleItem():QGraphicsItem()
{
setFlag(QGraphicsItem::ItemIsSelectable,true);
}
QRectF boundingRect() const override { return QRectF(-20,-20,40,40);}
void paint(QPainter *painter,const qstyleOptionGraphicsItem *,QWidget *) override
{
painter->setPen(Qt::black);
if(isSelected())
painter->setPen(Qt::red);
painter->setBrush(Qt::gray);
painter->drawRect(boundingRect());
}
};
// Item that contains a QGraphicsScene in a layout
// This item gets also a red contour when selected
class SceneItem : public QGraphicsWidget
{
public :
SceneItem():QGraphicsWidget()
{
setFlag(QGraphicsItem::ItemIsSelectable,true);
setFocusPolicy(Qt::ClickFocus);
// Create the inner scene
QGraphicslinearLayout * layout = new QGraphicslinearLayout;
setLayout(layout);
QGraphicsScene * scene = new QGraphicsScene;
QGraphicsView * view = new QGraphicsView(scene);
QGraphicsProxyWidget * proxy = new QGraphicsProxyWidget;
layout->addItem(proxy);
proxy->setWidget(view);
// Add a simple item
SimpleItem * simpleItem = new SimpleItem;
scene->addItem(simpleItem);
}
QRectF boundingRect() const override { return QRectF(0,100,100);}
void paint(QPainter *painter,QWidget *) override
{
painter->setPen(Qt::black);
if(isSelected())
painter->setPen(Qt::red);
painter->setBrush(Qt::lightGray);
painter->drawRect(boundingRect());
}
};
// Main
int main(int argc,char *argv[])
{
QApplication a(argc,argv);
QMainWindow w;
QGraphicsScene * scene = new QGraphicsScene;
QGraphicsView * view = new QGraphicsView(scene);
view->setDragMode(QGraphicsView::RubberBandDrag);
w.setCentralWidget(view);
SceneItem * item = new SceneItem;
scene->addItem(item);
w.show();
return a.exec();
}
解决方法
Disclamer
我个人不建议将小部件嵌入QGraphicsScene:
“图形视图”高性能的关键在于减少每帧绘制的数量。 QGraphicsWidget和QGraphicsProxyWidget一起是巨大的性能杀手,因为它们不能以有效的方式呈现。
此引用的来源以及有关该主题的更多信息可在此博客文章中找到:
Should you still be using QGraphicsView?
解决方案
如果我必须不惜一切代价使用OP使用的确切方法,我的解决方案将是:
- 使用
QGraphicsScene::selectionChanged
对选择更改做出反应,并且 - 使用
QGraphicsScene::selectedItems
检查是否选择了一项。
示例
这是OP提供的MVCE,我对它进行了修改,以演示如何实现建议的解决方案:
MyWindow.Window_Closing
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。