Data Type Conversion Between QML and C++
Qt 2017. 6. 11. 18:45[원문] https://doc.qt.io/qt-5/qtqml-cppintegration-data.html
Data Type Conversion Between QML and C++
QML과 C++간에 데이터 값이 교환되면 QML 엔진에 의해 변환되어 QML 또는 C++에서 사용하기에 적합한 데이터 유형을 갖게됩니다. 이를 위해서는 교환 된 데이터가 엔진이 인식 할 수있는 유형이어야합니다.
QML 엔진은 다수의 Qt C++ 데이터 유형을 기본적으로 지원합니다. 또한 사용자 정의 C++ 유형을 QML 유형 시스템에 등록하여 엔진에서 사용할 수 있도록 할 수 있습니다.
이 페이지에서는 QML 엔진에서 지원하는 데이터 유형과 QML과 C++간에 변환되는 데이터 유형에 대해 설명합니다.
Data Ownership
데이터가 C++에서 QML로 전송되면 데이터의 소유권은 항상 C++로 유지됩니다. 이 규칙의 예외는 명시 적 C++ 메서드 호출에서 QObject가 반환 된 경우입니다.이 경우 QML 엔진은 개체의 소유권이 명시 적으로 C++로 유지되도록 설정되지 않은 한 QQmlEngine::QQmlEngine::CppOwnership이 지정된 setObjectOwnership().
또한 QML 엔진은 Qt C++ 개체의 일반적인 QObject 부모 소유권 의미를 따르며 부모가있는 QObject 인스턴스를 삭제하지 않습니다.
Basic Qt Data Types
기본적으로 QML은 다음과 같은 Qt 데이터 유형을 인식합니다.이 데이터 유형은 C++에서 QML로 또는 그 반대로 전달 될 때 자동으로 해당 QML 기본 유형으로 변환됩니다.
Qt Type | QML Basic Type |
bool | bool |
unsigned int, int | int |
double | double |
float, qreal | real |
QString | string |
QUrl | url |
QColor | color |
QFont | font |
QDate | date |
QPoint, QPointF | point |
QSize, QSizeF | size |
QRect, QRectF | rect |
QMatrix4x4 | matrix4x4 |
QQuaternion | quaternion |
QVector2D, QVector3D, QVector4D | vector2d, vector3d, vector4d |
Enums declared with Q_ENUM() or Q_ENUMS() | enumeration |
참고 : Qt GUI 모듈에서 제공하는 QColor, QFont, QQuaternion 및 QMatrix4x4와 같은 클래스는 Qt Quick 모듈이 포함 된 경우에만 QML에서 사용할 수 있습니다.
편의상 많은 유형의 문자열을 QML에서 문자열 값으로 지정하거나 QtQml::Qt 객체에서 제공하는 관련 메서드로 지정할 수 있습니다. 예를 들어 Image::sourceSize 속성은 size 유형 (자동으로 QSize 유형으로 변환 됨)이며 "widthxheight"또는 Qt.size() 함수로 포맷 된 문자열 값으로 지정할 수 있습니다.
Item { Image { sourceSize: "100x200" } Image { sourceSize: Qt.size(100, 200) } }
자세한 내용은 QML 기본 유형에서 각 유형별 문서를 참조하십시오.
QObject-derived Types
모든 QObject 파생 클래스는 QML 유형 시스템에 클래스가 등록되어 있으면 QML과 C++ 간의 데이터 교환을위한 유형으로 사용할 수 있습니다.
엔진을 사용하면 인스턴스화 할 수있는 유형과 인스턴스화 할 수없는 유형을 모두 등록 할 수 있습니다. 클래스가 QML 유형으로 등록되면 QML과 C++간에 데이터를 교환하기위한 데이터 유형으로 사용할 수 있습니다. 형식 등록에 대한 자세한 내용은 QML 유형 시스템에 C++ 유형 등록을 참조하십시오.
Conversion Between Qt and JavaScript Types
QML 엔진에는 QML과 C++간에 데이터를 전송할 때 여러 가지 Qt 유형을 관련 JavaScript 유형으로 변환하거나 그 반대로 지원하는 내장형 지원이 있습니다. 이렇게하면 데이터 유형과 해당 속성에 대한 액세스를 제공하는 사용자 정의 유형을 구현할 필요없이 이러한 유형을 사용하고 C++ 또는 JavaScript로 수신 할 수 있습니다.
(QML의 JavaScript 환경은 추가 기능을 제공하기 위해 String, Date 및 Number의 프로토 타입을 포함하여 기본 JavaScript 객체 프로토 타입을 수정합니다. 자세한 내용은 JavaScript 호스트 환경을 참조하십시오.)
QVariantList and QVariantMap to JavaScript Array and Object
QML 엔진은 QVariantList와 JavaScript 배열 사이 및 QVariantMap과 JavaScript 객체 사이의 자동 유형 변환을 제공합니다.
예를 들어, 아래 QML에서 정의 된 함수는 배열과 객체라는 두 개의 인수를 예상하고 배열 및 객체 항목 액세스를위한 표준 JavaScript 구문을 사용하여 내용을 인쇄합니다. 아래의 C++ 코드는 QVariantList와 QVariantMap을 전달하여이 함수를 호출합니다.이 함수는 자동으로 JavaScript 배열과 객체 값으로 변환됩니다.
QML | // MyItem.qml Item { function readValues(anArray, anObject) { for (var i=0; i<anArray.length; i++) console.log("Array item:", anArray[i]) for (var prop in anObject) { console.log("Object item:", prop, "=", anObject[prop]) } } } |
C++ | // C++ QQuickView view(QUrl::fromLocalFile("MyItem.qml")); QVariantList list; list << 10 << QColor(Qt::green) << "bottles"; QVariantMap map; map.insert("language", "QML"); map.insert("released", QDate(2010, 9, 21)); QMetaObject::invokeMethod(view.rootObject(), "readValues", Q_ARG(QVariant, QVariant::fromValue(list)), Q_ARG(QVariant, QVariant::fromValue(map))); |
이렇게하면 다음과 같은 출력이 생성됩니다.
Array item: 10 Array item: #00ff00 Array item: bottles Object item: language = QML Object item: released = Tue Sep 21 2010 00:00:00 GMT+1000 (EST)
마찬가지로 C++ 유형이 속성 유형 또는 메소드 매개 변수에 대해 QVariantList 또는 QVariantMap 유형을 사용하는 경우이 값은 QML의 JavaScript 배열 또는 객체로 생성 될 수 있으며 C++로 전달 될 때 자동으로 QVariantList 또는 QVariantMap으로 변환됩니다.
QDateTime to JavaScript Date
QML 엔진은 QDateTime 값과 JavaScript Date 객체간에 자동 유형 변환을 제공합니다.
예를 들어, 아래 QML에서 정의 된 함수는 JavaScript Date 객체를 예상하고 현재 날짜와 시간이 포함 된 새 Date 객체를 반환합니다. 아래의 C++ 코드는이 함수를 호출하여 readDate() 함수에 전달 될 때 엔진에 의해 자동으로 Date 객체로 변환되는 QDateTime 값을 전달합니다. ReadDate() 함수는 C++에서 수신 될 때 자동으로 QDateTime 값으로 변환되는 Date 객체를 반환합니다.
QML | // MyItem.qml Item { function readDate(dt) { console.log("The given date is:", dt.toUTCString()); return new Date(); } } |
C++ | // C++ QQuickView view(QUrl::fromLocalFile("MyItem.qml")); QDateTime dateTime = QDateTime::currentDateTime(); QDateTime retValue; QMetaObject::invokeMethod(view.rootObject(), "readDate", Q_RETURN_ARG(QVariant, retValue), Q_ARG(QVariant, QVariant::fromValue(dateTime))); qDebug() << "Value returned from readDate():" << retValue; |
마찬가지로 C++ 유형이 속성 유형 또는 메소드 매개 변수에 대해 QDateTime을 사용하는 경우 값은 QML에서 JavaScript Date 객체로 생성 될 수 있으며 C++에 전달 될 때 자동으로 QDateTime 값으로 변환됩니다.
QTime to JavaScript Date
QML 엔진은 QTime 값에서 JavaScript Date 객체로의 자동 유형 변환을 제공합니다. 결과로 생성 된 Date 객체의 날짜 구성 요소는 운영 체제에 의존하므로 의존해서는 안됩니다. 특히 연도 (및 월과 일)는 0으로 설정됩니다. JavaScript Date 객체에서 QTime으로의 변환은 QDateTime으로 변환 한 다음 QVariant를 사용하여 QTime으로 변환하여 수행됩니다. 결과적으로 Date 개체의 날짜 부분은 무시되지만 DST의 복잡성을 무시하고 현지 표준 시간대가 사용됩니다.
Sequence Type to JavaScript Array
특정 C++ 시퀀스 유형은 QML에서 JavaScript Array 유형으로 투명하게 지원됩니다.
특히, QML은 현재 다음을 지원합니다.
QList<int>
QList<qreal>
QList<bool>
QList<QString>
andQStringList
QList<QUrl>
QVector<int>
QVector<qreal>
QVector<bool>
이러한 시퀀스 유형은 기본 C++ 시퀀스의 관점에서 직접 구현됩니다. 이러한 시퀀스가 QML에 노출 될 수있는 두 가지 방법이 있습니다. 주어진 시퀀스 유형의 Q_PROPERTY. 또는 Q_INVOKABLE 메소드의 리턴 유형으로 사용됩니다. 이들이 구현되는 방식에는 몇 가지 차이점이 있는데, 이는 중요합니다.
시퀀스가 Q_PROPERTY로 노출되면 인덱스로 시퀀스의 모든 값에 액세스하면 QObject의 속성에서 시퀀스 데이터를 읽은 다음 읽기가 발생합니다. 마찬가지로 시퀀스의 값을 수정하면 시퀀스 데이터가 읽히고 수정이 수행되고 수정 된 시퀀스가 QObject의 속성에 다시 기록됩니다.
시퀀스가 Q_INVOKABLE 함수에서 반환되면 QObject 속성 읽기 또는 쓰기가 발생하지 않으므로 액세스 및 변형이 훨씬 저렴합니다. 대신 C++ 시퀀스 데이터가 직접 액세스되고 수정됩니다.
다른 시퀀스 유형은 투명하게 지원되지 않으며 대신 다른 시퀀스 유형의 인스턴스는 QML과 C++ 사이에서 불투명 한 QVariantList로 전달됩니다.
중요 : 이러한 배열 배열 유형의 의미와 구현시 C++ 저장소 유형의 사용으로 인해 발생하는 기본 JavaScript Array 유형에는 약간의 차이가 있습니다. 특히 배열에서 요소를 삭제하면 정의되지 않은 값 대신 해당 요소를 대체하는 기본 생성 값이됩니다. 마찬가지로 Array의 length 속성을 현재 값보다 큰 값으로 설정하면 배열이 정의되지 않은 요소가 아닌 기본 생성 요소로 지정된 길이만큼 채워집니다. 마지막으로 Qt 컨테이너 클래스는 부호없는 (서명되지 않은) 정수 인덱스를 지원합니다. 따라서 INT_MAX보다 큰 인덱스에 액세스하려고하면 실패합니다.
각 시퀀스 유형에 대한 기본값으로 구성된 값은 다음과 같습니다.
QList<int> | integer value 0 |
QList<qreal> | real value 0.0 |
QList<bool> | boolean value false |
QList<QString> and QStringList | empty QString |
QList<QUrl> | empty QUrl |
QVector<int> | integer value 0 |
QVector<qreal> | real value 0.0 |
QVector<bool> | boolean value false |
시퀀스를 단순히 기본 구성 값으로 대체하는 대신 시퀀스에서 요소를 제거하려면 인덱스 삭제 연산자 ("delete sequence [i]")를 사용하지 말고 splice 함수 ( "sequence.splice(startIndex, deleteCount)").
Value types
QPoint와 같은 Qt의 일부 값 유형은 JavaScript에서 C++ API와 같은 속성 및 기능을 가진 객체로 표시됩니다. 사용자 정의 C++ 값 유형에서도 동일한 표현이 가능합니다. QML 엔진에서 사용자 정의 값 유형을 사용하려면 클래스 선언에 Q_GADGET 주석을 추가해야합니다. JavaScript 표현에서 볼 수있는 속성은 Q_PROPERTY로 선언해야합니다. 마찬가지로 함수는 Q_INVOKABLE로 표시되어야합니다. 이것은 QObject 기반 C++ API와 동일합니다. 예를 들어, 아래 Actor 클래스는 가제트로 주석 처리되고 속성을가집니다.
class Actor { Q_GADGET Q_PROPERTY(QString name READ name WRITE setName) public: QString name() const { return m_name; } void setName(const QString &name) { m_name = name; } private: QString m_name; } Q_DECLARE_METATYPE(Actor)
Enumeration Types
커스텀 열거 형을 데이터 타입으로 사용하기 위해서는 Qt의 메타 오브젝트 시스템에 그것을 등록하기 위해 그 클래스가 등록되어야하고 열거 형을 Q_ENUM()으로 선언해야한다. 예를 들어 아래의 Message 클래스에는 Status 열거 형이 있습니다.
class Message : public QObject { Q_OBJECT Q_PROPERTY(Status status READ status NOTIFY statusChanged) public: enum Status { Ready, Loading, Error }; Q_ENUM(Status) Status status() const; signals: void statusChanged(); };
Message 클래스를 QML 타입 시스템에 등록하면 QML에서 Status 열거 형을 사용할 수 있습니다.
Message { onStatusChanged: { if (status == Message.Ready) console.log("Message is loaded!") } }
enum을 QML의 플래그 유형으로 사용하려면 Q_FLAG()를 참조하십시오.
참고 : 열거 형 값의 이름은 QML에서 액세스 할 수 있도록 대문자로 시작해야합니다.
Enumeration Types as Signal and Method Parameters
열거 형과 매개 변수가있는 C++ 신호 및 메서드는 QML에서 사용할 수 있습니다. 단, 열거 형과 신호 또는 메서드는 모두 같은 클래스 내에서 선언되거나 열거 형 값은 Qt 네임 스페이스에서 선언 된 값 중 하나입니다.
또한 enum 매개 변수가있는 C++ 신호를 connect() 함수를 사용하여 QML 함수에 연결할 수 있으면 qRegisterMetaType()을 사용하여 열거 형을 등록해야합니다.
QML 신호의 경우 enum 값은 int 유형을 사용하여 신호 매개 변수로 전달 될 수 있습니다.
Message { signal someOtherSignal(int statusValue) Component.onCompleted: { someOtherSignal(Message.Loading) } }
'Qt' 카테고리의 다른 글
[펌] Qt QML Performance Considerations And Suggestions (0) | 2018.05.29 |
---|---|
VMWare Workstation 14 with Untutu 14.04.4 & Qt 5.6.3 Install (0) | 2018.04.29 |
Interacting with QML Objects from C++ (0) | 2017.06.11 |
Embedding C++ Objects into QML with Context Properties (0) | 2017.06.11 |
Defining QML Types from C++ (0) | 2017.06.10 |