Qt佈局管理器(詳解)


一、存在的問題 網絡


(1)目前的GUI開發方式:絕對定位ide


--直接在像素級指定各個組件的位置和大小函數


void QWidget::move(int x, int y)佈局

void QWidget::resize(int w, int h)測試


(2)問題this


--組件位置和大小沒法自適應父窗口的變化spa




二、佈局管理器指針


(1)解決方案:佈局管理器orm


--提供相關的類對界面組件進行佈局管理對象


@1:可以自動排列窗口中的界面組件

@2:窗口變化後自動更新界面組件的大小

(2)QLayout是Qt中佈局管理器的抽象基類


(3)經過繼承QLayout實現了功能各異且互補的佈局管理器


(4)Qt中能夠根據須要自定義佈局管理器


(5)佈局管理器不是界面組件,而是界面部件的定位策略


QLayout 是Qt佈局管理器中抽象的基類

QBoxLayout QGridLayout QFormLayout QStackedLayout這幾個類都繼承自QLayout。

(6)QBoxLayout佈局管理器


--以水平或者垂直的方式管理界面組件

QBoxLayout

QVBoxLayout QHBoxLayout 有兩個子類,一個是垂直管理界面組件的類,一個是水平管理界面組件的類。

(7)QVBoxLayout的使用(假設已經建立了四個按鈕對象,test1,test2,test3,test4)


QVBoxLayout *layout = new QVBoxLayout(); //建立一個佈局管理器對象

test1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); //函數有兩個參數,前一個參數是關於垂直的,後一個是關於水平的,這裏設置的是垂直和

//水平的大小都會隨着窗口的變化而變化

test1.setMinimumSize(160, 30); //設置這個按鈕最小是160, 30

layout->setSpaceing(30); //調用佈局管理器中的這個成員函數,能夠設置部件的空間,間隔,部件之間的距離是30個像素

layout->addWidget(&test1); //將test1這個按鈕部件添加到佈局管理器,意思是讓這個垂直的佈局管理器進行管理

layout->addWidget(&test2); //將test2這個按鈕部件添加到佈局管理器,意思是讓這個垂直的佈局管理器進行管理

layout->addWidget(&test3); //將test3這個按鈕部件添加到佈局管理器,意思是讓這個垂直的佈局管理器進行管理

layout->addWidget(&test4); //將test4這個按鈕部件添加到佈局管理器,意思是讓這個垂直的佈局管理器進行管理

setLayout(layout); //調用setLayout函數設置佈局管理器爲這個layout

可是通過這幾部的操做,咱們發現界面跟着變大的時候,這幾個按鈕也會隨着變化,但僅僅只是寬度的變化,而按鈕的高度卻沒有隨着主窗口的變化而變化,解決的方法有。


這時就用到了這個QSizePolicy類,繼承自QWidget,由於QWidget是基類,這個類咱們能夠在Qt的幫助文檔中詳細的看,大概的意思就是一個大小的策略,是當有佈局管理器存在的時候起做用。當佈局管理器時

這個QSizePolicy類的大小的策略,就會被佈局管理器所使用。大小策略的函數是setSizePolicy();

(8)水平管理器QHBoxLayout的使用和垂直管理器QVBoxLayout的使用方式同樣



(9)佈局管理器能夠相互嵌套,造成更加複雜的佈局方式。因此Qt中提供的四個佈局管理器,能夠相互的配合,完成幾乎全部的經常使用的界面佈局。


--佈局嵌套幾乎能夠完成全部經常使用的界面佈局


--自定義佈局管理類能夠達到個性化界面佈局的效果



如:


#include "widget.h"

#include <QVBoxLayout>

#include <QHBoxLayout>


Widget::Widget(QWidget *parent)

    : QWidget(parent), Test1(this), Test2(this), Test3(this), Test4(this)

{


   // testQVBoxLayout();

   // testQHBoxLayout();

    qiantao_QV_QHlayout();

}


void Widget::testQVBoxLayout()  //垂直管理器的佈局

{

    Test1.setText("Test1Button");

    Test2.setText("Test2Button");

    Test3.setText("Test3Button");

    Test4.setText("Test4Button");


    Test1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);    //設置大小策略,當有佈局管理器時起做用,窗口變化

                                                                            //按鈕垂直和水平大小都會有擴展,不會只寬度變

    Test2.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    Test3.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    Test4.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);


    Test1.setMinimumSize(160, 30);  //設置按鈕最小的寬度和高度爲160和30,不能在小了

    Test2.setMinimumSize(160, 30);

    Test3.setMinimumSize(160, 30);

    Test4.setMinimumSize(160, 30);



    QVBoxLayout *vlayout = new QVBoxLayout();   //建立一個垂直管理器的對象


    vlayout->setSpacing(30);    //設置這個佈局管理器中的組件間間隔是30個像素


    vlayout->addWidget(&Test1); //將這個按鈕組件添加到vlayout這個垂直佈局管理器中

    vlayout->addWidget(&Test2);

    vlayout->addWidget(&Test3);

    vlayout->addWidget(&Test4);


    setLayout(vlayout); //設置佈局管理器爲這個


}


void Widget::testQHBoxLayout()  //水平管理器的佈局

