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++ 개발자도 사용할 수 있도록했다. 결론적으로 코드의 성능, 가독성 및 유지보수 용이성이 향상된다.