Наличие QScrollArea динамически соответствует его родителю, но не расширяется для его потомков

Кажется, у меня проблема с получением желаемого поведения от QScrollArea, Как есть, всякий раз, когда я добавляю что-то в макет виджета, установленного в качестве цели области прокрутки, он предпочитает расширять все окно, а не подгонять для прокрутки.

Вот мои текущие настройки:

QSplitter * mainArea = new QSplitter( Qt::Vertical );

QWidget * containment = new QWidget;
containment->setLayout( new QVBoxLayout );

currentStructures = new QWidget;
currentStructures->setLayout( new QVBoxLayout );
currentStructures->layout()->setAlignment( Qt::AlignTop );

QScrollArea * scroll = new QScrollArea();
scroll->setWidget( currentStructures );

containment->layout()->addWidget( currentStructures );
mainArea->addWidget( containment );

mainArea->addWidget( new QWidget ); //TODO: create preview bar

this->layout()->addWidget( mainArea );

Это делает так, что область прокрутки только расширяется и никогда не показывает полосы прокрутки.

Вставив эту строку:

containment->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Ignored );

Я могу заставить область игнорировать размер ее дочерних элементов, но она также не занимает необходимое пространство и не показывает полосы прокрутки - она ​​просто хрустит внутри виджета.

Я немного сторонник использования Qt, но мне было интересно, как бы я смог добиться нужного мне поведения: я бы хотел, чтобы область прокрутки жадно занимала область, доступную из родительского макета, но не расширяла содержит макеты вертикально при добавлении, но вместо этого фактически показывает полосы прокрутки. Я планирую разрешить большое изменение размеров, поэтому его нужно масштабировать до родительского, а не фиксированного размера. Я в недоумении относительно того, как мне следует поступить в решении этого аспекта моего графического интерфейса. Спасибо за ваше время.

Если вы хотите решить эту проблему визуально, вот ремень, который вы можете использовать. Я очень ценю вашу помощь.

#include <QtWidgets\qapplication.h>
#include <QtWidgets\qsplitter.h>
#include <QtWidgets\qlayout.h>
#include <QtWidgets\qscrollarea.h>
#include <QtWidgets\qpushbutton.h>
#include <QtWidgets\qlabel.h>
#include <QtWidgets\qsizepolicy.h>

int main( int argc, char * argv[] )
{
    QApplication app( argc, argv );

    QWidget * testWidget = new QWidget;
    testWidget->setLayout( new QVBoxLayout );

    //////////////////CODE IN QUESTIION//////////////////////
    QSplitter * mainArea = new QSplitter( Qt::Vertical );

    QWidget * containment = new QWidget;
    containment->setLayout( new QVBoxLayout );

    //containment->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Ignored );

    QWidget * currentStructures = new QWidget;
    currentStructures->setLayout( new QVBoxLayout );
    currentStructures->layout()->setAlignment( Qt::AlignTop );

    QScrollArea * scroll = new QScrollArea();
    scroll->setWidget( currentStructures );

    containment->layout()->addWidget( currentStructures );
    mainArea->addWidget( containment );
    ///////////////////////////////////////////////////////////

    QPushButton * pushIntoLayout = new QPushButton( "Add Element to Widget" );
    QWidget::connect( pushIntoLayout, &QPushButton::clicked, [currentStructures](){ currentStructures->layout()->addWidget( new QLabel( "A generated label" ) ); } );
    mainArea->addWidget( pushIntoLayout );
    currentStructures->setStyleSheet(
        "QWidget {"
            "background-color: #FAA;"
        "}" 
    );


    testWidget->layout()->addWidget( mainArea );

    testWidget->show();
    return app.exec();
}

1 ответ

Решение

Даже после того, как я скопировал и вставил мой код для создания тестовой программы, я не заметил своей серьезной ошибки. Я по ошибке толкнул currentStructures виджет для макета контейнера, а не scrollПрокрутка области после предоставления ей своего ребенка.

Выдержка из документации по Qtvoid QScrollArea::setWidget( QWidget * widget ) для незнакомых:

Виджет становится дочерним по отношению к области прокрутки и будет уничтожен при удалении области прокрутки или при установке нового виджета.

Спасибо всем, кто просмотрел это.

Для тех, кому интересно, исправленный код будет выглядеть следующим образом:

QSplitter * mainArea = new QSplitter( Qt::Vertical );

QWidget * containment = new QWidget;
containment->setLayout( new QVBoxLayout );

QWidget * currentStructures = new QWidget;
currentStructures->setLayout( new QVBoxLayout );
currentStructures->layout()->setAlignment( Qt::AlignTop );

QScrollArea * scroll = new QScrollArea();
scroll->setWidget( currentStructures );
scroll->setWidgetResizable( true );

containment->layout()->addWidget( scroll );
mainArea->addWidget( containment );

mainArea->addWidget( new QWidget ); //TODO: create preview bar

this->layout()->addWidget( mainArea );

Ура!

Другие вопросы по тегам