Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QGridLayout only showing last grid occupied



  • I am working on an application that has 4 input cameras shown in a quad-split. I've implemented a QGLWidget (m_pGLWidget) and have a QGridLayout (ui.videoBox) attached to it with 2 rows and 2 columns. I add a QGraphicsView to each cell in the grid, but only the last grid that I add actually shows up. If I change the number of cells I populate, its always just the last one that shows up. Not sure what I'm doing wrong, any help would be appreciated. Both the QGraphicsView and QGraphicsScene are subclassed in my code, and my client wants to keep those proprietary, so hopefully you can make sense of this. Here's a snapshot of the code that I'm using. Inside the method setView(), I attach the view to the scene and set the rectangle within the QGLWidget that I will draw the video into.

    m_pGLWidget->makeCurrent();
    m_pScene.resize(m_numCams);
    m_pView.resize(m_numCams);
    for (int cam = 0; cam < m_numCams; cam++)
    {
        m_pScene[cam] = std::make_shared<QGraphicsScene>(...);
        m_pView[cam] = std::make_shared<QGraphicsView>(...);
        QRect *multiViewRect;
        int row, col;
        if (cam == 0)
        {
            multiViewRect = new QRect(0, 0, multiViewWidth, multiViewHeight);
            row = 0; col = 0;
        }
        else if (cam == 1)
        {
            multiViewRect = new QRect(multiViewWidth, 0, multiViewWidth, multiViewHeight);
            row = 0; col = 1;
        }
        else if (cam == 2)
        {
            multiViewRect = new QRect(0, multiViewHeight, multiViewWidth, multiViewHeight);
            row = 1; col = 0;
        }
        else if (cam == 3)
        {
            multiViewRect = new QRect(multiViewWidth, multiViewHeight, multiViewWidth, multiViewHeight);
            row = 1; col = 1;
        }
    
        m_pScene[cam]->setView(m_pView[cam], *multiViewRect);
        ui.videoBox->addWidget(m_pView[cam].get(), row, col);
    }
    

  • Lifetime Qt Champion

    Hi,

    @N2CV said in QGridLayout only showing last grid occupied:

    m_pScene[cam]->setView(m_pView[cam], *multiViewRect);

    Where is that setView method coming from ?



  • It is a method on my QGraphicsScene subclass. Here's the relevant parts:

    void SubclassScene::setView(std::shared_ptr<SubclassView>& view, QRect geom)
    {
    	m_pView = view.get();
    
    	// Figure out maximum size of video can be to fit into the video widget
    	auto viewport = centeredViewport(geom.width(), geom.height());
    
    	m_pVideoCanvas->set_viewsize(viewport.width(), viewport.height(), geom.x(), geom.y(), geom.width(), geom.height()); 
    .
    .
    .
    }
    
    

  • Lifetime Qt Champion

    You don't seem to set the scene on the view at any given time.

    Your code is pretty obscure to setup a scene on a view.

    By the way, why are you making a pointer to a QRect in your code ? You are just leaking them currently.



  • Sorry about the obscure code...my client is paranoid about me putting any code out here. I tried to put out the pertinent parts. After this for loop, I do some "proprietary" things on each view, and then I set the view to the scene. I also clean up the rect pointer.


  • Lifetime Qt Champion

    In that case, I would recommend that you first cleanup that method.

    I don't see why you should have a scene that has method to set a view on it as it's the "container class" job to put these two together.

    You should start by:

    • setup your scenes with that rectangle
    • building that grid of view
    • set the view on the scene in the same code that generates the grid

    Start by doing that with dummy scenes that contains e.g. a coloured rectangle so you'll see if you grid is working.
    Then move to your custom scene.



  • I probably shouldn't have posted any code...I had to cut it up so much that it looks like I have problems that my real code doesn't. Here's what I really need to know:

    Can 1 QGLWidget have 4 QGraphicsScene's each with a separate QGraphicsView? Because what I'm seeing in the debugger is that Qt is only calling drawBackground/drawForeground on the last view I added, so it is the only one being displayed. The other three that I created never get notified that they need to be redrawn. If it is possible for this scenario, how do I force Qt to notify all 4 views that they need to be redrawn?


  • Lifetime Qt Champion

    AFAIK, you can't use one QGLWidget (why not QOpenGLWidget ?)

    You can share a context between several of them though.



  • Sorry didn't understand your last response. Are you saying you can't use multiple scenes on one QGLWidget? I'm using QGLWidget because its legacy code that I'm updating and the client wanted to stay with it.


  • Lifetime Qt Champion

    What I was suggesting is to have one QGLWidget per QGraphicsView you want to accelerate.


Log in to reply