1. 程式人生 > >Qt QScrollArea顯示滾動條(新增自定義控制元件)

Qt QScrollArea顯示滾動條(新增自定義控制元件)

最近在做專案,想要使用一個帶滾動條的窗體來顯示一些資訊,可以自己重寫一個區域再關聯一個QScrollBar,但是這樣一來,工作量貌似挺大,之前就知道有QScrollArea物件,但是一直沒用過,心裡想著應該可以在上面布一些控制元件物件,但是後來查了幫助文件,怎麼也沒發現類似於append或者insert之類的方法,有從網上找了些資料,原來QScrollArea可以使用setWidget方法來設定需要使用滾動條來控制顯示的視窗(現在想想,這樣其實是很合理的,我自己當初想偏了,滾動條本來是應該用來控制視窗的滾動,而不能是一個button或者lineEdit)。不過這樣也簡單,只需要子類化QWidget,或者僅僅建立一個QWidget物件,然後在其上使用一個佈局,放需要顯示的部件就可以了,於是就上手試了一下,原始碼如下:

類及方法的宣告

class ChatList : public QWidget
{
    Q_OBJECT
public:
    explicit ChatList(QWidget *parent = 0);
    ~ChatList();

private:
    void initComponent();

signals:

public slots:

private:
    QScrollArea* m_pChatListScrollArea;
    QVBoxLayout* m_pSCVLayout;
};

類方法的實現

ChatList::ChatList(QWidget *parent) : QWidget(parent)
{
    initComponent();
}

ChatList::~ChatList()
{
    delete m_pChatListScrollArea;
}

void ChatList::initComponent()
{
    this->m_pChatListScrollArea = new QScrollArea(this);
    this->m_pChatListScrollArea->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
    this->m_pChatListScrollArea->setWidgetResizable(true);

    this->m_pSCVLayout = new QVBoxLayout(this);
    this->m_pSCVLayout->setSizeConstraint(QVBoxLayout::SetMinAndMaxSize);

    QWidget* widget = new QWidget(this);
    widget->setMinimumSize(72, 32);
    widget->setMaximumSize(80,32);

    int i = 0;
    QString str("pushButton %1");
    QPushButton* pushButton;
    for (i=0; i<10; ++i)
    {
        pushButton = new QPushButton(str.arg(i+1), widget);
        pushButton->setMinimumSize(pushButton->size());
        this->m_pSCVLayout->addWidget(pushButton);
    }
    widget->setLayout(this->m_pSCVLayout);
    this->m_pChatListScrollArea->setWidget(widget);
}

但是這樣並沒有自己想要的效果,沒有滾動條出現,或者滾動條不可以用,繼續從網上找資料,在QTCN開發網是發現了一個求助帖,在最後一條回答中找到了答案,只需要在initCompont()方法的末尾給this新增一個Layout並且將QScrollArea物件放在該Layout中就可以了,具體需要新增的程式碼如下:

    QVBoxLayout *mainLayout = new QVBoxLayout(this);
    mainLayout->addWidget(this->m_pChatListScrollArea);
    this->setLayout(mainLayout);
main函式為:
#include "ChatWidget.h"
#include "ScrollArea.h"
#include <QApplication>
#include <QVBoxLayout>

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

    ChatList chatList;
    chatList.show();

    return app.exec();
}

執行效果如下:


後來又梳理了一下,在使用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.

具體內部原理也不太清楚,只是根據各種資料摸索出來的,也不確定這樣寫是不是合理,如果有更好的建議還望告知,在此先拜謝~~