티스토리 뷰

개발/QT, QML

[QT,QML] C++과 QML 간의 시그널-슬롯 통신

부캐: 개발하는 조대리 2024. 11. 8. 08:47
반응형

C++과 QML 간의 시그널-슬롯 통신

C++ 클래스에서 시그널을 정의하고, 이를 QML에서 사용하여 UI 갱신 또는 유저 인터페이스의 동적 반응을 처리할 수 있습니다. C++에서 시그널을 발생시키고, QML에서 이를 받아 처리하기 위해 Connections 객체를 사용합니다.

 

 

 

 C++ 클래스에서 시그널 정의

먼저, C++ 클래스에서 시그널을 정의해야 합니다. 이 시그널은 QML에서 연결되어 사용할 수 있습니다.

#include <QObject>

class MyBackend : public QObject {
    Q_OBJECT

public:
    explicit MyBackend(QObject *parent = nullptr) : QObject(parent) {}

    void triggerUpdate() {
        emit updateSignal(); // C++에서 시그널 발생
    }

signals:
    void updateSignal(); // QML에서 연결할 시그널
};
  • updateSignal() 시그널: 이 시그널은 QML에서 받아 처리할 시그널입니다.
  • triggerUpdate() 함수: 이 함수는 시그널을 발생시키기 위해 사용됩니다. 애플리케이션의 특정 이벤트(버튼 클릭, 데이터 변경 등)에 따라 호출됩니다.

 

 

 

 C++ 객체를 QML에 노출

QML에서 C++ 객체를 사용하려면, 해당 객체를 QML 엔진에 노출해야 합니다. 아래와 같이 QML 컨텍스트에 등록합니다.

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

int main(int argc, char *argv[]) {
    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;

    MyBackend backend;

    // C++ 객체를 QML에 등록
    engine.rootContext()->setContextProperty("backend", &backend);

    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}
  • engine.rootContext()->setContextProperty("backend", &backend): "backend"라는 이름으로 C++ 객체를 QML에서 사용할 수 있도록 등록합니다.

 

 

 

 QML에서 Connections 객체를 사용해 C++ 시그널 처리

이제 QML에서 C++ 객체의 시그널을 Connections를 통해 처리할 수 있습니다.

import QtQuick 2.15
import QtQuick.Controls 2.15

ApplicationWindow {
    visible: true
    width: 640
    height: 480

    Button {
        text: "Trigger C++ Signal"
        anchors.centerIn: parent
        onClicked: {
            backend.triggerUpdate() // C++ 함수 호출하여 시그널 발생
        }
    }

    Connections {
        target: backend
        onUpdateSignal: {
            console.log("Received update signal from C++")
        }
    }
}

설명

  1. C++ 시그널 발생:
    • Button을 클릭하면 backend.triggerUpdate()를 호출하여 C++에서 updateSignal() 시그널을 발생시킵니다.
  2. Connections 객체로 시그널 처리:
    • Connections 객체를 사용하여 **target**을 "backend"로 설정하고, onUpdateSignal 핸들러를 정의합니다.
    • C++에서 updateSignal이 발생하면 onUpdateSignal 핸들러가 호출되어 QML UI에서 처리됩니다. 이 경우, 콘솔에 메시지가 출력됩니다.

 

 

 

 활용 사례

  • 데이터 갱신: C++에서 데이터가 변경될 때 이를 QML로 전달하여 UI가 자동으로 갱신되도록 할 수 있습니다. 예를 들어, 데이터베이스에서 새로운 정보를 받아왔을 때 QML UI에 반영하는 경우.
  • 이벤트 알림: C++ 백엔드에서 발생한 이벤트(네트워크 응답, 센서 데이터 수신 등)를 QML에서 처리하여 UI에 반영하는 데 사용할 수 있습니다.
  • 상호작용 처리: C++에서의 복잡한 로직 처리를 마친 후 결과를 QML에 전달하여, 사용자가 이를 즉각적으로 UI를 통해 확인할 수 있게 합니다.

 

 

 

 주의사항

  • 타이밍 이슈: C++에서 시그널을 발생시킨 후 QML에서 그 시그널을 받는 과정에서 타이밍 문제가 발생할 수 있습니다. QML 객체가 시그널 발생 전에 준비되지 않은 경우 시그널을 놓칠 수 있습니다. 이를 방지하려면, 객체가 적절히 초기화된 후 시그널이 발생하도록 해야 합니다.
  • 메모리 관리: C++에서 생성한 객체의 수명을 잘 관리해야 합니다. QML에 등록된 객체가 해제될 때, 시그널을 발생시키면 잘못된 메모리 접근이 발생할 수 있으므로 객체의 생명 주기를 명확히 이해하고 관리하는 것이 중요합니다.

 

 

 

 결론

  • QML의 Connections 객체는 C++에서 발생하는 시그널을 UI에서 처리하는 매우 강력한 도구입니다.
  • 이를 통해 백엔드 로직(C++)과 프론트엔드(QML) 간의 상호작용을 쉽게 구현하고, UI와 데이터의 연동을 효과적으로 관리할 수 있습니다.
  • Connections를 활용하면 유연하고 유지보수 가능한 코드 구조를 만들 수 있으며, C++의 복잡한 로직을 QML의 간결한 UI와 잘 결합할 수 있습니다.

 


 

 

개인적으로 학습하면서 정리한 내용입니다.
잘못된 내용이 있을 경우 알려주시면 확인 후 수정 및 반영하도록 하겠습니다.

오늘도 감사합니다.(__)

 

 

 

'개발 > QT, QML' 카테고리의 다른 글

QML의 positionViewAtIndex 함수  (0) 2024.11.10
[QT,QML] Qt의 QAbstractListModel  (0) 2024.11.09
[QT,QML] QML의 Connections  (2) 2024.11.07
[QT,QML] Q_PROPERTY의 MEMBER 키워드  (5) 2024.11.06
[QT,QML] Q_PROPERTY 매크로  (1) 2024.11.06