1. 程式人生 > 程式設計 >Qt圖形影象開發之QT滾動區控制元件(滾動條)QScrollArea的詳細方法用法圖解與例項

Qt圖形影象開發之QT滾動區控制元件(滾動條)QScrollArea的詳細方法用法圖解與例項

QT滾動區控制元件(滾動條控制元件)QScrollArea簡介

滾動區域控制元件QScrollArea用於顯示一個畫面中的子部件的內容。如果部件超過畫面的大小,檢視可以提供滾動條,這樣就可以看到部件的整個區域。

QScrollArea屬於控制元件容器類,可以直接在ui中拖出來。

Qt圖形影象開發之QT滾動區控制元件(滾動條)QScrollArea的詳細方法用法圖解與例項

對於QScrollArea,最難搞懂的就是:如何控制它,才能讓它在我們想要出現滾動條的時候出現滾動條。

我們拖入一個QScrollArea,再向他裡面拖入4個button,觀察資訊如下:

Qt圖形影象開發之QT滾動區控制元件(滾動條)QScrollArea的詳細方法用法圖解與例項

可以發現,4個button並不是直接位於QScrollArea中的,而是位於它的成員scorllAreaWidgetContents中的,這個成員的型別也是控制元件型別QWidget,也就是說,QScrollArea這個容器本身就套了兩層,我們放入的按鈕等控制元件,都處在scrllAreaWidgetContents層,下文中我把QScrollArea.widget統一稱之為“內部容器”或者"內容層",內部容器是QScrollArea這個控制元件的子控制元件。

"內容層"相當於一塊很大的幕布,按鈕、label等控制元件都被繪製在了幕布上,而QScrollArea相當於一個小視窗,透過這個小視窗我們看一看到幕布上的一小部分內容,拖動滾動條相當於在視窗後面移動幕布,這樣我們就能透過視窗看到幕布上不同位置的內容。

這個幕布本質上就是一個QWidget,如果QScrollArea是從UI設計師介面拖出來的,那麼QT會自動為我們建立這個幕布,如果你是用程式碼new出來的QScrollArea,那麼不要忘記同時new一個幕布widget,並通過QScrollArea::setWidget(QWidget *)把幕布和QScrollArea關聯起來。

這裡有一個坑,如果你寫了一個功能更強的QScrollArea的子類,假設叫QScrollAreaEx(裡面自帶幕布,幕布中自帶一些按鈕什麼的),在ui設計師介面把QScrollArea提升為QScrollAreaEx的時候,你會發現,按鈕並沒有顯示出來,why?因為QT自動生成的ui程式碼中,new了一個幕布控制元件,並把這個空的幕布賦給了QScrollAreaEx物件,這真是太坑了。解決方案有兩種,①自己用程式碼new QScrollAreaEx,②在ui中拖出一個非QScrollArea的QWidget控制元件,然後提升為QScrollAreaEx。

一旦理解了幕布和觀察視窗的關係,就能很容易的總結出QScrollArea的標準程式設計步驟,分這麼幾種情況:

QScrollArea純程式碼實現

(1) new QscrollArea

(2) new 內部的幕布容器

(3) new 佈局,例如網格佈局QGridLayout(前3步不分先後順序)或者你想用的其他佈局

(4) 向佈局中新增你想要的控制元件(這一步必須位於步驟3之後,這不是廢話嗎)

(5) 關聯"幕布控制元件"和"佈局"(如果在建立佈局時,就把佈局構造在了幕布控制元件中,那麼這一步就省了)

(6) 給QScroolArea設定幕布,也即呼叫QScrollArea::setWidget(QWidget *),這一步必須位於步驟4、5之後。

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QHBoxLayout>
#include <QPushButton>
#include <QScrollArea>
 
MainWindow::MainWindow(QWidget *parent) :
  QMainWindow(parent),ui(new Ui::MainWindow)
{
  ui->setupUi(this);
 
  QScrollArea * scrollArea = new QScrollArea(this);
  QWidget * pWgt = new QWidget;
 
  QHBoxLayout *pLayout = new QHBoxLayout();//網格佈局
    for(int i = 0; i < 100; i++)
    {
      QPushButton *pBtn = new QPushButton();
      pBtn->setText(QString("按鈕%1").arg(i));
      pBtn->setMinimumSize(QSize(60,30));  //width height
      pLayout->addWidget(pBtn);//把按鈕新增到佈局控制元件中
    }
  pWgt->setLayout(pLayout);
 
  //這一句setWidget必須放在pWgt裡面的內容都準備完畢之後,否則顯示有問題
  scrollArea->setWidget(pWgt);
  setCentralWidget(scrollArea);
}
 
MainWindow::~MainWindow()
{
  delete ui;
}

QScrollArea是直接從ui裡拖出來

滾動區裡面的控制元件是程式碼new的,那麼程式設計步驟如下:

只做上一種情形的步驟(3)(4)(5)即可。

QScrollArea和它裡面的控制元件都是直接在ui裡拖出來的

