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

Weird QVBoxLayout behavior containing QChartView derived class objects



  • I thought that I had enough problem reporting for some time but it seems like I have stumble into yet another problem during my QChart journey...

    I'm not sure that this one is related to QChart code itself but it could be... Maybe something related to how QChart code sets the view widget minimum and maximum sizes... but honestly idk yet what is causing that. I would think that it is very unlikely to come from QVBoxLayout code since it is used by so many software for years without any issues...

    Here is the context: I have a widget having QVBoxLayout as the layout object. In the layout, I am inserting 3 QChartView objects.

    Then, I can toggle on/off the visibility of each QChartView (I have created a class called OneOrManyActionGroup that is similar to QActionGroup except that what it enforce is that at least 1 checkbox is checked. The group object disable the last checked checkbox after its last checked peer gets unchecked. You can see it in action in the picture found on https://forum.qt.io/topic/110369/why-is-qt-makes-it-hard-to-activate-a-qaction-with-menu-from-qmenu).

    My expectation is that each visible widget would share evenly the available space in the layout. This is not what is happening and I am very surprised about this unexpected behavior.

    I have modified my resizeEvent() function to log some traces:

    /*
     * resizeEvent()
     * 
     * https://forum.qt.io/topic/110370/issue-with-qchart-layout-when-resizing-the-parent-qchartview-qt-5-14-0
     */
    void LinkedChartView::resizeEvent(QResizeEvent *event)
    {
        QChartView::resizeEvent(event);
        qDebug() << event->oldSize() << event->size();
        chart()->layout()->invalidate();
        chart()->layout()->activate();
    }
    

    Here are the 3 view widget sizes on startup:

    QSize(-1, -1) QSize(1904, 330)
    QSize(-1, -1) QSize(1904, 329)
    QSize(-1, -1) QSize(1904, 330)
    

    So far so good. I hide one:

    QSize(1904, 330) QSize(1904, 494)
    QSize(1904, 330) QSize(1904, 495)
    

    Still working as expected. I remove another one:

    QSize(1904, 495) QSize(1904, 989)
    

    Now, I start putting back hidden view widgets. The first one:

    QSize(1904, 989) QSize(1904, 495)
    QSize(-1, -1) QSize(1904, 494)
    

    The last one:

    QSize(1904, 494) QSize(1904, 275)
    QSize(1904, 495) QSize(1904, 275)
    QSize(-1, -1) QSize(1904, 439)
    

    What did happen here?
    Why do I get a widget much bigger than the 2 other ones?
    Why am I not retrieving the initial sizes?



  • I have tried to call

    setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    

    on my view widgets. It doesn't change the outcome...


  • Moderators

    Have you tried setting the stretches for the layout manually?



  • @lano1106
    Try as @kshegunov has just written.

    I think your "My expectation is that each visible widget would share evenly the available space in the layout." is not guaranteed, not the "evenly", at least in your case of adding & removing items. If you still can't get it to work, you might have to try a QGridLayout to ensure desired behaviour?



  • Ok. I think that I have found at least 2 ways to achieve what I want.

    1. Create my own dumb custom QLayout derived class that does distribute evenly the available space between every Layout items. I'm surprised to discover that this requirement isn't more widespread and that there is not already a standard Layout class that attempts doing that as long as even size is within the min/max size range of all its items...

    2. Leave no liberty to the layout object by setting its items minimum height to be precisely Layout height/number of items. This would have to be performed when parent is resizing and when layout items visibility is changed.



  • @kshegunov : No I haven't tried the stretches. My understanding of them is that they prioritize which items are going to get any remaining extra space. By default, stretch value is 0 and I would need to make sure that all my widgets have the same stretch value. So we are back to square 1.

    @JonB : QGridLayout creates columns and rows. Unless, there is a setting to share evenly all the spaces among all cells not empty, I would have the same issue with it I think...



  • @lano1106
    QGridLayout allows you to set individual row heights etc. easily, so e.g. you could do the calculation of the available space and set accordingly. That's if it doesn't distribute evenly anyway, which it may do. That's all I meant.

    You may indeed need to do your own custom layout to get what you want.

    I don't think your overall request is not typical, but maybe the way you add then delete then re-add and expect equalization is what is unusual.

    It would be good if someone with better knowledge than me about layouts chipped in here.....



  • @JonB : Then setting manually rows height would be equivalent to my solution #2. It would come down to if you prefer to set children widget minimum height or GridLayout row height...



  • @lano1106
    Effectively it does. But I didn't know you were going post your solution #2 at the time I suggested it might be something you could look at :)


Log in to reply