ふるお〜と!- FullAuto

AI・ロボットが普及しBI(ベーシックインカム)が早急に実現されることを願う元ニートのブログ

ふるお〜と!-FullAuto

Qt Quick 入門 改

GUIは基本的にユーザからの入力(イベント)に応じて処理をするイベントドリブンなインターフェースです。

Visual Studioだとフォームアプリケーションを作り、ボタンをデザイナ上に配置しボタンをダブルクリックすると、 ボタンクリックイベントが発生した際に処理されるスニペットを自動で作ってくれます。

Windows Formアプリケーションの場合

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Button1_Click(object sender, EventArgs e)
        {

        }
    }
}

ではQt Quickはどうか
「ファイル」→「新しいプロジェクト」→「Qt Quick Application - Empty」→デフォルトで次へ
そしてデザイナを表示させるとこうなります。f:id:nullpo24:20200930135233p:plain

なんとデフォルトだとボタンがない。
ボタンなどのコントロールツールを追加するにはmain.qmlに下記を追記します。

main.qml

import QtQuick.Controls 2.xx

xxの部分はタイピングしてインテリセンスに従うのがベター。 f:id:nullpo24:20200930135815p:plain ヨシ!これでボタンをダブルクリックしてスニペットを作成だ!!
というわけにはいかない。

自分で作る必要があります。

1.C++

「ファイル」→「新しいファイル」→「C++ヘッダーファイル」でhelloworld.hを作成する。

#ifndef HELLWORLD_H
#define HELLWORLD_H

#endif // HELLWORLD_H

クラスの宣言し、 button1_clickメソッドを作成する。

#ifndef HELLWORLD_H
#define HELLWORLD_H

#include <QObject>
#include <QString>

class HelloWorld:public QObject
{
    Q_OBJECT
public:
    Q_INVOKABLE QString button1_click(){
        qDebug("Hello world");
    }
};

#endif // HELLWORLD_H

補足

QObjectを継承し、 Q_OBJECTマクロを使う。
GUIの実装は大変めんくさい。
イベントオブジェクト、シグナリングの実装をしなければならない。
残念ながらC++の標準ライブラリ(STL)にはイベントオブジェクトの規定はない。
QObjectを継承することによって実装を簡便にすることができる。

2.QML

button1_clickメソッドが実行されるようにする。
どのようなシグナル(イベント)が定義されているかは
https://doc.qt.io/qt-5/qml-qtquick-controls2-button.html を参照する。
参照してくなれければ'on'とタイプすればインテリセンスが教えてくれます。
呼び出すためには
{登録名称}.{メソッド名}()
で記述します。

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Button {
        id: button
        x: 77
        y: 57
        text: qsTr("Button")
        onClicked: hello.button1_click()
    }
}

3.紐付け(イベント登録)

紐付けにはsetContextPropertyを使います(#include <QQmlContext>)。
オブジェクトhelloworldを
helloとして登録。

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "helloworld.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    HelloWorld helloworld;
    engine.rootContext()->setContextProperty("hello",&helloworld);

    return app.exec();
}

実行

実行してボタンをクリックするとアプリケーション出力に"hello world"と出力されます。 f:id:nullpo24:20200930144955p:plain