한국어
Qt
 

Qt 6 Qt 6 에서 프로퍼티 바인딩

makersweb 2021.04.03 20:50 조회 수 : 284

Qt 6에는 많은 새로운 기능이 포함되어 있지만 가장 흥미로운 기능 중 하나는 QML 및 Qt Quick의 바인딩 개념을 C++ 에서도 사용할 수 있도록한 것이다.
 

Qt 5에서 QML 프로퍼티 바인딩

Qt 5에서 프로퍼티 바인딩이 작동하는 방식을 다시 살펴 보겠다. 거기에서 바인딩 지원은 Qt Quick으로 제한되었다. 다음은 매우 간단한 QML 코드이다.
import QtQuick 2.15

Rectangle {
    height: width
    border.width: height/10
}
 
직사각형 객체에 두 개의 바인딩을 설정하는 것이다. 첫 번째 바인딩은 직사각형이 항상 정사각형이되도록한다. 두 번째 바인딩은 테두리 너비를 높이의 10%로 설정한다. 그런 다음 Qt의 QML 엔진은 이러한 관계가 유지되도록하고 Rectangle의 너비가 변경 될 때마다 높이와 테두리 너비를 자동으로 조정한다.
 
이 바인딩 메커니즘은 대부분 선언적 방식으로 Qt Quick에서 UI 정의를 작성할 수 있게한다. 바인딩 식 (바인딩의 오른쪽)은 임의로 복잡 할 수 있으며 다른 개체의 프로퍼티에 대한 참조를 포함하거나 다른 메서드를 호출 할 수도 있다.
 
Qt 5에서 바인딩은 코드를 훨씬 더 표현력있게 만들었고 작성해야하는 많은 글루 코드를 제거한다는 것을 보았다. 따라서 Qt 6에서 이 메커니즘을 C++ 개발자도 사용할 수 있도록하는 것이다.
 

QProperty 클래스

C++에서 동일한 관계를 어떻게 표현하고 싶은지 살펴 보자. 다음은 이러한 직사각형을 C++ 클래스로 작성하는 방법이다.
class Rectangle {
public:
    QProperty<int> width;
    QProperty<int> height;
    QProperty<int> border;

    Rectangle() {
        height.setBinding(width);
        border.setBinding([this]() {
            return height / 10;
        });
    }
};
예제 코드에서 3 가지 프로퍼티가있는 직사각형 클래스를 정의한다. 너비, 높이 및 테두리. 그런 다음 생성자는 두 개의 바인딩을 설정한다. 하나는 높이를 너비에 바인딩하고 다른 하나는 테두리를 높이의 10 %에 바인딩한다. 너비가 변경되면 의존하는 모든 바인딩에 더티로 플래그를 지정하고 바인딩 식을 다시 평가하게된다.
 
바인딩 설정 외에도 QProperty는 프로퍼티에 대한 변경 처리기를 등록 할 수 있다. QProperty의 onValueChanged() 또는 subscribe() 메소드를 사용하면 프로퍼티의 기본 값이 변경 될 때마다 호출되는 콜백을 등록 할 수 있다.
setter를 호출하여 프로퍼티 값이 변경되었거나 프로퍼티의 바인딩이 종속성 중 하나가 변경되어 더티로 표시된 경우 콜백이 호출된다.
 

QObjects 프로퍼티 시스템의 바인딩 지원

Qt 5 에서는 Q_PROPERTY 매크로를 사용하여 QML 측에 노출되는 사용자 지정 프로퍼티를 추가 할 수 있다.
Q_PROPERTY(int x READ x WRITE setX NOTIFY xChanged)
 
