我的环境:

  • Windows 10 64位
  • Microsoft Visual Studio 2015年
  • Qt 5.6.2
  • Qt Creator 4.8.1

  • 我有一个包含滚动区域的对话框。滚动区域最初是空的:

    c++ - 无法自动调整QScrollArea的大小-LMLPHP

    当用户单击复选框时,小部件将添加到滚动区域:

    c++ - 无法自动调整QScrollArea的大小-LMLPHP

    从上面可以看到,仅显示了滚动区域的一部分。我想自动放大它(以及包含它的对话框),所以结果看起来像这样:

    c++ - 无法自动调整QScrollArea的大小-LMLPHP

    我的代码缺少什么?

    我已将问题简化为一个最小的示例程序(从上面的照片中拍摄)。这是代码:

    scroll_area.pro:
    QT += widgets
    TEMPLATE = app
    SOURCES += main.cpp my_dialog.cpp
    HEADERS += my_dialog.h my_widget.h
    TARGET = ScrollArea
    

    main.cpp:
    #include "my_dialog.h"
    #include <QApplication>
    
    int main(int argc, char* argv[])
    {
        QApplication app(argc, argv);
        MyDialog myDialog;
        myDialog.show();
        return app.exec();
    }
    

    my_dialog.h:
    #ifndef MY_DIALOG_H
    #define MY_DIALOG_H
    
    #include <QBoxLayout>
    #include <QDialog>
    #include <QScrollArea>
    
    class MyDialog : public QDialog
    {
        Q_OBJECT
    
    public:
        MyDialog();
    
    private:
        QScrollArea* m_scrollArea;
        QHBoxLayout* m_hLayout;
    
    private slots:
        void changeScrollArea(int newState);
    };
    
    #endif // MY_DIALOG_H
    

    my_dialog.cpp:
    #include "my_dialog.h"
    #include "my_widget.h"
    #include <QCheckBox>
    #include <QDialogButtonBox>
    
    MyDialog::MyDialog() :
        QDialog(nullptr), m_scrollArea(new QScrollArea(this)), m_hLayout(new QHBoxLayout())
    {
        setWindowTitle("My Dialog");
    
        QVBoxLayout* vlayout = new QVBoxLayout(this);
    
        // Set up the scroll area.
        m_scrollArea->setBackgroundRole(QPalette::ColorRole::Light);
        m_scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
        vlayout->addWidget(m_scrollArea);
    
        // Set up the scroll contents.
        QWidget* scrollContents = new QWidget(this);
        scrollContents->setLayout(m_hLayout);
        m_scrollArea->setWidget(scrollContents);
    
        // Set up the check box.
        QCheckBox* checkbox = new QCheckBox("Check to add widgets", this);
        connect(checkbox, SIGNAL(stateChanged(int)), this, SLOT(changeScrollArea(int)));
        vlayout->addWidget(checkbox);
    }
    
    void MyDialog::changeScrollArea(int newState)
    {
        // Set up the horizontal layout.
        m_hLayout->deleteLater();
        m_hLayout = new QHBoxLayout();
    
        // Set up the scroll contents.
        QWidget* scrollContents = new QWidget(this);
        scrollContents->setLayout(m_hLayout);
        if (newState == Qt::Checked)
        {
            m_hLayout->addWidget(new MyWidget(scrollContents));
            m_hLayout->addWidget(new MyWidget(scrollContents));
        }
        m_scrollArea->setWidget(scrollContents);
    }
    

    my_widget.h
    #ifndef MY_WIDGET_H
    #define MY_WIDGET_H
    
    #include <QGridLayout>
    #include <QPushButton>
    
    class MyWidget : public QWidget
    {
        Q_OBJECT
    
    public:
        MyWidget(QWidget* parent) : QWidget(parent)
        {
            QGridLayout* gridLayout = new QGridLayout(this);
    
            for (int row = 0; row < 5; ++row)
            {
                for (int column = 0; column < 1; ++column)
                {
                    QPushButton* button = new QPushButton("FOO");
                    gridLayout->addWidget(button, row, column);
                }
            }
        }
    };
    
    #endif // MY_WIDGET_H
    

    最佳答案

    QScrollArea不会根据其内容更改大小,因为其任务是建立在视口(viewport)中可以具有较大大小的小部件,因此解决方案是使用代码来更改大小:

    mydialog.h

    #ifndef MYDIALOG_H
    #define MYDIALOG_H
    
    #include <QDialog>
    
    class QScrollArea;
    class QHBoxLayout;
    
    class MyDialog : public QDialog
    {
        Q_OBJECT
    public:
        MyDialog();
    private:
        QScrollArea* m_scrollArea;
        QHBoxLayout* m_hLayout;
    private slots:
        void changeScrollArea(int newState);
        void adjust();
    };
    #endif // MYDIALOG_H
    

    mydialog.cpp
    #include "mydialog.h"
    #include "mywidget.h"
    
    #include <QCheckBox>
    #include <QHBoxLayout>
    #include <QScrollArea>
    #include <QScrollBar>
    #include <QTimer>
    
    MyDialog::MyDialog() :
        QDialog(nullptr), m_scrollArea(new QScrollArea), m_hLayout(new QHBoxLayout())
    {
        setWindowTitle("My Dialog");
        QVBoxLayout* vlayout = new QVBoxLayout(this);
        // Set up the scroll area.
        m_scrollArea->setBackgroundRole(QPalette::ColorRole::Light);
        m_scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
        m_scrollArea->setWidgetResizable(true);
        vlayout->addWidget(m_scrollArea);
        // Set up the scroll contents.
        QWidget* scrollContents = new QWidget;
        scrollContents->setLayout(m_hLayout);
        m_scrollArea->setWidget(scrollContents);
        // Set up the check box.
        QCheckBox* checkbox = new QCheckBox("Check to add widgets");
        connect(checkbox, &QCheckBox::stateChanged, this, &MyDialog::changeScrollArea);
        vlayout->addWidget(checkbox);
    }
    void MyDialog::changeScrollArea(int newState)
    {
        m_hLayout->deleteLater();
        // Set up the scroll contents.
        QWidget* scrollContents = new QWidget;
        // Set up the horizontal layout.
        m_hLayout = new QHBoxLayout(scrollContents);
        if (newState == Qt::Checked)
        {
            m_hLayout->addWidget(new MyWidget(scrollContents));
            m_hLayout->addWidget(new MyWidget(scrollContents));
        }
        m_scrollArea->setWidget(scrollContents);
        m_scrollArea->resize(m_scrollArea->minimumSizeHint());
        resize(sizeHint());
        QTimer::singleShot(0, this, &MyDialog::adjust);
    }
    
    void MyDialog::adjust()
    {
        const QSize max_size(1000, 1000);
        const int step = 5;
        while (m_scrollArea->verticalScrollBar()->isVisible() && height() < max_size.height())
            resize(width(), height() + step);
        while (m_scrollArea->horizontalScrollBar()->isVisible() && width() < max_size.width())
            resize(width()+step, height());
    }
    

    关于c++ - 无法自动调整QScrollArea的大小,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54351997/

    10-16 16:29
    查看更多