{

    Test1.setText("Test1Button");

    Test2.setText("Test2Button");

    Test3.setText("Test3Button");

    Test4.setText("Test4Button");


    Test1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);    //設置大小策略,當有佈局管理器時起做用,窗口變化

                                                                            //按鈕垂直和水平大小都會有擴展,不會只寬度變

    Test2.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    Test3.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    Test4.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);


    Test1.setMinimumSize(160, 30);  //設置按鈕最小的寬度和高度爲160和30,不能在小了

    Test2.setMinimumSize(160, 30);

    Test3.setMinimumSize(160, 30);

    Test4.setMinimumSize(160, 30);



    QHBoxLayout *hlayout = new QHBoxLayout();   //建立一個水平管理器的對象


    hlayout->setSpacing(30);    //設置這個佈局管理器中的組件間間隔是30個像素


    hlayout->addWidget(&Test1); //將這個按鈕組件添加到vlayout這個垂直佈局管理器中

    hlayout->addWidget(&Test2);

    hlayout->addWidget(&Test3);

    hlayout->addWidget(&Test4);


    setLayout(hlayout); //設置佈局管理器爲這個

}


void Widget::qiantao_QV_QHlayout()  //嵌套的佈局管理器,水平和垂直的嵌套

{

    Test1.setText("Test1Button");

    Test2.setText("Test2Button");

    Test3.setText("Test3Button");

    Test4.setText("Test4Button");


    Test1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);    //設置大小策略,當有佈局管理器時起做用,窗口變化

                                                                            //按鈕垂直和水平大小都會有擴展,不會只寬度變

    Test2.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    Test3.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    Test4.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);


    Test1.setMinimumSize(160, 30);  //設置按鈕最小的寬度和高度爲160和30,不能在小了

    Test2.setMinimumSize(160, 30);

    Test3.setMinimumSize(160, 30);

    Test4.setMinimumSize(160, 30);


    QVBoxLayout *vlayout = new QVBoxLayout();


    QHBoxLayout *hlayout1 = new QHBoxLayout();

    QHBoxLayout *hlayout2 = new QHBoxLayout();

    hlayout1->setSpacing(20);   //設置水平佈局管理器1中的組件間隔是20個像素

    hlayout2->setSpacing(20);   //設置水平佈局管理器2中的組件間隔是20個像素


    hlayout1->addWidget(&Test1);

    hlayout1->addWidget(&Test2);

    hlayout2->addWidget(&Test3);

    hlayout2->addWidget(&Test4);


    vlayout->setSpacing(20);    //設置垂直佈局管理器中的兩個佈局管理器的間隔是20個像素

    vlayout->addLayout(hlayout1);   //添加管理佈局時,要用addLayout,不能用addWidget了

    vlayout->addLayout(hlayout2);


    setLayout(vlayout); //告訴當前的窗口,有vlayout這個佈局管理器來幫忙管理


}


Widget::~Widget()

{

    

}


/*************************************************************************************************************************************************/



三、佈局管理器中的比例係數


(1)默認狀況下以等比例的方式更新組件的大小(就是在窗口大小變化的時候,佈局管理器管理的組件的大小變化是等比例的)


(2)能夠自定義組件大小更新時的比例係數(就是在窗口大小進行變化的時候,佈局管理器管理的組件其大小的變化能夠自定義)


(3)QBoxLayout中的比例係數設置


--void setStretch(int index, int stretch) //第一個參數是當前佈局管理器中(QBoxLayout)格子的下標,第二個參數是比例係數


--bool setStretchFactor(QWidget *Widget, int stretch) //第一個參數是當前QBoxLayout中的具體的組件,第二參數是比例係數


--bool setStretchFactor(QLayout *Layout, int stretch) //第一個參數是被嵌套的具體的佈局管理器,第二個參數是比例係數



(4)void setStretch(int index, int stretch)函數的使用,經過下標(格子)來指定。


QVBoxLayout *layout = new QVBoxLayout();


layout->setStretch(0, 1); //設置佈局管理器QVBoxLayout中的第0個格子的比例係數爲1

layout->setStretch(1, 1);

layout->setStretch(2, 2);

layout->setStretch(3, 2);

layout->addWidget(&Test1); //將這個按鈕組件添加到layout這個垂直佈局管理器中

    layout->addWidget(&Test2);

    layout->addWidget(&Test3);

    layout->addWidget(&Test4);


    setLayout(layout); //設置佈局管理器爲這個

當窗口進行變化的時候,QVBoxLayout佈局管理器中的四個test,大小的變化是1122的變化,比例係數是1:1:2:2

(5)bool setStretchFactor(QWidget *Widget, int stretch)函數的使用,指定具體的佈局管理器中的組件


QVBoxLayout *layout = new QVBoxLayout();


layout->setStretchFactor(&Test1, 1); //設置佈局管理器QVBoxLayout中的Test1這個組件的比例係數爲1

layout->setStretchFactor(&Test2, 1);

layout->setStretchFactor(&Test3, 2);

layout->setStretchFactor(&Test4, 2);

layout->addWidget(&Test1); //將這個按鈕組件添加到layout這個垂直佈局管理器中

layout->addWidget(&Test2);

layout->addWidget(&Test3);

layout->addWidget(&Test4);


setLayout(layout); //設置佈局管理器爲這個

(6)bool setStretchFactor(QLayout *Layout, int stretch)函數的使用,指定佈局管理器中嵌套的佈局管理器,設置其的比例係數


QVBoxLayout *vlayout = new QVBoxLayout();


