Qt QScrollArea显示滚动条(添加自定义控件)

  最近在做项目,想要使用一个带滚动条的窗体来显示一些信息,可以自己重写一个区域再关联一个QScrollBar,但是这样一来,工作量貌似挺大,之前就知道有QScrollArea对象,但是一直没用过,心里想着应该可以在上面布一些控件对象,但是后来查了帮助文档,怎么也没发现类似于append或者insert之类的方法,有从网上找了些资料,原来QScrollArea可以使用setWidget方法来设置需要使用滚动条来控制显示的窗口(现在想想,这样其实是很合理的,我自己当初想偏了,滚动条本来是应该用来控制窗口的滚动,而不能是一个button或者lineEdit)。不过这样也简单,只需要子类化QWidget,或者仅仅创建一个QWidget对象,然后在其上使用一个布局,放需要显示的部件就可以了,于是就上手试了一下,源码如下:

类及方法的声明

 1 class ChatList : public QWidget
 2 {
 3     Q_OBJECT
 4 public:
 5     explicit ChatList(QWidget *parent = 0);
 6     ~ChatList();
 7  
 8 private:
 9     void initComponent();
10  
11 signals:
12  
13 public slots:
14  
15 private:
16     QScrollArea* m_pChatListScrollArea;
17     QVBoxLayout* m_pSCVLayout;
18 };

类方法的实现

 1 ChatList::ChatList(QWidget *parent) : QWidget(parent)
 2 {
 3     initComponent();
 4 }
 5  
 6 ChatList::~ChatList()
 7 {
 8     delete m_pChatListScrollArea;
 9 }
10  
11 void ChatList::initComponent()
12 {
13     this->m_pChatListScrollArea = new QScrollArea(this);
14     this->m_pChatListScrollArea->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
15     this->m_pChatListScrollArea->setWidgetResizable(true);
16  
17     this->m_pSCVLayout = new QVBoxLayout(this);
18     this->m_pSCVLayout->setSizeConstraint(QVBoxLayout::SetMinAndMaxSize);
19  
20     QWidget* widget = new QWidget(this);
21     widget->setMinimumSize(72, 32);
22     widget->setMaximumSize(80,32);
23  
24     int i = 0;
25     QString str("pushButton %1");
26     QPushButton* pushButton;
27     for (i=0; i<10; ++i)
28     {
29         pushButton = new QPushButton(str.arg(i+1), widget);
30         pushButton->setMinimumSize(pushButton->size());
31         this->m_pSCVLayout->addWidget(pushButton);
32     }
33     widget->setLayout(this->m_pSCVLayout);
34     this->m_pChatListScrollArea->setWidget(widget);
35 }

但是这样并没有自己想要的效果,没有滚动条出现,或者滚动条不可以用,继续从网上找资料,在QTCN开发网是发现了一个求助帖,在最后一条回答中找到了答案,只需要在initCompont()方法的末尾给this添加一个Layout并且将QScrollArea对象放在该Layout中就可以了,具体需要添加的代码如下:

1     QVBoxLayout *mainLayout = new QVBoxLayout(this);
2     mainLayout->addWidget(this->m_pChatListScrollArea);
3     this->setLayout(mainLayout);

main函数为:

 1 #include "ChatWidget.h"
 2 #include "ScrollArea.h"
 3 #include <QApplication>
 4 #include <QVBoxLayout>
 5  
 6 int main(int argc, char* argv[])
 7 {
 8     QApplication app(argc, argv);
 9  
10     ChatList chatList;
11     chatList.show();
12  
13     return app.exec();
14 }

运行效果如下:

后来又梳理了一下,在使用QScrollArea大体上需要按照这么一个框图顺序

关于initComponent()方法中的一下设置属性的问题,是根据帮助文档中关于QScrollArea部分的Size Hints and Layouts部分中建议说明设置的,具体如下:

Size Hints and Layouts

When using a scroll area to display the contents of a custom widget, it is important to ensure that the size hint of the child widget is set to a suitable value. If a standard QWidget is used for the child widget, it may be necessary to call QWidget::setMinimumSize() to ensure that the contents of the widget are shown correctly within the scroll area.

If a scroll area is used to display the contents of a widget that contains child widgets arranged in a layout, it is important to realize that the size policy of the layout will also determine the size of the widget. This is especially useful to know if you intend to dynamically change the contents of the layout. In such cases, setting the layout's size constraint property to one which provides constraints on the minimum and/or maximum size of the layout (e.g., QLayout::SetMinAndMaxSize) will cause the size of the scroll area to be updated whenever the contents of the layout changes.

具体内部原理也不太清楚,只是根据各种资料摸索出来的,也不确定这样写是不是合理,如果有更好的建议还望告知,在此先拜谢~~

原文地址:https://www.cnblogs.com/ybqjymy/p/14592422.html