한국어
Qt
 

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

makersweb 2021.04.03 20:50 조회 수 : 1478

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 91541
60 main함수 명령줄 옵션 해석 makersweb 2020.09.01 3104
59 Qt 6.0의 개발 호스트 및 대상 플랫폼 makersweb 2020.09.16 1764
58 Qt 6에서 QList 변경사항 makersweb 2020.10.08 1757
57 QRandomGenerator 클래스를 사용하여 난수(random values) 생성 makersweb 2020.10.17 2404
56 Qt 6의 비동기 API makersweb 2020.10.19 1981
55 QML과 코루틴(Coroutines) makersweb 2020.11.03 1323
54 QML 바인딩 끊김 진단 makersweb 2020.11.08 1661
53 Qt Quick Controls 2에 네이티브 데스크탑 스타일 추가 file makersweb 2020.11.23 1249
52 Qt5Compat 라이브러리를 사용하여 Qt5에서 Qt6로 포팅 [2] makersweb 2020.12.05 1430
51 그래픽 소프트웨어에서 디자인 내보내기 (Exporting Designs from Graphics Software) j2doll 2020.12.25 1202
50 QThread 및 QMutex 예제 makersweb 2021.01.12 2219
49 Loader를 사용하여 동적으로 QML 로드 makersweb 2021.01.19 2646
48 Qt 를 사용하거나 기반으로 하는 응용프로그램 file makersweb 2021.01.30 4917
47 Qt MQTT의 pus/sub 튜토리얼 file makersweb 2021.02.06 2751
46 C++로 작성한 클래스를 QML에서 생성 file makersweb 2021.02.10 6347
45 Qt 5 코드를 Qt 6로 포팅하기 위해 도움이 되는 Clazy Framework file makersweb 2021.03.01 1724
44 QML과 JavaScript 의 숫자 관련 내장된 함수 makersweb 2021.03.28 2278
» Qt 6 에서 프로퍼티 바인딩 makersweb 2021.04.03 1478
42 응용프로그램 자동실행 설정 (on Windows) makersweb 2021.05.08 1296
41 싱글 샷(Single-Shot) 시그널/슬롯 연결 makersweb 2021.05.12 1497