QT之佈局

QT主要佈局類型

QT中主要提供了QLayout類及其子類作爲佈局管理器,如下圖所示主要的佈局類及其繼承關係
在這裏插入圖片描述
所有的QWidget類的子類的實例都可以使用佈局管理器來管理位於它們之中的子部件,QWidget::setLayout()函數可以在一個部件上應用佈局管理器。
一旦一個部件上設置了佈局管理器,那麼它會完成以下幾種任務:

  • 定位子部件
  • 感知窗口默認大小
  • 感知窗口最小大小
  • 改變大小處理
  • 內容改變時自動更新:字體大小,文本或子部件的其他內容隨之改變、隱藏或顯示子部件、移除子部件
  • 當部件加入到一個佈局管理器中,然後這個佈局管理器再放到一個窗口部件上時,這個佈局管理器以及它包含的所有部件都會自動重新定義自己的父對象(parent)爲這個窗口部件,所以在創建佈局管理器和其中的部件時並不用指定父部件。

佈局管理器

QLayout類是佈局管理器的基類,它是一個抽象基類。該類繼承自QObject和QLayoutItem類,而QLayoutItem類提供了一個供QLayout操作的抽象項目。 QLayout和QLayoutItem都是在設計自己的佈局管理器時才使用,有一些常用的佈局管理器:

  • QBoxLayout(基本佈局管理器)
  • QGridLayout(柵格佈局管理器)
  • QFormLayout(窗體佈局管理器)
  • QStackedLayout(棧佈局管理器)
    下面詳細介紹每一個佈局管理器,以及如何使用。

QBoxLayout(基本佈局管理器)

基本佈局管理器QBoxLayout類可以使子部件在水平方向或者垂直方向排成一列,它有兩個子類QHBoxLayout水平佈局管理器和QVBoxLayout垂直佈局管理器。

  • QHBoxLayout:水平佈局,放入此佈局的部件,將按照水平方式排列
  • QVBoxLayout:垂直佈局,放入此佈局的部件,將按照垂直方式排列
    以下是一些基本屬性的設置:
QHBoxLayout *layout = new QHBoxLayout;      // 新建水平佈局管理器
layout->addWidget(ui->textEdit);			// 向佈局管理器中添加部件
layout->setSpacing(50);                     // 設置部件間的間隔,所有的部件之間都是這個間距
layout->setContentsMargins(0, 0, 50, 100);  // 設置佈局管理器到邊界的距離,
                                            // 四個參數順序是左,上,右,下
layout->addSpacing(50);						// 與setSpacing不一樣,僅僅是前後兩個的間距
layout->addStretch();						// 增加一個可伸縮空間
setLayout(layout);							// 在父窗口添加布局管理器

QGridLayout(柵格佈局管理器)

柵格佈局管理器,它將所有的空間分隔成一些行和列,行和列的交叉處就形成了單元格,然後將部件放入一個確定的單元格中,示例代碼如下:

QGridLayout *layout = new QGridLayout;
// 添加部件,從第0行0列開始,佔據1行2列
layout->addWidget(ui->fontComboBox, 0, 0, 1, 2);
// 添加部件,從第0行2列開始,佔據1行1列
layout->addWidget(ui->pushButton, 0, 2, 1, 1);
// 添加部件,從第1行0列開始,佔據1行3列
layout->addWidget(ui->textEdit, 1, 0, 1, 3);
setLayout(layout);

QFormLayout(表單佈局管理器)

表單佈局管理器QFormLayout類用來管理表單的輸入部件和與它們相關的標籤,它將子部件分爲兩列,左邊是一些標籤,右邊是一些輸入部件,比如行編輯器或者數字選擇框等,左右兩邊有對應關係。
在設計模式,從部件欄中找到Form Layout,將其拖入到界面上,然後雙擊它,或者在它上面點擊鼠標右鍵,選擇“添加窗體佈局行”菜單。
然後在彈出的“添加表單佈局行”對話框中填入標籤文字,這樣下面便自動填寫了“標籤名稱”、“字段類型”和“字段名稱”等,並且設置了夥伴關係。
夥伴關係表示當按下“Alt+設置標籤的快捷字母,即(&符號後面的字母)“”時,光標會自動跳轉到標籤後面對應的行編輯器中。

QStackedLayout(棧式佈局管理器)

QStackedLayout棧式佈局管理器管理的所有組件在垂直於屏幕的方向上,每次只有一個界面組件會顯示在屏幕上,只要最頂層的界面組件會被顯示。 QStackedLayout棧式佈局管理器的特點如下:

  • 組件大小一致,且充滿父組件的顯示區
  • 不能直接嵌套其它佈局管理器
  • 能夠自由切換需要顯示的組件
  • 每次僅能顯示一個界面組件
void LayoutWidget::StackedLayout()
 {
     //創建組件並設置顯示標籤
     QPushButton *button1 = new QPushButton();
     QPushButton *button2 = new QPushButton();
     QPushButton *button3 = new QPushButton();
     QPushButton *button4 = new QPushButton();
     button1->setText("1st");
     button2->setText("2rd");
     button3->setText("3th");
     button4->setText("4th");
     //創建棧式佈局管理器並添加組件
     sLayout = new QStackedLayout();
     sLayout->addWidget(button1);
     sLayout->addWidget(button2);
     sLayout->addWidget(button3);
     sLayout->addWidget(button4);
     //設置當前棧頂顯示的組件

     connect(button1, &QPushButton::clicked, this, &LayoutWidget::btn1_clicked);
     connect(button2, &QPushButton::clicked, this, &LayoutWidget::btn2_clicked);
     connect(button3, &QPushButton::clicked, this, &LayoutWidget::btn3_clicked);
     connect(button4, &QPushButton::clicked, this, &LayoutWidget::btn4_clicked);

     sLayout->setCurrentIndex(0);
     //設置棧式佈局管理器到窗口
     setLayout(sLayout);
 }