QHBoxLayout *hlayout1 = new QHBoxLayout();

QHBoxLayout *hlayout2 = new QHBoxLayout();

hlayout1->setSpacing(20);   //設置水平佈局管理器1中的組件間隔是20個像素

hlayout2->setSpacing(20);   //設置水平佈局管理器2中的組件間隔是20個像素


hlayout1->addWidget(&Test1);

hlayout1->addWidget(&Test2);

hlayout2->addWidget(&Test3);

hlayout2->addWidget(&Test4);


vlayout->setSpacing(20);    //設置垂直佈局管理器中的兩個佈局管理器的間隔是20個像素

vlayout->addLayout(hlayout1);   //添加管理佈局時,要用addLayout,不能用addWidget了

vlayout->addLayout(hlayout2);

vlayout->setStretchFactor(hlayout1, 1); //設置vlayout這個垂直的佈局管理器中的hlayout1這個嵌套的水平管理器的比例係數爲1

vlayout->setStretchFactor(hlayout2, 2); //設置vlayout這個垂直的佈局管理器中的hlayout2這個嵌套的水平管理器的比例係數爲2


setLayout(vlayout); //告訴當前的窗口,有vlayout這個佈局管理器來幫忙管理

(7)組件的初始大小是獨立於佈局管理器設置的,所以不能保證組件的大小始終符合比例係數的設置(好比,開始的時候,設置了按鈕的最小的大小,可是後面佈局管理器接手管理這幾個按鈕

後,設置了按鈕的變化的比例係數,但這樣並不會讓開始的時候,按鈕的大小就是按照比例係數設置的那樣的大小,而是咱們開始時設置的按鈕的最小的大小)


例:佈局管理器的比例係數的設置,詳細代碼


#include "widget.h"

#include <QVBoxLayout>

#include <QHBoxLayout>


Widget::Widget(QWidget *parent)

    : QWidget(parent), Test1(this), Test2(this), Test3(this), Test4(this)

{


    //testQVBoxLayout();

   // testQHBoxLayout();

    qiantao_QV_QHlayout();

}


void Widget::testQVBoxLayout()  //垂直管理器的佈局

{

    Test1.setText("Test1Button");

    Test2.setText("Test2Button");

    Test3.setText("Test3Button");

    Test4.setText("Test4Button");


    Test1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);    //設置大小策略,當有佈局管理器時起做用,窗口變化

                                                                            //按鈕垂直和水平大小都會有擴展,不會只寬度變

    Test2.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    Test3.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    Test4.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);


    Test1.setMinimumSize(160, 30);  //設置按鈕最小的寬度和高度爲160和30,不能在小了

    Test2.setMinimumSize(160, 30);

    Test3.setMinimumSize(160, 30);

    Test4.setMinimumSize(160, 30);



    QVBoxLayout *vlayout = new QVBoxLayout();   //建立一個垂直管理器的對象


    vlayout->setSpacing(30);    //設置這個佈局管理器中的組件間間隔是30個像素


    vlayout->addWidget(&Test1); //將這個按鈕組件添加到vlayout這個垂直佈局管理器中

    vlayout->addWidget(&Test2);

    vlayout->addWidget(&Test3);

    vlayout->addWidget(&Test4);


    vlayout->setStretch(0, 1);  //設置vlayout這個佈局管理器中的第0個格子的比例係數爲1

    vlayout->setStretch(1, 1);

    vlayout->setStretch(2, 3);

    vlayout->setStretch(3, 3);


    setLayout(vlayout); //設置佈局管理器爲這個


}


void Widget::testQHBoxLayout()  //水平管理器的佈局

{

    Test1.setText("Test1Button");

    Test2.setText("Test2Button");

    Test3.setText("Test3Button");

    Test4.setText("Test4Button");


    Test1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);    //設置大小策略,當有佈局管理器時起做用,窗口變化

                                                                            //按鈕垂直和水平大小都會有擴展,不會只寬度變

    Test2.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    Test3.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    Test4.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);


    Test1.setMinimumSize(160, 30);  //設置按鈕最小的寬度和高度爲160和30,不能在小了

    Test2.setMinimumSize(160, 30);

    Test3.setMinimumSize(160, 30);

    Test4.setMinimumSize(160, 30);



    QHBoxLayout *hlayout = new QHBoxLayout();   //建立一個水平管理器的對象


    hlayout->setSpacing(30);    //設置這個佈局管理器中的組件間間隔是30個像素


    hlayout->addWidget(&Test1); //將這個按鈕組件添加到vlayout這個垂直佈局管理器中

    hlayout->addWidget(&Test2);

    hlayout->addWidget(&Test3);

    hlayout->addWidget(&Test4);


    hlayout->setStretchFactor(&Test1, 1);   //設置這個hlayout佈局管理器中的Test1這個按鈕組件的比例係數變化是1

    hlayout->setStretchFactor(&Test2, 2);

    hlayout->setStretchFactor(&Test3, 1);

    hlayout->setStretchFactor(&Test4, 2);



    setLayout(hlayout); //設置佈局管理器爲這個

}


void Widget::qiantao_QV_QHlayout()  //嵌套的佈局管理器,水平和垂直的嵌套

