w99hyun
프로필프로젝트포스트연락처
목록
w99hyun

본 사이트는 개인 포트폴리오 게시용으로 제작되었습니다.

ⓒ 2026. w99hyun(Woohyun Cho) All rights reserved.


QT - C++ ↔ QML connect

원본 글 보기

2025년 11월 12일


QML에서 C++ 객체를 사용하려면?

  • C++ 클래스를 QML 타입으로 등록한다.
  • QML_ELEMENT 매크로 등록을 통해 QML 타입으로 등록하면, QML에서 C++의 함수나 변수에 접근이 가능하다.
  • 헤더에서 함수 원형을 선언할 때, Q_INVOKABLE 매크로를 앞에 붙여주면 QML에서 직접 해당 함수를 호출할 수 있다.
- QT5 에서는

main.cpp의 main 함수에서 qmlRegister가 필요하다
...qmlRegisterType<cpp 클래스명>("프로젝트명", 0, 1, "{QML에서 사용할 네임}");
qmlRegisterType<MessageProcessor>("Course", 0, 1, "MessageProcessor");...
이후, 해당 cpp 파일을 쓸 qml파일에서import {프로젝트명} {버전}을 통해 QML에서 cpp클래스에 정의된 함수를 사용할 수 있다.
import Course 0.1

Q_PROPERTY

  • C++ 클래스의 속성을 QML이나 다른 C++ 클래스에서 사용할 수 있게 노출

  • QML에서 해당 속성의 값을 읽고 쓸 수 있게 되며, 속성 값이 변경될 때 알림을 받을 수 있음

      Q_PROPERTY(Type name READ readFunction WRITE writeFunction NOTIFY notifySignal)
    
      //Type: 속성(프로퍼티)의 데이터타입  //name: 속성의 이름  //READ: 속성 값을 읽는 함수  //WRITE: 속성 값을 설정하는 함수 (선택)  //NOTIFY: 속성 값이 변경될 때 발생하는 시그널 (선택)
  • CONST 키워드

    • 해당 속성이 상수임을 나타냄.
      Q_PROPERTY(QString version READ version CONSTANT)
  • MEMBER 키워드

    • 별도의 읽기/쓰기 함수를 정의하지 않아도 자동으로 읽기/쓰기 제공
      Q_PROPERTY(QString name MEMBER m_name NOTIFY nameChanged)
  • NOTIFY 시그널

    • 속성 값이 변경될 때 발생하는 시그널을 지정
    • 속성 값의 변경을 모니터링 할 수 있음
    • 데이터 바인딩이나 모델-뷰 아키텍처에서 매우 유용

Q_INVOKABLE

  • C++ 클래스의 멤버 함수를 QML에서 호출할 수 있는 메소드로 노출
  • 비즈니스 로직은 C++ 에서 처리하고, QML에서는 View만 제공하도록 함

QObject

  • QObject는 부모-자식 관계를 통해 객체들을 트리 형태로 관리함
  • 부모 객체가 소멸되면 자식 객체도 모두 소멸되어 메모리 누수를 방지함
  • 스레드를 사용할 때는 객체가 생성된 스레드와 동일한 스레드에서 접근해야 함

QAbstractItemModel

  • 프록시 모델, 리스트 모델, 테이블 모델 등을 제공하는 모델 원형
  • 이 클래스를 상속받아 만들어진 여러 모델이나 커스텀 모델을 통해 C++에서 데이터를 관리하고, QML의 UI에서 표현할 수 있음

QAbstractListModel

  • Custom Model을 통한 ListView 생성 예제
/* MyModel.h */

#pragma once#include <QAbstractListModel>
class MyItem {public:    QString name;    QString description;};
class MyModel : public QAbstractListModel{    Q_OBJECTpublic:    enum ItemRoles {        NameRole = Qt::UserRole + 1,        DestiptionRole,    };
explicit MyModel(QObject *parent = nullptr);

int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;

//데이터 추가 함수
Q_INVOKABLE void addItem(const QString &name, const QString &description);

protected:    QHash<int, QByteArray> roleNames() const override;
private:    QList<MyItem> m_items;};
/* MyModel.cpp */
#include "mymodel.h"
MyModel::MyModel(QObject *parent)    : QAbstractListModel{parent}{
}
QVariant MyModel::data(const QModelIndex &index, int role) const{    if (!index.isValid() || index.row() < 0 || index.row() >= m_items.count())    {        return QVariant();    }
const MyItem &item = m_items[index.row()];

switch(role) {
case NameRole:
    return item.name;
case DestiptionRole:
    return item.description;
default:
    return QVariant();
}

}
int MyModel::rowCount(const QModelIndex &parent) const{    return m_items.count();}
void MyModel::addItem(const QString &name, const QString &description){    beginInsertRows(QModelIndex(), rowCount(), rowCount());
MyItem item;
item.name = name;
item.description = description;
m_items << item;

endInsertRows();

}
// beginInsertRows(), endInsertRows() 사이에 있는 아이템에 변화가 생길 경우 UI가 업데이트됨
//RoleEnum 값과 매칭되는 name(qml에서 접근할) 매핑QHash<int, QByteArray> MyModel::roleNames() const{    QHash<int, QByteArray> roles;    roles[NameRole] = "name";    roles[DestiptionRole] = "description";    return roles;}
/* main.qml */
MyModel {    id: myModel}
ListView {    id: listView    anchors.fill: parent    model: myModel
ScrollBar.vertical: ScrollBar {
    id: verticalScrollBar
    width: 14
    policy: ScrollBar.AlwaysOn
}

//List Item Preset
delegate: Item {
    height: column.height + 10

    Column {
        id: column

        Text {
            text:model.name
            font.bold: true
        }

        Text {
            text:model.description
            color: "lightpink"
        }
    }
}

Component.onCompleted: {
    // 어플리케이션이 시작될 때 항목 추가
    myModel.addItem("Item1", "This is the first item.")

    for (var i = 0; i < 20; i++)
    {
        myModel.addItem("item" + i, "This is " +i+ " item.")
    }
}

}

이전 글

유니티 UI 최상위 렌더링 (Render Objects)

2025년 11월 15일

다음 글

QT - QML summary

2025년 11월 10일