QScrollArea与QWidget和QVBoxLayout一起使用时无法按预期工作

9

我有一个父窗口小部件QFrame(在代码中由this表示)。在这个小部件中,我想将一个QWidget放置在距离顶部10px的位置(同时距离底部也是10px,因此它将具有高度为140px,而父窗口小部件的高度是160px)。这个QWidget将包含一些自定义按钮,在垂直布局的滚动区域内,所以当按钮的高度合计超过QWidget的高度(140px)时,滚动条会自动出现。因为滚动条不是针对整个父窗口小部件,而只是针对子小部件,所以这里的滚动条应该仅适用于子小部件。以下是我的代码:

//this is a custom button class with predefined height and some formatting styles
class MyButton: public QPushButton
{

public:
    MyButton(std::string aText, QWidget *aParent);

};

MyButton::MyButton(std::string aText, QWidget *aParent): QPushButton(QString::fromStdString(aText), aParent)
{
    this->setFixedHeight(30);
    this->setCursor(Qt::PointingHandCursor);
    this->setCheckable(false);
    this->setStyleSheet("background: rgb(74,89,98);   color: black; border-radius: 0px; text-align: left; padding-left: 5px; border-bottom: 1px solid black;");
}

//this is where I position the parent widget first, and then add sub widget
this->setGeometry(x,y,width,160);
this->setStyleSheet("border-radius: 5px; background:red;");

//this is the widget which is supposed to be scrollable
QWidget *dd = new QWidget(this);
dd->setGeometry(0,10,width,140);
dd->setStyleSheet("background: blue;");

QVBoxLayout *layout = new QVBoxLayout();
dd->setLayout(layout);

for (int i = 0; i < fValues.size(); i++)
{
    MyButton *button = new MyButton(fValues[i],dd);
    layout->addWidget(button);
}

QScrollArea *scroll = new QScrollArea(this);
scroll->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
scroll->setWidget(dd);

与我的期望相反,我得到了以下结果(附图)。我做错了什么,如何解决? enter image description here

观察调试信息是有意义的。 - Alexander V
1个回答

23

您把项目堆栈搞砸了。具有可滚动区域的想法是这样的:

  • 底部是父控件(例如QDialog
  • 在其上方是固定大小的可滚动区域(QScrollArea
  • 在其上方是一个小部分可见的小部件(QWidget),通常应该比滚动区域大
  • 在其上方是布局
  • 最后:布局管理子项(这里有一些QPushButton

尝试此代码:

int
main( int _argc, char** _argv )
{
    QApplication app( _argc, _argv );

    QDialog * dlg = new QDialog();
    dlg->setGeometry( 100, 100, 260, 260);

    QScrollArea *scrollArea = new QScrollArea( dlg );
    scrollArea->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOn );
    scrollArea->setWidgetResizable( true );
    scrollArea->setGeometry( 10, 10, 200, 200 );

    QWidget *widget = new QWidget();
    scrollArea->setWidget( widget );

    QVBoxLayout *layout = new QVBoxLayout();
    widget->setLayout( layout );

    for (int i = 0; i < 10; i++)
    {
        QPushButton *button = new QPushButton( QString( "%1" ).arg( i ) );
        layout->addWidget( button );
    }

    dlg->show();

    return app.exec();
}

值得一提的是QScrollArea::setWidgetResizable, 可以根据其内容动态调整子窗口大小。

而结果看起来像这样:

enter image description here


5
感谢使用 scrollArea->setWidgetResizable( true );。如果不使用该函数,所包含的布局似乎无法得到正确的布局。 - Martin Hennings

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接