{

    Test1.setText("Test1Button");

    Test2.setText("Test2Button");

    Test3.setText("Test3Button");

    Test4.setText("Test4Button");


    Test1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);    //設置大小策略,當有佈局管理器時起做用,窗口變化

                                                                            //按鈕垂直和水平大小都會有擴展,不會只寬度變

    Test2.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    Test3.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    Test4.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);


    Test1.setMinimumSize(160, 30);  //設置按鈕最小的寬度和高度爲160和30,不能在小了

    Test2.setMinimumSize(160, 30);

    Test3.setMinimumSize(160, 30);

    Test4.setMinimumSize(160, 30);


    QVBoxLayout *vlayout = new QVBoxLayout();


    QHBoxLayout *hlayout1 = new QHBoxLayout();

    QHBoxLayout *hlayout2 = new QHBoxLayout();

    hlayout1->setSpacing(20);   //設置水平佈局管理器1中的組件間隔是20個像素

    hlayout2->setSpacing(20);   //設置水平佈局管理器2中的組件間隔是20個像素


    hlayout1->addWidget(&Test1);

    hlayout1->addWidget(&Test2);

    hlayout2->addWidget(&Test3);

    hlayout2->addWidget(&Test4);


    vlayout->setSpacing(20);    //設置垂直佈局管理器中的兩個佈局管理器的間隔是20個像素

    vlayout->addLayout(hlayout1);   //添加管理佈局時,要用addLayout,不能用addWidget了

    vlayout->addLayout(hlayout2);


    vlayout->setStretchFactor(hlayout1, 1); //設置vlayout這個佈局管理器中的hlayout1嵌套佈局管理器變化時的比例係數爲1

    vlayout->setStretchFactor(hlayout2, 5);//設置vlayout這個佈局管理器中的hlayout1嵌套佈局管理器變化時的比例係數爲5


    setLayout(vlayout); //告訴當前的窗口,有vlayout這個佈局管理器來幫忙管理


}


Widget::~Widget()

{

    

}


四、QGridLayout佈局管理器,網格的佈局管理利器


(1)以網格(二維)的方式管理界面組件


(2)QGridLayout中的比例係數設置(是針對行和列的比例係數)


--void setColumnStretch(int column, int stretch) //設置哪一列的比例係數。第一個參數就是佈局管理器的哪一列,第二參數就是比例係數


--void setRowStretch(int row, int stretch) //設置哪個行的比例係數,第一個參數就是佈局管理器的哪一行,第二個參數就是比例係數



(3)QGridLayout佈局管理器的使用方法


QGridLayout *layout = new QGridLayout();


layout->setSpacing(10); //設置組件的間隔爲10像素

layout->addWidget(&Test1, 0, 0); //將Test1這個按鈕,放在二維網絡的0,0這個位置,也就是左上角的位置

layout->addWidget(&Test2, 0, 1); //將Test2這個按鈕,放在二維網絡的0,1這個位置,也就是右上角的位置

layout->addWidget(&Test3, 1, 0);

layout->addWidget(&Test4, 1, 1);


layout->setRowStretch(0, 1); //設置第0行的比例係數爲1

layout->setRowStretch(1, 3); //設置第1行的比例係數爲3


layout->setColumnStretch(0, 1); //設置第0列的比例係數爲1

layout->setColumnStretch(1, 3); //設置第1列的比例係數爲3


setLayout(layout);


(4)QGridLayout佈局管理器的使用方法(跨行和跨列的使用,就是佔用多行多列的使用)


QGridLayout *layout = new QGridLayout();


layout->setSpacing(10); //設置組件的間隔爲10像素

layout->addWidget(&Test1, 0, 0, 2, 1); //將Test1這個按鈕,放在二維網絡的0,0這個位置,也就是左上角的位置,而且佔兩行一列的空間,這就是第四個參數和第五個參數

layout->addWidget(&Test2, 0, 1, 2, 1); //將Test2這個按鈕,放在二維網絡的0,1這個位置,也就是右上角的位置,而且佔兩行一列的

layout->addWidget(&Test3, 2, 0, 1, 2); //將Test3按鈕,放在第2行0列的位置,而且佔1行2列的位置空間。

layout->addWidget(&Test4, 3, 0, 1, 2); //將Test4按鈕,放在第3行0列的位置,而且佔用1行2列的位置空間


layout->setRowStretch(0, 1); //設置第0行的比例係數爲1

layout->setRowStretch(1, 3); //設置第1行的比例係數爲3


layout->setColumnStretch(0, 1); //設置第0列的比例係數爲1

layout->setColumnStretch(1, 3); //設置第1列的比例係數爲3


setLayout(layout);

(5)QGridLayout佈局管理器也支持嵌套其餘佈局管理器 



(6)QGridLayout佈局管理器的使用方法,代碼


#include "widget.h"

#include <QGridLayout>


Widget::Widget(QWidget *parent)

    : QWidget(parent), Test1(this), Test2(this), Test3(this), Test4(this)

{

   // testQGridLayout1();

    testQGridLayout2();

}



void Widget::testQGridLayout1()

