C++ 入門指南 - QGridLayout

QGridLayout 的作法是把視窗分成一個一個的格子 (grid) ,然後把小工具 (widget) 放到選定的格子中,可依視窗元件的大小設定佔用的格子數




當建立 QGridLayout 排版物件 (object) 後,利用 addWidget() 方法加入小工具物件時,第一個參數 (parameter) 為小工具物件,其後兩個參數為小工具在視窗中的座標,若需要佔用多個格子,例如向右延伸多格,就得提供更多的參數。


我們設置一個 GUIDemo 專案,標頭檔 GUIDemo.h 如下
#ifndef GUIDEMO_H
#define GUIDEMO_H

#include <QWidget>

class QLabel;
class QLineEdit;
class QPushButton;

class GUIDemo : public QWidget {
    Q_OBJECT

public:
    GUIDemo(QWidget *parent = 0);

private:
    QLabel *display;
    QLineEdit *inputField;
    QLineEdit *outputField;
    QPushButton *newButton;
    QPushButton *loadButton;
    QPushButton *saveButton;
    QPushButton *encodeButton;
    QPushButton *decodeButton;
    QPushButton *clearButton;
    QPushButton *copyButton;
};

#endif

/* 《程式語言教學誌》的範例程式
    http://pydoing.blogspot.com/
    檔名:GUIDemo.h
    功能:示範 C++ 程式 
    作者:張凱慶
    時間:西元 2012 年 10 月 */


這裡把十個小工具設計成 GUIDemo 的變數成員 (variable member) ,這是因為這些小工具會與使用者的鍵盤輸入或滑鼠點擊產生反應。其他還有兩個 QLabel ,也就是放在 inputField 與 outputField 之前 Input:Output: ,因為與使用者操作無關,所以我們在建構子 (constructor) 中再建立就可以了。


實作檔 GUIDemo.cpp 如下
#include <QtGui>
#include "GUIDemo.h"

GUIDemo::GUIDemo(QWidget *parent) : QWidget(parent) {
    QLabel *input = new QLabel(tr("Input:"));
    QLabel *output = new QLabel(tr("Output:"));
    display = new QLabel(tr("something happened"));
    
    inputField = new QLineEdit;
    outputField = new QLineEdit;
    outputField->setReadOnly(true);
    
    newButton = new QPushButton(tr("New"));
    loadButton = new QPushButton(tr("Load"));
    saveButton = new QPushButton(tr("Save"));
    encodeButton = new QPushButton(tr("Encode"));
    decodeButton = new QPushButton(tr("Decode"));
    clearButton = new QPushButton(tr("Clear"));
    copyButton = new QPushButton(tr("Copy"));
    
    QGridLayout *layout = new QGridLayout;
    
    layout->addWidget(input, 0, 0);
    layout->addWidget(inputField, 0, 1, 1, 6, 0);
    
    layout->addWidget(output, 1, 0);
    layout->addWidget(outputField, 1, 1, 1, 6, 0);
    
    layout->addWidget(newButton, 2, 0);
    layout->addWidget(loadButton, 2, 1);
    layout->addWidget(saveButton, 2, 2);
    layout->addWidget(encodeButton, 2, 3);
    layout->addWidget(decodeButton, 2, 4);
    layout->addWidget(clearButton, 2, 5);
    layout->addWidget(copyButton, 2, 6);
    
    layout->addWidget(display, 3, 0, 1, 7, 0);
    
    setLayout(layout);
    setWindowTitle(tr("GUIDemo"));
} 

/* 《程式語言教學誌》的範例程式
    http://pydoing.blogspot.com/
    檔名:GUIDemo.cpp
    功能:示範 C++ 程式 
    作者:張凱慶
    時間:西元 2012 年 10 月 */


我們先看到第 11 行
outputField->setReadOnly(true);


由於我們不想要使用者在 outputField 輸入任何資料,因此建立完 outputField 呼叫 setReadOnly() ,將其設定成唯讀狀態。


然後看到 addWidget() 的部份,左上角第一格座標為 (0, 0) ,也就是第一橫列第一直行的位置,而第一橫列第一直行的座標為 (0, 1) ,第二橫列第一直行的座標為 (1, 0) ,第二橫列第二直行的座標為 (1, 1) ,餘下可類推
layout->addWidget(input, 0, 0);
layout->addWidget(inputField, 0, 1, 1, 6);
    
layout->addWidget(output, 1, 0);
layout->addWidget(outputField, 1, 1, 1, 6);
    
layout->addWidget(newButton, 2, 0);
layout->addWidget(loadButton, 2, 1);
layout->addWidget(saveButton, 2, 2);
layout->addWidget(encodeButton, 2, 3);
layout->addWidget(decodeButton, 2, 4);
layout->addWidget(clearButton, 2, 5);
layout->addWidget(copyButton, 2, 6);
    
layout->addWidget(display, 3, 0, 1, 7);


當格數需要跨越多行時,就需要額外提供三個參數,例如 display 在第四橫列第一直行,因此第二個參數為 3 ,第三個參數為 0 ,第四個參數為垂直延伸格數,此處為 1 ,第五個參數為水平延伸格數,此處為 7
layout->addWidget(display, 3, 0, 1, 7);


概念很簡單吧! GUIDemo 專案的 main.cpp 如下
#include <QtGui>
#include "GUIDemo.h"

int main(int argv, char **args)
{
    QApplication app(argv, args);

    GUIDemo demo;
    demo.show();

    return app.exec();
}

/* 《程式語言教學誌》的範例程式
    http://pydoing.blogspot.com/
    檔名:main.cpp
    功能:示範 C++ 程式 
    作者:張凱慶
    時間:西元 2012 年 10 月 */


編譯執行結果如下



好了, GUI 的外觀做出來了,可是按鈕還是沒反應呀!這是因為我們還沒設定 SIGNAL 與 SLOT


中英文術語對照
格子grid
小工具widget
物件object
參數parameter
變數成員variable member
建構子constructor


您可以繼續參考
GUI 篇


相關目錄
回 C++ 入門指南
回 C++ 教材目錄
回首頁


參考資料
Qt Developer Network
Layout Management

沒有留言: