티스토리 뷰

반응형

QML에서 시그널과 슬롯을 사용하기 위한 몇 가지 조건

QML에서 시그널(signal)과 슬롯(slot)을 사용하는 것은 Qt의 신호-슬롯 메커니즘을 활용하여 객체 간의 통신을 구현하는 중요한 방법입니다. 이를 통해 UI 요소 간의 이벤트 처리데이터 변경에 따른 반응을 구현할 수 있습니다. QML에서 시그널과 슬롯을 사용하기 위한 몇 가지 조건과 방법에 대해 자세히 설명하겠습니다.

 

 

 

 시그널과 슬롯의 기본 개념

  • 시그널 (Signal): 특정 이벤트가 발생했음을 알리는 역할을 합니다. 예를 들어 버튼이 클릭되었거나 데이터가 변경되었을 때 시그널이 발생합니다.
  • 슬롯 (Slot): 시그널에 연결되어 호출되는 함수 또는 핸들러입니다. 시그널이 발생했을 때 이를 처리하기 위해 호출되는 함수입니다.

QML에서는 주로 JavaScript 함수를 슬롯으로 사용하거나, C++에서 정의된 시그널과 슬롯을 QML에서 연결하여 사용합니다.

 

 

 

 QML에서 시그널 정의 및 사용

QML에서 시그널을 정의하고, 슬롯(핸들러)로 연결하는 기본적인 방법은 다음과 같습니다.

시그널 정의

QML에서 시그널을 정의하기 위해서는 signal 키워드를 사용합니다. 일반적으로 컴포넌트 내부에서 시그널을 정의하고 발생시킬 수 있습니다.

Rectangle {
    width: 200
    height: 200

    // 시그널 정의
    signal buttonClicked(string message)

    Button {
        text: "Click Me"
        anchors.centerIn: parent

        // 버튼 클릭 시 시그널 발생
        onClicked: {
            buttonClicked("Button was clicked!") // 시그널 발생
        }
    }

    // 시그널 핸들러 (슬롯) 정의
    onButtonClicked: {
        console.log(message) // 시그널 발생 시 콘솔에 메시지 출력
    }
}