void LayoutWidget::btn1_clicked()
{
    sLayout->setCurrentIndex(1);
}

void LayoutWidget::btn2_clicked()
{
    sLayout->setCurrentIndex(2);
}

void LayoutWidget::btn3_clicked()
{
    sLayout->setCurrentIndex(3);
}

void LayoutWidget::btn4_clicked()
{
    sLayout->setCurrentIndex(0);
}

QSplitter(分裂器)

它和QBoxLayout很相似,可以完成佈局管理器的功能,但是包含在它裏面的部件,默認是可以隨着分裂器的大小變化而進行相應大小變化的。QSplitter有以下特點

  • 一個按鈕,放在佈局管理器中,它的垂直方向默認是不會被拉伸的,但是放到分裂器中就可以被拉伸
  • 佈局管理器是繼承自QObject類的,而分裂器卻是繼承自QFrame類,QFrame類又是繼承自QWidget類,也就是說分裂器擁有QWidget類的特性,它是可見的,而且可以像QFrame一樣設置邊框。
  • 分離器能通過鼠標拖拽調整兩個窗口的大小
QSplitter *splitterMain = new QSplitter(Qt::Horizontal,0);
QTextEdit *textLeft = new QTextEdit(QObject::tr("Left Widget"),splitterMain);
textLeft->setAlignment(Qt::AlignCenter);
//右部分分割窗口
QSplitter *splitterRight = new QSplitter(Qt::Vertical,splitterMain);
splitterRight->setOpaqueResize(true);
//表示分割窗口拖拽時邊界是否實時顯示
QTextEdit *textUp = new QTextEdit(QObject::tr("Top Widget"),splitterRight);
textUp->setAlignment(Qt::AlignCenter);
QTextEdit *textBottom = new QTextEdit(QObject::tr("Bottom Widget"),splitterRight);
textBottom->setAlignment(Qt::AlignCenter);
splitterMain->setStretchFactor(1,1);    
//SetStretchFactor()方法用於設定可伸縮控件,它的第一個參數指定設置的控件序號,
//控件序號按插入的先後次序進行編號;第二個參數爲大於0的值表示此控件爲可伸縮控件。
splitterMain->setWindowTitle(QObject::tr("Splitter"));

佈局策略

設置部件大小

凡是繼承自QWidget的類都有這兩個屬性:大小提示(sizeHint)和最小大小提示(minimumSizeHint)。

  • sizeHint屬性保存了部件的建議大小,對於不同的部件,默認擁有不同的sizeHint,程序中使用sizeHint()函數來獲取sizeHint的值
  • minimumSizeHint保存了一個建議的最小大小。程序中可以使用minimumSizeHint()函數來獲取minimumSizeHint的值 。
  • 如果使用minimumSize()函數設置了部件的最小大小,那麼最小大小提示將會被忽略。
    部件大小的策略屬性有以下幾種選擇
    在這裏插入圖片描述

伸縮因子 stretch factor

它是用來設置部件間的比例的。

例如,界面上的字體選擇框和一個按鈕處於一個水平佈局管理器中,現在想讓它們的寬度比例爲2:1,
那麼就可以點擊對象欄中的horizontalLayout水平佈局管理器對象,然後在它的屬性欄中將layoutStretch屬性設置爲“2,1”,這樣這個水平佈局管理器中的兩個部件的寬度就是2:1的比例了。

如果要在代碼中進行設置,可以在使用佈局管理器的addWidget()函數添加部件的同時,在第二個參數中指定伸縮因子。

設置夥伴關係

夥伴(buddy)是在QLabel類中提出的一個概念。
因爲一個標籤經常用作一個交互式部件的說明,就像表單佈局管理器時看到的那樣,一個lineEdit部件前面有一個標籤說明這個lineEdit的作用。爲了方便定位,QLabel提供了一個有用的機制,那就是提供了助記符來設置鍵盤焦點到對應的部件上,而這個部件就叫做這個QLabel的夥伴。
其中助記符就是我們所說的加速鍵。在使用英文標籤時,在字符串的一個字母前面添加“&”符號,那麼就可以指定這個標籤的加速鍵是Alt加上這個字母,而對於中文,需要在小括號中指定加速鍵字母。

設置TAB鍵順序

對於一個應用程序,當希望使用Tab鍵來將焦點從一個部件移動到下一個部件。在設計模式,設計器提供了Tab鍵的設置功能。在UI設計模式中,按下上邊欄的編輯Tab順序按鈕進入編輯Tab鍵順序模式,這時已經顯示出了各個部件的Tab鍵順序,只需要用鼠標點擊這些數字,就可以更改它們。
代碼實現方式如下:

//lineEdit在spinBox前面
setTabOrder(ui->lineEdit,ui->spinBox);   
//spinBox在pushButton前面
setTabOrder(ui->spinBox,ui->pushButton);   
//pushButton在checkBox前面
setTabOrder(ui->pushButton,ui->checkBox);  

整體與局部佈局

對於一個APP應用,需要最開始框架一層層深入到交互的每一層窗口,每個窗口使用哪些部件元素,如何佈局,需要花一點心思,但是總體思路是框架設計由整體到局部,佈局細化由局部到整體,儘量在每一層的局部就把佈局昨晚,這樣每一層只關心同等層次的佈局,與軟件開發類似。
本篇文章借用了QT社區的一些內容,歡迎訪問Qt開源社區

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章