{

    Test1.setText("Test1button");

    Test2.setText("Test2button");

    Test3.setText("Test3button");

    Test4.setText("Test4button");



    //設置大小策略,當有佈局管理器時起做用,窗口變化

    //按鈕垂直和水平大小都會有擴展,不會只寬度變

    Test1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    Test2.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    Test3.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    Test4.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);


    Test1.setMinimumSize(160, 30);

    Test2.setMinimumSize(160, 30);

    Test3.setMinimumSize(160, 30);

    Test4.setMinimumSize(160, 30);


    QGridLayout *Layout = new QGridLayout();


    Layout->setSpacing(10);

    Layout->addWidget(&Test1, 0, 0);

    Layout->addWidget(&Test2, 0, 1);

    Layout->addWidget(&Test3, 1, 0);

    Layout->addWidget(&Test4, 1, 1);


    Layout->setRowStretch(0, 1);    //設置第0行的比例係數爲1

    Layout->setRowStretch(1, 3);    //設置第1行的比例係數爲3

    Layout->setColumnStretch(0, 1); //設置第0列的比例係數爲1

    Layout->setColumnStretch(1, 3); //設置第1列的比例係數爲3


    setLayout(Layout);


}


void Widget::testQGridLayout2()

{

    Test1.setText("Test1button");

    Test2.setText("Test2button");

    Test3.setText("Test3button");

    Test4.setText("Test4button");


    //設置大小策略,當有佈局管理器時起做用,窗口變化

    //按鈕垂直和水平大小都會有擴展,不會只寬度變

    Test1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    Test2.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    Test3.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    Test4.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);


    Test1.setMinimumSize(160, 30);

    Test2.setMinimumSize(160, 30);

    Test3.setMinimumSize(160, 30);

    Test4.setMinimumSize(160, 30);


    QGridLayout *Layout = new QGridLayout();


    Layout->setSpacing(10);

Layout->addWidget(&Test1, 0, 0, 2, 1); //設置按鈕1在0,0位置,佔用2行1列

Layout->addWidget(&Test2, 0, 1, 2, 1); //設置按鈕2在0,1位置,佔用2行1列

    Layout->addWidget(&Test3, 3, 0, 1, 2);      //設置按鈕3在3,0位置,佔用1行2列

    Layout->addWidget(&Test4, 4, 0, 1, 2);      //設置按鈕4在4,0位置,佔用1行2列


    Layout->setRowStretch(0, 1);    //設置第0行的比例係數爲1

    Layout->setRowStretch(1, 3);    //設置第1行的比例係數爲3

    Layout->setColumnStretch(0, 1); //設置第0列的比例係數爲1

    Layout->setColumnStretch(1, 3); //設置第1列的比例係數爲3


    setLayout(Layout);

}


Widget::~Widget()

{

    

}



小結:QGridLayout一以網格的方式對組件進行管理,QGridLayout中的組件能夠根據須要跨越多個網格,QBoxLayout和QGridLayout支持比例係數的概念,比例係數決定了組件大小的相對變化



五、QFormLayout佈局管理器


(1)以表單(Form)的方式管理界面組件(就是標籤和組件是一塊兒的,之間是相互對應的關係,一個標籤一個組件,一個標籤一個組件這樣的)


(2)表單佈局中的標籤和組件是相互對應的關係


(3)QFormLayout的用法概要


--void addRow(QWidget *label, QWidget *field)


--void addRow(QWidget *label, QLayout *field)


--void addRow(const QString& LabelText, QWidget *field)


--void addRow(const QString& labelText, QLayout *field)


表單佈局支持嵌套,其餘佈局管理器能夠做爲子佈局被其管理


(4)例,QFormLayout表單佈局管理器的使用


#include "widget.h"

#include <QLineEdit>

#include <QFormLayout>  //包含表單形式的佈局管理器,標籤和組件相互對應


Widget::Widget(QWidget *parent)

: QWidget(parent, Qt::WindowCloseButtonHint)    //加上後面的屬性,就只有關閉的按鈕在窗口上

{

QLineEdit *NameEdit = new QLineEdit();  //建立一個文本框組件

QLineEdit *Email = new QLineEdit();

QLineEdit *Address = new QLineEdit();


QFormLayout *Layout = new QFormLayout();    //建立一個表單形式管理的佈局管理器對象



Layout->addRow("Name: ", NameEdit); //第一個參數就是標籤,第二個參數就是組件,這二者是相互對應的關係,在窗口變化時,二者的距離不會改變

Layout->addRow("Email: ", Email);

Layout->addRow("Address", Address);


this->setLayout(Layout);

this->setWindowTitle("FTP");    //設置主窗口的標題

}


Widget::~Widget()

{

}



(5)QFormLayout的樣式函數


--void setRowWrapPolicy(RowWrapPolicy policy) //這個函數用來設置每一行的排布方式


--void setLabelAlignment(Qt::Alignment alignment) //這個函數是用設置標籤是如何對齊的,左對齊仍是右對齊



@1:Layout->setRowWrapPolicy(QFormLayout::WrapAllRows); //WrapAllRows這個常量,這樣的就會使得,未來顯示出來的標籤在上面,組件在下面,這是嵌入式中最經常使用的樣式


@2:Layout->setLabelAlignment(Qt::AlignRight); //這樣就會使得,未來顯示的標籤是向右對齊的



(6)QFormLayout這個表單形式的佈局管理器也具有支持嵌套佈局管理器的能力


小結:QFormLayout以表單的方式管理界面組件的,它的樣式簡潔明瞭,支持佈局管理器的相互嵌套,是嵌入式產品中最經常使用的佈局方式


例:QFormLayout的樣式函數使用方法


#include "widget.h"

#include <QLineEdit>

#include <QFormLayout>  //包含表單形式的佈局管理器,標籤和組件相互對應


