Widgetsチュートリアル

WidgetsはGUIアプリケーションを構成するための基本ブロックとなる。それぞれのコンポーネントはユーザーインターフェースWindowのどこかに配置されるWidgetsであし、独立したwindowとして描画される。様々なwidgetsの種類は Qwidget のサブクラスとして提供されている。

Qwidget は抽象クラスではなく、他のwidgetsのコンテナとなり、新しいwidgetsを作るときにも簡単にサブクラス化することができる。 QWidgetQWidget を含む新しいWindowを作るときによく使われる。

0. Main Function

#include <iostream>
#include <QtWidgets>

int main(int argc, char **argv){
    QApplication app(argc, argv);
    // QApplicationはQtにコマンドライン引数を渡すための関数であり、一番最初に実行される。
    // widgetsが作られた後に、QApplication.exec()でQtのメインループが始まる.

    return app.exec();
}

1. Windowを作る。

リファレンス( window )

#include <iostream>
#include <QtWidgets>

int main(int argc, char **argv){
    QApplication app(argc, argv);
    QWidget w;
    w.resize(320, 240);
    w.show();
    w.setWindowTitle(
             QApplication::translate("toplevel", "Top-level widgets"));


    return app.exec();
}

2. 子Widgetsを作る。

#include <iostream>
#include <QtWidgets>

int main(int argc, char **argv){
    QApplication app(argc, argv);
    QWidget w;
    w.resize(320, 320);
    w.setWindowTitle(QApplication::translate("childwidget", "Child widget"));
    w.show();

    QPushButton *b =
        new QPushButton(QApplication::translate("childewidget", "Press me"), &w);
    b->move(100, 100);
    b->show();

    QPushButton *b2 =
        new QPushButton(QApplication::translate("childewidget", "Press me"), &w);
    b2->move(200, 100);
    b2->show();

    
    return app.exec();
}

3. Layoutsの使い方

一般的に、場所やサイズを明示的に指定するより、子widgetsはlayoutオブジェクトを用いて配置される。ここでは、ラベルとedit窓を並べた例を示す。

#include <iostream>
#include <QtWidgets>

int main(int argc, char **argv){
    QApplication app(argc, argv);
    QWidget w;
    QLabel *l = new QLabel(QApplication::translate("windowlayout","Name:"));
    QLineEdit *le = new QLineEdit();

    QHBoxLayout *lyt = new QHBoxLayout();
    lyt->addWidget(l);
    lyt->addWidget(le);
    w.setLayout(lyt);
    w.setWindowTitle(QApplication::translate("windowlayout","Window layout:"));
    w.show();
    
    return app.exec();
}

このlayoutオブジェクトは addWidget() 関数で提供される配置とサイズの情報を操作することができる。レイアウト自体は、 setLayout() を呼び出すことによって作ることができる。

上記の例では、オブジェクトの所属が明らかではない。親オブジェクトなしで、widgetsやlaytouを作成したので、ラベルを含むウィンドウとedit窓を含むウィンドウの二つができると思ってしまうかもしれない。しかし、レイアウトにラベルとエディットの操作を伝え、windowにlayoutをセットすると、二つのWidgetsとレイアウト自体はウィンドウの子となるために再親化(reparented:親なし->親がwindow)される。

4. ネスト化されたLayouts

3.のようにwidgetsに他のwidgetsを埋め込むことができる。そして、layoutsはwidgetsをグループ化するために異なるレベルを提供している。ここでは、先の例に加え、さらにクエリーの結果を示す表を付け加える。

上記の例を実行するために、二つのLayoutを作る。queryLytは QHBoxLayout であり、これは QLabelQLineEdit を並んで配置する。mainLytは QVBoxLayout であり、queryLytと QTableView を垂直に配置する。

#include <iostream>
#include <QtWidgets>

int main(int argc, char **argv){
    QApplication app(argc, argv);
    QWidget w;
    QLabel *ql = new QLabel(QApplication::translate("nestedlayouts","Query:"));
    QLineEdit *qe = new QLineEdit();
    QTableView *resultView = new QTableView();

    QHBoxLayout *queryLyt = new QHBoxLayout();
    queryLyt->addWidget(ql);
    queryLyt->addWidget(qe);    
    
    QVBoxLayout *mainLyt = new QVBoxLayout();
    mainLyt->addLayout(queryLyt);
    mainLyt->addWidget(resultView);
    w.setLayout(mainLyt);
    w.setWindowTitle(QApplication::translate("nestedlayouts","Nested layout:"));
    w.show();


    return app.exec();
}

注意する点は、mainLytの addLayout() 関数であり、この関数はresultViewの上にqueryLytを配置している。

ここの例では、QTableViewによってmodelデータが示されていないが、下のコードを実行することで完璧な例を実行することができる。

QHBoxLayoutQVBoxLayout と同様に、より複雑なインターフェースを実行すために、Qtは QGridLayoutQFormLayout クラスの提供もしている。

#include <iostream>
#include <QtWidgets>

int main(int argc, char **argv){
    QApplication app(argc, argv);
    QWidget w;
    QLabel *ql = new QLabel(QApplication::translate("nestedlayouts","Query:"));
    QLineEdit *qe = new QLineEdit();
    QTableView *resultView = new QTableView();

    QHBoxLayout *queryLyt = new QHBoxLayout();
    queryLyt->addWidget(ql);
    queryLyt->addWidget(qe);    
    

    // -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
    QStandardItemModel m;
    m.setHorizontalHeaderLabels(QStringList()
                                << QApplication::translate("nestedlayouts","Name")
                                << QApplication::translate("nestedlayouts","Office"));
    
    QList<QStringList> rows = QList<QStringList>()
        << (QStringList() << "Verne Nilsen" << "123")
        << (QStringList() << "Carlos Tang" << "77")
        << (QStringList() << "Bronwyn Hawcroft" << "119")
        << (QStringList() << "Alessandro Hanssen" << "32")
        << (QStringList() << "Andrew John Bakken" << "54")
        << (QStringList() << "Vansessa Weatherley" << "85")
        << (QStringList() << "Revecca Dickens" << "17")
        << (QStringList() << "David Bradley" << "42")
        << (QStringList() << "Knut Walters" << "25")
        << (QStringList() << "Andrea Jones" << "34");

    foreach(QStringList row, rows){
        QList<QStandardItem *> items;
        foreach (QString text, row)
            items.append(new QStandardItem(text));
        m.appendRow(items);
    }
    resultView->setModel(&m);

    resultView->verticalHeader()->hide();
    resultView->horizontalHeader()->setStretchLastSection(true);
    // -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-

    QVBoxLayout *mainLyt = new QVBoxLayout();
    mainLyt->addLayout(queryLyt);
    mainLyt->addWidget(resultView);
    w.setLayout(mainLyt);
    w.setWindowTitle(QApplication::translate("nestedlayouts","Nested layout:"));
    w.show();


    return app.exec();
}