설명

  • signal buttonClicked(string message): "buttonClicked"라는 이름의 시그널을 정의하고, 문자열 매개변수를 전달하도록 설정합니다.
  • onClicked 핸들러: 버튼이 클릭되면 buttonClicked 시그널을 발생시킵니다. 이때 매개변수로 메시지를 전달합니다.
  • onButtonClicked: 슬롯 함수로, buttonClicked 시그널이 발생했을 때 자동으로 호출됩니다. 전달된 메시지를 콘솔에 출력합니다.

 

 

 

 시그널과 슬롯의 사용 조건

  1. 시그널 정의가 필요:
    • QML 컴포넌트 내에서 사용자 정의 시그널을 사용하고 싶다면, 반드시 signal 키워드를 사용해 정의해야 합니다.
    • 시그널은 다른 UI 컴포넌트 또는 로직에서 발생시킬 수 있습니다.
  2. 시그널 핸들러 이름 규칙:
    • QML에서 시그널이 정의되면, 해당 시그널을 처리하기 위해 자동으로 만들어지는 핸들러 이름이 있습니다.
    • 시그널 이름이 buttonClicked라면, 핸들러는 onButtonClicked 형태로 정의됩니다.
    • 이 핸들러 함수는 시그널이 발생했을 때 호출됩니다.
  3. Connections 객체 사용 (다른 위치에서 시그널 처리 필요 시):
    • 특정 시그널에 대한 핸들러를 컴포넌트 외부에서 정의하려면 Connections 객체를 사용할 수 있습니다.
    Rectangle {
        width: 200
        height: 200
    
        Button {
            id: myButton
            text: "Click Me"
            anchors.centerIn: parent
            signal clickedWithMessage(string message)
            onClicked: clickedWithMessage("Hello from Button")
        }
    
        // 다른 위치에서 시그널을 처리하기 위해 Connections 사용
        Connections {
            target: myButton
            onClickedWithMessage: {
                console.log("Received message: " + message)
            }
        }
    }
    • Connections 객체는 target 속성을 통해 특정 컴포넌트의 시그널을 외부에서 처리할 수 있도록 합니다.
    • onClickedWithMessage 핸들러는 myButton의 "clickedWithMessage" 시그널이 발생할 때 호출됩니다.
  4. C++과의 통합:
    • C++에서 정의된 시그널과 슬롯을 QML에서 사용하려면, QObject을 상속받는 클래스에서 시그널과 슬롯을 정의하고 이를 QML에 노출해야 합니다.
    • C++ 시그널과 QML 슬롯을 연결하거나, QML에서 C++의 시그널을 처리하는 것도 가능합니다.
    // C++ MyClass.h 파일
    #include <QObject>
    
    class MyClass : public QObject {
        Q_OBJECT
    public:
        explicit MyClass(QObject *parent = nullptr) {}
    
    signals:
        void valueChanged(int newValue);
    
    public slots:
        void setValue(int value) {
            emit valueChanged(value); // 시그널 발생
        }
    };
    // C++ main.cpp 파일
    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include <QQmlContext>
    #include "MyClass.h"
    
    int main(int argc, char *argv[]) {
        QGuiApplication app(argc, argv);
        QQmlApplicationEngine engine;
    
        MyClass myClass;
        engine.rootContext()->setContextProperty("myClass", &myClass);
    
        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
        if (engine.rootObjects().isEmpty())
            return -1;
    
        return app.exec();
    }
    // QML main.qml 파일
    import QtQuick 2.15
    import QtQuick.Controls 2.15
    
    ApplicationWindow {
        visible: true
        width: 300
        height: 400
    
        Button {
            text: "Change Value"
            anchors.centerIn: parent
            onClicked: {
                myClass.setValue(42) // C++ 슬롯 호출
            }
        }
    
        Connections {
            target: myClass
            onValueChanged: {
                console.log("C++ signal received, new value: " + newValue)
            }
        }
    }
    • C++의 MyClass 클래스는 valueChanged라는 시그널과 setValue라는 슬롯을 정의합니다.
    • QML에서 C++ 객체를 사용하여 버튼 클릭 시 setValue(42)를 호출하고, C++에서 시그널을 발생시키면 QML에서 이를 처리하여 콘솔에 메시지를 출력합니다.

 

 

 

 요약

  • QML에서 시그널 정의: signal 키워드를 사용하여 컴포넌트 내부에서 시그널을 정의합니다.
  • 핸들러 사용: 시그널이 발생했을 때 자동으로 호출되는 핸들러를 정의하려면 onSignalName 형태로 핸들러를 작성해야 합니다.
  • Connections 객체: 특정 컴포넌트 외부에서 시그널을 처리할 때 사용합니다. 이를 통해 유연한 시그널 처리가 가능합니다.
  • C++과의 통합: C++에서 시그널과 슬롯을 정의하고 이를 QML에서 사용하여 C++ 백엔드와 QML 프론트엔드 간의 상호작용을 쉽게 구현할 수 있습니다.

 

QML의 시그널과 슬롯 메커니즘은 모듈 간의 통신을 간단하게 구현할 수 있어 UI 이벤트 처리, 데이터 변경 반영 등에 매우 유용하며, C++과의 연동을 통해 더욱 복잡하고 강력한 기능을 구현할 수 있습니다.

 

 


 

 

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

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

 

 

 

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

QML에서 MVVC (Model-View-ViewModel) 패턴  (1) 2024.11.20
QML의 Repeater  (0) 2024.11.19
빈 ListModel 생성 후 데이터 추가  (0) 2024.11.17
QML의 ListModel과 ListView  (1) 2024.11.16
QML ListView의 contentX  (0) 2024.11.14