Widget::Widget(QWidget *parent)

: QWidget(parent, Qt::WindowCloseButtonHint)    //加上後面的屬性,就只有關閉的按鈕在窗口上

{

QLineEdit *NameEdit = new QLineEdit();  //建立一個文本框組件

QLineEdit *Email = new QLineEdit();

QLineEdit *Address = new QLineEdit();


QFormLayout *Layout = new QFormLayout();    //建立一個表單形式管理的佈局管理器對象



Layout->addRow("Name: ", NameEdit); //第一個參數就是標籤,第二個參數就是組件,這二者是相互對應的關係,在窗口變化時,二者的距離不會改變

Layout->addRow("Email: ", Email);

Layout->addRow("Address", Address);


Layout->setRowWrapPolicy(QFormLayout::WrapAllRows); //設置表單佈局的樣式,這個常量,表示設置爲上面是標籤下面是組件的形式

  // Layout->setRowWrapPolicy(QFormLayout::WrapLongRows);    //設置爲若是標籤無論多長都能顯示出來,屏幕若是不夠,會將組件弄到下面

//Layout->setLabelAlignment(Qt::AlignRight);  //設置標籤爲向右對齊


this->setLayout(Layout);

this->setWindowTitle("FTP");    //設置主窗口的標題

}


Widget::~Widget()

{

}


六、最特別的佈局管理器


(1)棧式佈局管理器(QStackedLayout),就是全部組件是垂直於屏幕的,以棧的形式堆疊在一塊兒的,咱們的視線只能看到在棧頂的組件,而且只能看到一個組件。


--全部組件在垂直於屏幕的方向上被管理


--每次只有一個組件會顯示在屏幕上


--只有最頂層的組件會被最終顯示



(2)棧式佈局管理器的特色


--組件大小一致且充滿父組件的顯示區


--不能直接嵌套其餘佈局管理器(成員函數只接受管理組件,但能夠經過間接的方式管理其餘佈局管理器,也就是嵌套)


--可以自由切換須要顯示的組件


--每次能且僅能顯示一個組件



(3)QStackedLayout棧式佈局管理器的用法概要


--int addWidget(QWidget *widget) //向這個棧式佈局管理器中,加入它要管理的組件,每次加入一個組件的時候,這些組件都會有一個下標


--QWidget* currentWidget() //獲得當前顯示在屏幕上的組件是哪個(也就是返回當前棧式佈局管理器中最頂層的那一個組件)


--void setCurrentIndex(int index) //設置哪一個下標的組件爲當前的頂層組件,也就是要顯示的組件。在每個組件添加到這個棧式佈局管理器中的時候,都會有一個下標(從0開始)


--int currentIndex() //獲得當前組件的下標


例:棧式佈局管理器的使用


#include "widget.h"

#include <QStackedLayout>



Widget::Widget(QWidget *parent)

    : QWidget(parent), TestButton1(this), TestButton2(this), TestButton3(this), TestButton4(this)

{

    QStackedLayout *slayout = new QStackedLayout(); //建立一個棧式佈局管理器對象


    TestButton1.setText("Button 1");

    TestButton2.setText("Button 2");

    TestButton3.setText("Button 3");

    TestButton4.setText("Button 4");




    slayout->addWidget(&TestButton1);   //將button1加入到這個棧式佈局管理器中 0

    slayout->addWidget(&TestButton2);   //1

    slayout->addWidget(&TestButton3);   //2

    slayout->addWidget(&TestButton4);   //3


    slayout->setCurrentIndex(1);    //設置當前顯示的組件是第二個組件,0是第一個


    setLayout(slayout);

}


Widget::~Widget()

{

    

}


例://棧式佈局管理器的間接嵌套其餘的佈局管理器


#include "widget.h"

#include <QStackedLayout>   //棧式佈局管理器

#include <QHBoxLayout>  //水平佈局管理器


Widget::Widget(QWidget *parent)

    : QWidget(parent), TestButton1(this), TestButton2(this), TestButton3(this), TestButton4(this)

{

    //testQStackedLayout();

    testQStacked_QH_Layout();

}


void Widget::testQStackedLayout()

{

    QStackedLayout *slayout = new QStackedLayout(); //建立一個棧式佈局管理器對象


    TestButton1.setText("Button 1");

    TestButton2.setText("Button 2");

    TestButton3.setText("Button 3");

    TestButton4.setText("Button 4");




    slayout->addWidget(&TestButton1);   //將button1加入到這個棧式佈局管理器中 0

    slayout->addWidget(&TestButton2);   //1

    slayout->addWidget(&TestButton3);   //2

    slayout->addWidget(&TestButton4);   //3


    slayout->setCurrentIndex(1);    //設置當前顯示的組件是第二個組件,0是第一個


    setLayout(slayout);

}


//用棧式佈局管理器,間接地嵌套了水平佈局管理器,依賴一箇中間組件widget,這個組件中有佈局管理器,這個中間組件中的佈局管理器管理的組件的父組件爲

//這個中間組件。以後將這個中間組件加入到棧式的佈局管理器中,這樣就達到了棧式佈局管理器間接的嵌套了其餘佈局管理器,由於棧式佈局管理器中的成員函數

//addWidget().這個添加組件的成員函數,只接受QWidget類型的指針對象。因此只能接受組件,不能接受佈局管理器

void Widget::testQStacked_QH_Layout()

