qml c++에서 선언한 enum 사용하기

김준형·2024년 1월 24일

c++에서 선언한 enum값을 qml에서 사용하는 방법에 대해 말해보겠습니다.
enum을 사용하면 코드가 단순해지며 가독성이 좋습니다. 정의를 잘해놓으면 여러 곳에서 사용할 수 있어서 좋습니다. 코드 사이즈가 큰 경우 한 곳에서 관련된 값들을 확인할 수 있습니다.
이러한 장점이 있는 enum을 qml에서도 같이 사용 할 수 있게하여 보다 가독성있고 코드가 단순해질 수 있습니다.

아래 예제를 확인합니다.

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "mainclass.h"

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

    QQmlApplicationEngine engine;
    MainClass mainClass(&engine, &app);

    return mainClass.load();
}

enumClass.h

#ifndef ENUMCLASS_H
#define ENUMCLASS_H
#include <QObject>

class EnumClass : public QObject
{
    Q_OBJECT
 public:
    enum Trinfo
    {
        TRINFO_KOR,
        TRINFO_ENG
    };
    Q_ENUMS(Trinfo)
};

#endif // ENUMCLASS_H

mainclass.h

#ifndef MAINCLASS_H
#define MAINCLASS_H

#include <QObject>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "enumClass.h"

class MainClass : public QObject
{
    Q_OBJECT
public:
    explicit MainClass(QObject *parent = nullptr);
    MainClass(QQmlApplicationEngine *engine, QGuiApplication *app);
    int load();
signals:

public slots:

private:
    QGuiApplication *_app;
    QQmlApplicationEngine *_engine;
};

#endif // MAINCLASS_H

mainclass.cpp

#include "mainclass.h"
#include <QDebug>

MainClass::MainClass(QObject *parent) : QObject(parent)
{
}

MainClass::MainClass(QQmlApplicationEngine *engine, QGuiApplication *app)
{
    _app = app;
    _engine = engine;
}

int MainClass::load()
{
    qmlRegisterType<EnumClass>("qml.register", 1, 0, "EnumClass");
    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);
    return _app->exec();
}

위에 enumClass.h를 보면 Enum들로 정의하려는 목적의 class를 만들고 class내부에 enum을 정의 후 Q_ENUMS에 선언한 enum을 넣어주었습니다. 간단하게 말하면 Q_ENUMS을 사용하면 QML에 enum을 사용하겠다라는 의미라고 보면됩니다.
하지만 Q_ENUMS를 사용한다고해서 무조건 QML에서 사용할 수는 없습니다.

mainclass.cpp를 보면 qmlRegisterType("qml.register", 1, 0, "EnumClass"); 코드가 있는데 qmlRegisterType은 Qt에서 c++클래스를 QML에서 사용 가능하게 등록하는 함수입니다. 는 EnumClass를 넣고 "qml.register"는 qml에서 사용할 수 있는 타입, 1은 메이저 버전, 0은 마이너버전 마지막으로 "EnumClass"는 qml에서 사용하는 타입네임입니다.
이제 선언했으니 qml코드를 확인합니다.

main.qml

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Layouts 1.12
import QtQuick.Controls 1.4
import qml.register 1.0


Window {
	visible: true
	width: 640
	height: 480
    title: qsTr("Hello") + ": " + EnumClass.TRINFO_KOR

	Component.onCompleted: {
        busyIndicator.running = true
        workerScript.sendMessage({'listmodel': listmodel})
	}

	ListModel {
        id: listmodel
	}

    WorkerScript {
        id: workerScript
        source: "listModelWorkerScript.js"
        onMessage: {
            console.log(messageObject.finish)
            if(messageObject.finish) {
                busyIndicator.running = false
            }
        }
    }

	CustomTableView {
		id: customTableView
		anchors.fill: parent
        model: listmodel
	}

    BusyIndicator {
        id: busyIndicator
        anchors.centerIn: parent
        running: false
    }
}

qmlRegisterType에 등록한걸 기반으로 qml에서 해당 enum을 사용하기 위해 import qml.register 1.0으로 선언하여 나 해당 enumclass 사용하겠다라는 의미입니다.
title: qsTr("Hello") + ": " + EnumClass.TRINFO_KOR 코드를 보면 Hello 뒤에 enumClass.h 선언한 Trinfo enum값인 TRINFO_KOR를 사용했습니다.

이런식으로 qml에서도 c++ header에 정의된 enum을 사용할 수 있는 예제를 보여드렸습니다.

profile
안녕하세요 QT,QML 개발자입니다.

0개의 댓글