這種情形不用寫程式碼,只要在滾動區域把控制元件擺放好,然後使用任意一種佈局即可,如下2圖所示:

 Qt圖形影象開發之QT滾動區控制元件(滾動條)QScrollArea的詳細方法用法圖解與例項

Qt圖形影象開發之QT滾動區控制元件(滾動條)QScrollArea的詳細方法用法圖解與例項

一句話總結QScrollArea何時出現滾動條

只要幕布控制元件scorllAreaWidgetContents的大小超過了QScrollArea的大小,就會自動出現滾動條;如果幕布比觀察視窗還小,那就不會出現滾動條。

最後再看幾個例項

我給scorllAreaWidgetContents成員設定寬高最小值為500*1000,這麼高的scorllAreaWidgetContents,顯然QScrollArea在高度上是無法容納下的。實際上,看效果發現,還沒有執行程式,就已經有滾動條了:

Qt圖形影象開發之QT滾動區控制元件(滾動條)QScrollArea的詳細方法用法圖解與例項

我們執行一下程式,然後把視窗縮小,看看是不是當視窗<scorllAreaWidgetContents最小值500*1000時,會自動出現水平滾動條。看下圖發現,並沒有出現我們期望的效果。

Qt圖形影象開發之QT滾動區控制元件(滾動條)QScrollArea的詳細方法用法圖解與例項

原因就是,水平滾動條,只有當QScrollArea<內部的QWidget時,才會出現,顯然上圖中,QScrollArea雖然沒顯示全,但是QScrollArea的寬度仍然保持原值,只是被遮住了而已。要想使QScrollArea的寬度變小,要麼通過程式直接修改,要麼通過設定佈局,使QScrollArea的寬度隨窗體的寬度減小而減小。我們這裡就簡單一點,直接給窗體設定網格佈局:

Qt圖形影象開發之QT滾動區控制元件(滾動條)QScrollArea的詳細方法用法圖解與例項

使得QScrollArea的大小受窗體大小驅動。執行起來,再看下效果:

Qt圖形影象開發之QT滾動區控制元件(滾動條)QScrollArea的詳細方法用法圖解與例項

再補充幾點:

內部的小QWidget與QScrollArea的關係,就像是給QScrollArea設定了網格佈局,然後把小QWidget放進了這個佈局中,如果給小QWidget設定的最大寬高<QScrollArea的實時大小,那麼QScrollArea會顯示出空白,而空白部分是無法放置/顯示我們自己拖入的控制元件的,如下圖:

Qt圖形影象開發之QT滾動區控制元件(滾動條)QScrollArea的詳細方法用法圖解與例項

技巧:

通過上述操作,我們知道了,我們可以通過設定內部小QWidget的寬、高最小值,來讓外部QScrollArea適時的出現滾動條,那麼到底把小QWidget的寬、高最小值設定為多少合適呢?

答案是顯然的:把小QWidget的寬、高最小值設定為剛好能容納內部的按鈕等控制元件,這樣看起來最舒服。難道我要先計算或者觀察一下按鈕等控制元件佔用的面積之後,才能去設定小QWidget的寬、高最小值嗎?

這樣做太費勁了,我們肯定不會去這樣做,除非是用ui設計師拖控制元件時,所見即所得,才無需計算小QWidget的寬、高最小值。用程式碼寫介面時,最好的做法是:

1、向小QWidget中新增按鈕等控制元件時,隨著新增的按鈕增多,小QWidget自動變大,顯然用QGridLayout來做就能實現這個自動增大這個需求。自動增大也只是出現建立內部容器階段,一旦內部容器和佈局、佈局內的控制元件都建立和新增完畢,後續即使再向佈局中新增控制元件,內部容器也不會自動增大了,這時只有靠setGeometry或者resize手動修改內部容器的大小了。

2、新增完控制元件後,手動呼叫一下adjustSize函式,該函式會根據所有子控制元件的大小之和,來調整父控制元件的大小。

步驟如下:先在ui中拖入一個QScrollArea控制元件,名字為scrollArea,然後新增程式碼:

MainWindow::MainWindow(QWidget *parent) :
  QMainWindow(parent),ui(new Ui::MainWindow)
{
  ui->setupUi(this);
 
  QGridLayout *pLayout = new QGridLayout();//網格佈局
  for(int i = 0; i < 100; i++)
  {
    QPushButton *pBtn = new QPushButton();
    pBtn->setText(QString("按鈕%1").arg(i));
    pBtn->setMinimumSize(QSize(60,30));  //width height
    pLayout->addWidget(pBtn);//把按鈕新增到佈局控制元件中
  }
  ui->scrollArea->widget()->setLayout(pLayout);//把佈局放置到QScrollArea的內部QWidget中
}

Qt圖形影象開發之QT滾動區控制元件(滾動條)QScrollArea的詳細方法用法圖解與例項

本文主要講解了QT滾動區控制元件(滾動條)QScrollArea的詳細方法用法圖解與例項,更多關於QT圖形影象開發知識請檢視下面的相關連結