{

    QStackedLayout *slayout = new QStackedLayout(); //建立一個棧式佈局管理器對象

    QHBoxLayout *hlayout = new QHBoxLayout();   //建立一個水平佈局管理器對象

    QWidget *widget = new QWidget();    //建立一個組件對象


    TestButton1.setText("Button 1");

    TestButton2.setText("Button 2");

    TestButton3.setText("Button 3");

    TestButton4.setText("Button 4");


    TestButton2.setParent(widget);      //設置按鈕2的父組件爲新建立的widget對象

    TestButton3.setParent(widget);      //設置按鈕3的父組件爲新建立的widget對象


    hlayout->addWidget(&TestButton2);   //將按鈕2添加到水平佈局管理器中

    hlayout->addWidget(&TestButton3);   //將按鈕3添加到水平佈局管理器中


    widget->setLayout(hlayout);         //設置widget這個組件的窗口爲hlayout這個佈局管理器管理


    slayout->addWidget(&TestButton1);   //將按鈕1添加到這個棧式佈局管理器中 0

    slayout->addWidget(widget);         //將widget這個窗口組件添加到這個棧式佈局管理器中,這個窗口組件中用水平管理器管理了兩個按鈕 1

    slayout->addWidget(&TestButton4);   //將按鈕4添加到這個棧式佈局管理器中 2


    slayout->setCurrentIndex(1);


    setLayout(slayout);    //設置當前窗口組件是用的棧式佈局管理器



}



Widget::~Widget()

{



}



(4)當時上面的棧式佈局管理器,咱們是用代碼的方式,來指定顯示在頂層的組件是哪個,並不能達到動態的效果,因此接下來咱們就要解決這個問題了



七、計時器的概念


(1)計時器是工程開發中很是重要的角色


(2)計時器用於每一個必定的時間觸發一個消息的


(3)計時器消息最終會被轉化爲函數調用


(4)宏觀上:計時器在每一個時間間隔會調用指定的函數


八、Qt中的計時器(QTimer)在QtCore這個頭文件中


(1)計時器(QTimer)的使用方法


@1:編寫計時器消息處理函數

@2:在程序中建立計時器對象

@3:鏈接計時器消息和消息處理函數(信號和槽,信號就是計時器的消息,槽就是消息處理函數。用connect函數鏈接)

@4:設置計時器時間間隔並啓動計時

(2)在類中聲明這個槽(消息處理函數),未來用來計時器時間到了的時候發消息所觸發的消息處理函數。建立QTimer這個計時器對象,在QtCore這個頭文件中。用connect函數進行信號消息和槽

消息處理函數鏈接,發消息的對象是剛建立的QTimer的對象,信號是timerout()信號,this,槽就是剛纔編寫的消息處理函數。最後啓動計時器,調用start成員函數啓動(start(2000),2S發

計時器時間到發一次消息)


(3)例:計時器的使用


//類中要聲明槽函數

private slots:  //聲明槽函數

    void timetimerout();

//計時器的使用測試

void Widget::testtimer()

{

    QTimer *timer = new QTimer();   //建立一個計時器對象


    connect(timer, SIGNAL(timeout()), this, SLOT(timetimerout())); //timeout()爲計時器的信號


    timer->start(2000); //啓動計時,並設置2S計時時間到

}


//計時器的消息處理函數

void Widget::timetimerout()

{

    qDebug() << "timetimerout";

}



(4)用計時器來完成棧式佈局管理器中的組件的逐個顯示,佈局管理器中的coutn()成員函數能夠獲取當前佈局管理器中管理的組件個數


void Widget::timetimerout()

{

    //layout()函數會將當前組件中的佈局管理器直接返回,當時返回的佈局管理器類型是Layout的指針類型,因此咱們要給裝換成咱們的佈局管理器類型

    QStackedLayout *slayout = dynamic_cast<QStackedLayout*>(layout());


}



(5)例:棧式佈局管理器,和計時器的方式循環顯示棧式佈局管理器中的各個組件


#include "widget.h"

#include <QStackedLayout>   //棧式佈局管理器

#include <QHBoxLayout>  //水平佈局管理器

#include <QtCore>   //使用計時器要包含這個

#include <QDebug>


Widget::Widget(QWidget *parent)

    : QWidget(parent), TestButton1(this), TestButton2(this), TestButton3(this), TestButton4(this)

{

    //testQStackedLayout();

    //testQStacked_QH_Layout();

    //testtimer();

    test_Timer_QStacked_QH_Layout();

}


void Widget::testQStackedLayout()

{

    QStackedLayout *slayout = new QStackedLayout(); //建立一個棧式佈局管理器對象


    TestButton1.setText("Button 1");

    TestButton2.setText("Button 2");

    TestButton3.setText("Button 3");

    TestButton4.setText("Button 4");




    slayout->addWidget(&TestButton1);   //將button1加入到這個棧式佈局管理器中 0

    slayout->addWidget(&TestButton2);   //1

    slayout->addWidget(&TestButton3);   //2

    slayout->addWidget(&TestButton4);   //3


    slayout->setCurrentIndex(1);    //設置當前顯示的組件是第二個組件,0是第一個


    setLayout(slayout);

}


//用棧式佈局管理器,間接地嵌套了水平佈局管理器,依賴一箇中間組件widget,這個組件中有佈局管理器,這個中間組件中的佈局管理器管理的組件的父組件爲

