0
votes

I am creating a GUI where user needs to interact using QGraphicsView. So what I am doing right now is, I created QGraphicsScene and assigned it to QGraphicsView.

There are supposed to be two layers for drawing: one static and one dynamic.

Static layer is supposed to have objects that are created once at startup while dynamic layer contains multiple items (may be hundred of them) and user will interact will dynamic layer objects.

Currently I am drawing both layers on same scene which creates some lag due to large number of objects being drawn.

So question: Is there any way to assign two or more QGraphicsScene to a QGraphicsView ?

1
I'm afraid that the Qt developers explicitly intended to have one scene per view. Can't you use dedicated QGraphicsItem instances instead to separate essential parts of your scene? AFAIK, scene graphs are usually designed with exploiting the hierarchy for minimal performance impact of changes in individual nodes. Alternatively, you may render the static scene into a pixmap and render the pixmap first "under" the dynamic part of scene. Bitblitting a pixmap may be much cheaper than re-rendering and earn the missing performance.Scheff's Cat
I thought of another of creating multiple Mat images using OpenCV, finally ORing all of them and put them on the scene. Haven't done that yet, is your solution same as this one?taimoor1990
May be I can use transparency graphicsEffect of qgraphicsitem for that purpose but I haven't tested it yet.taimoor1990

1 Answers

0
votes

One option might be to implement your own class derived from QGraphicsScene that can then render a second 'background' scene in its drawBackground override.

class graphics_scene: public QGraphicsScene {
  using super = QGraphicsScene;
public:
  using super::super;
  void set_background_scene (QGraphicsScene *background_scene)
    {
      m_background_scene = background_scene;
    }
protected:
  virtual void drawBackground (QPainter *painter, const QRectF &rect) override
    {
      if (m_background_scene) {
        m_background_scene->render(painter, rect, rect);
      }
    }
private:
  QGraphicsScene *m_background_scene = nullptr;
};

Then use as...

QGraphicsView view;

/*
 * fg is the 'dynamic' layer.
 */
graphics_scene fg;

/*
 * bg is the 'static' layer used as a background.
 */
QGraphicsScene bg;
bg.addText("Text Item 1")->setPos(50, 50);
bg.addText("Text Item 2")->setPos(250, 250);
fg.addText("Text Item 3")->setPos(50, 50);
fg.addText("Text Item 4")->setPos(350, 350);
view.setScene(&fg);
fg.set_background_scene(&bg);
view.show();

I've only performed basic testing but it appears to behave as expected. Not sure about any potential performance issues though.