그러나 이러한 방법은 적어도 C++ 쪽에서는 바인딩 할 수 없다. Qt 6 부터 다음을 수행하여 C++ 프로퍼티를 바인딩 가능하도록 할 수 있다.
class MyClass : public QObject 
{ 
    Q_OBJECT 
    Q_PROPERTY(int x READ x WRITE setX NOTIFY xChanged BINDABLE bindableX) 
public: 
    int x() const { return xProp; } 
    void setX(int x) { xProp = x; } 
    QBindable<int> bindableX() { return QBindable<int>(&xProp); } 
signals: 
    void xChanged(); 
private: 
    // 바인딩 가능한 프로퍼티 데이터의 인스턴스를 선언
    Q_OBJECT_BINDABLE_PROPERTY(MyClass, int, xProp, &MyClass::xChanged) 
};
QProperty가 독립형 클래스로 수행하는 작업 중 일부이다.  일반적인 getter, setter, 그리고  QBindable<int>를 반환하는 새로운 bindableX() 메소드를 가리키는 BINDABLE 이 추가 된 Q_PROPERTY 매크로를 사용한다.
QBindable <T>는 QProperty에서도 사용할 수있는 추가 기능을 제공하는 경량 인터페이스이다. 바인딩을 설정 및 검색하고 알림을 등록 할 수 있다. MyObject의 x 속성에 대한 바인딩 설정은 예를 들어 다음과 같다.
MyClass *myObject; 
QBindable<int> bindableX = myObject->bindableX();

qDebug() << bindableX.hasBinding(); // prints false

QProperty<int> y {42}; 
bindableX.setBinding([&](){ return 2*y.value(); });

qDebug() << bindableX.hasBinding() << myObject->x(); // prints true 84

결론

Qt 5의 바인딩 엔진은 Qt Quick을 성공적으로 만들었다. 이제 Qt 6에서 해당 엔진을 Qt Quick에서 Qt의 핵심기능으로 옮겨졌으며 C++ 개발자도 사용할 수 있도록했다. 결론적으로 코드의 성능, 가독성 및 유지보수 용이성이 향상된다.
번호 제목 글쓴이 날짜 조회 수
공지 Qt프로그래밍(QtQuick) Beginner를 위한 글 읽는 순서 운영자 2019.01.05 32685
150 Qt 6의 C++ 프로퍼티 바인딩 예제 makersweb 2021.11.01 55
149 QML에서 앵커(anchors)로 위치 지정 file makersweb 2021.10.05 100
148 안드로이드용 Qt 6.2 makersweb 2021.10.02 72
147 Qt 응용프로그램에서 PDF 문서 렌더링 file makersweb 2021.09.23 52
146 QML에서 Websocket 서버와 통신 file makersweb 2021.09.18 76
145 QML 코딩 규칙 makersweb 2021.09.05 378
144 QML 에서 QR코드 생성 file makersweb 2021.08.20 131
143 앱을 종료할 때 QML 바인딩 오류를 피하는 방법 makersweb 2021.08.08 57
142 Qt 응용프로그램에서 Lottie Animation사용 file makersweb 2021.05.30 307
141 싱글 샷(Single-Shot) 시그널/슬롯 연결 makersweb 2021.05.12 214
140 응용프로그램 자동실행 설정 (on Windows) makersweb 2021.05.08 185
» Qt 6 에서 프로퍼티 바인딩 makersweb 2021.04.03 284
138 QML과 JavaScript 의 숫자 관련 내장된 함수 makersweb 2021.03.28 223
137 Qt 5 코드를 Qt 6로 포팅하기 위해 도움이 되는 Clazy Framework file makersweb 2021.03.01 296
136 C++로 작성한 클래스를 QML에서 생성 file makersweb 2021.02.10 1165
135 Qt MQTT의 pus/sub 튜토리얼 file makersweb 2021.02.06 525
134 Qt 를 사용하거나 기반으로 하는 응용프로그램 file makersweb 2021.01.30 1183
133 Loader를 사용하여 동적으로 QML 로드 makersweb 2021.01.19 556
132 QThread 및 QMutex 예제 makersweb 2021.01.12 450
131 그래픽 소프트웨어에서 디자인 내보내기 (Exporting Designs from Graphics Software) j2doll 2020.12.25 181