//這個中間組件。以後將這個中間組件加入到棧式的佈局管理器中,這樣就達到了棧式佈局管理器間接的嵌套了其餘佈局管理器,由於棧式佈局管理器中的成員函數

//addWidget().這個添加組件的成員函數,只接受QWidget類型的指針對象。因此只能接受組件,不能接受佈局管理器

void Widget::testQStacked_QH_Layout()

{

    QStackedLayout *slayout = new QStackedLayout(); //建立一個棧式佈局管理器對象

    QHBoxLayout *hlayout = new QHBoxLayout();   //建立一個水平佈局管理器對象

    QWidget *widget = new QWidget();    //建立一個組件對象


    TestButton1.setText("Button 1");

    TestButton2.setText("Button 2");

    TestButton3.setText("Button 3");

    TestButton4.setText("Button 4");


    TestButton2.setParent(widget);      //設置按鈕2的父組件爲新建立的widget對象

    TestButton3.setParent(widget);      //設置按鈕3的父組件爲新建立的widget對象


    hlayout->addWidget(&TestButton2);   //將按鈕2添加到水平佈局管理器中

    hlayout->addWidget(&TestButton3);   //將按鈕3添加到水平佈局管理器中


    widget->setLayout(hlayout);         //設置widget這個組件的窗口爲hlayout這個佈局管理器管理


    slayout->addWidget(&TestButton1);   //將按鈕1添加到這個棧式佈局管理器中 0

    slayout->addWidget(widget);         //將widget這個窗口組件添加到這個棧式佈局管理器中,這個窗口組件中用水平管理器管理了兩個按鈕 1

    slayout->addWidget(&TestButton4);   //將按鈕4添加到這個棧式佈局管理器中 2


    slayout->setCurrentIndex(1);


    setLayout(slayout);    //設置當前窗口組件是用的棧式佈局管理器



}


//計時器的方法,每隔2S來逐個顯示棧式佈局管理器中的組件

void Widget::test_Timer_QStacked_QH_Layout()

{

    QStackedLayout *slayout = new QStackedLayout(); //建立一個棧式佈局管理器對象

    QHBoxLayout *hlayout = new QHBoxLayout();   //建立一個水平佈局管理器對象

    QWidget *widget = new QWidget();    //建立一個組件對象

    QTimer *timer = new QTimer();   //建立一個計時器對象


    TestButton1.setText("Button 1");

    TestButton2.setText("Button 2");

    TestButton3.setText("Button 3");

    TestButton4.setText("Button 4");


    TestButton2.setParent(widget);      //設置按鈕2的父組件爲新建立的widget對象

    TestButton3.setParent(widget);      //設置按鈕3的父組件爲新建立的widget對象


    hlayout->addWidget(&TestButton2);   //將按鈕2添加到水平佈局管理器中

    hlayout->addWidget(&TestButton3);   //將按鈕3添加到水平佈局管理器中


    widget->setLayout(hlayout);         //設置widget這個組件的窗口爲hlayout這個佈局管理器管理


    slayout->addWidget(&TestButton1);   //將按鈕1添加到這個棧式佈局管理器中 0

    slayout->addWidget(widget);         //將widget這個窗口組件添加到這個棧式佈局管理器中,這個窗口組件中用水平管理器管理了兩個按鈕 1

    slayout->addWidget(&TestButton4);   //將按鈕4添加到這個棧式佈局管理器中 2


    slayout->setCurrentIndex(1);


    setLayout(slayout);    //設置當前窗口組件是用的棧式佈局管理器


    connect(timer, SIGNAL(timeout()), this, SLOT(timetimerout()));  //鏈接計時器的信號與槽


    timer->start(2000);     //啓動計時器,並每一個2S發一次消息


}


//計時器的使用測試

void Widget::testtimer()

{

    QTimer *timer = new QTimer();   //建立一個計時器對象


    connect(timer, SIGNAL(timeout()), this, SLOT(timetimerout())); //timeout()爲計時器的信號


    timer->start(2000); //啓動計時,並設置2S計時時間到

}

/*

//計時器的消息處理函數

void Widget::timetimerout()

{

    qDebug() << "timetimerout";

}

*/


//計時器的消息處理函數

void Widget::timetimerout()

{

    //進到計時器的消息處理函數中,由於要循環的顯示棧式佈局管理器中的組件,因此要先獲取這個棧式佈局管理,以達到操做這個棧式佈局管理器

    //layout()函數會將當前組件中的佈局管理器直接返回,可是返回的佈局管理器類型是Layout的指針類型,因此咱們要給裝換成咱們的佈局管理器類型

    QStackedLayout *slayout = dynamic_cast<QStackedLayout*>(layout());


    if ( NULL != slayout )

    {

        //這時證實咱們已經獲得了棧式佈局管理器

        //咱們要取得佈局管理器中的下一個頂層組件的下標

        int index = ((slayout->currentIndex() + 1) % slayout->count());  //前面得到當前的頂層組件下標,+1後爲下一個要顯示的組件下標

                                                                        //count是獲取當前棧式佈局管理器中的組件個數

                                                                        //取餘是爲了防止+1致使的溢出,可讓其一直循環

        slayout->setCurrentIndex(index);    //設置當前要顯示的組件下標

    }

}


Widget::~Widget()

{



}

相關文章
相關標籤/搜索