QScrollArea无法与QWidget和QVBoxLayout一起使用 [英] QScrollArea not working as expected with QWidget and QVBoxLayout

查看:493
本文介绍了QScrollArea无法与QWidget和QVBoxLayout一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我有这个QFrame,它是父窗口小部件(在代码中由this表示).在此小部件中,我想在距顶部10像素(距底部10像素)处放置QWidget,其结果是高度为140像素,而父级为160像素). QWidget在滚动区域中的垂直布局中将具有许多自定义按钮,因此,当组合的按钮高度超过QWidget's高度(140px)时,滚动会自动设置.因为滚动不是针对整个父窗口小部件,而是仅针对子窗口小部件,所以此处的滚动应仅应用于子窗口小部件.这是我的代码:

So I have this QFrame which is the parent widget (represented by this in the code). In this widget, I want to place a QWidget at 10 px from top (and 10 px from bottom, as a result of which it will have a height of 140px, whereas parent is 160px). The QWidget will have a number of custom buttons inside it in a vertical layout, in a scroll area, so that when the height of the buttons combined exceeds the QWidget's height (140px), scroll sets in automatically. Because the scroll is not for the entire parent widget, but only for a child widget, the scroll should apply only to the child widget here. Here is my code:

//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);

与我的期望相反,这就是我得到的(附图).我在做什么错了,我该如何解决?

Contrary to my expectations, this is what I am getting (attached image). What am I doing wrong, and how do I fix this?

推荐答案

您弄乱了项目堆栈.具有可滚动区域的想法是这样的:

You messed up the stack of items. The idea of having scrollable area is like this:

  • 底部是父窗口小部件(例如QDialog)
  • 在其顶部是固定大小的可滚动区域(QScrollArea)
  • 在其顶部是某个大小的窗口小部件(QWidget),通常其中只有一部分可见(应该大于滚动区域)
  • 在此之上是布局
  • 最后一个:布局管理子项(此处为QPushButton对)
  • on the bottom is parent widget (for example QDialog)
  • on top of this is scrollable area (QScrollArea) of fixed size
  • on top of this is a widget (QWidget) of some size, where usually only part of it is visible (it's supposed to be bigger than scrollarea)
  • on top of this is a layout
  • and the last: layout manages child items (couple of QPushButton here)

尝试以下代码:

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,它会根据其内容动态调整子窗口小部件的大小.

Worth to mention about QScrollArea::setWidgetResizable, which adjusts the child widget size dynamically according to its content.

结果如下:

这篇关于QScrollArea无法与QWidget和QVBoxLayout一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