C ++オブジェクトとQML、すべて棚に

HabréとWebには、QMLのトピックに関する記事がたくさんありますが、それらはすべていくつかのシーンを残しています。 今日は、QMLとC ++の束を扱っている人にとっては明らかなポイントを越えようとしていますが、この素晴らしい技術のニュアンスを掘り下げ始めている人にとってはそれほど明白ではありません。

だから。 QMLアプリケーションインターフェイスと、作業ロジックを備えたC ++クラスがあるとします。 どうすればこれらすべてをまとめることができますか? C ++クラスから始めましょう。QMLからアクセス可能にするために最初に行う必要があるのは、QObjectまたはこのQObjectの子孫から継承することです。



class TestClass : public QObject { Q_OBJECT public: explicit TestClass(QObject *parent = 0); signals: public slots: };
      
      





QMLからいくつかのプロパティを使用できるようにします。これにはQ_PROPERTYマクロがあります。

 class TestClass : public QObject { Q_OBJECT Q_PROPERTY(int someProperty READ getSomeProperty WRITE setSomeProperty NOTIFY somePropertyChanged) public: explicit TestClass(QObject *parent = 0); int getSomeProperty()const; void setSomeProperty(const int &); private: int someProperty; signals: void somePropertyChanged(); public slots: }; int TestClass::getSomeProperty()const { qDebug() << "I'm getter"; return someProperty; } void TestClass::setSomeProperty(const int &i) { qDebug() << "I'm setter"; someProperty = i; }
      
      







ここで、somePropertyはプロパティそのものであり、getSomePropertyは読み取り用のメソッドであり、setSomePropertyは書き込み用のメソッドです。 プロパティをC ++から変更する場合、信号somePropertyChangedを使用して、これについてQMLインターフェイスに通知する必要があります。 ここで、クラスをQMLに登録する必要があります。そのため、新しいQtQuickプロジェクトを作成するときにQtCreatorが自動的に作成するコンストラクターQmlApplicationViewerを呼び出し、テンプレート関数qmlRegisterTypesへの呼び出しを追加する必要があります。



 qmlRegisterType<TestClass>("ModuleName", 1, 0, "TypeName");
      
      







ここで、TestClassはクラス、ModuleNameはインポートされたQMLモジュールの名前、TypeNameはQMLのオブジェクトのタイプの名前です。 次に、クラスをQMLファイルにインポートして、インスタンスを作成します。

 import QtQuick 1.0 import ModuleName 1.0 Rectangle { width: 360 height: 360 TypeName{ id: myObj someProperty: 10 } Text { text: "My property is: " + myObj.someProperty anchors.centerIn: parent } MouseArea { anchors.fill: parent onClicked: { Qt.quit(); } } }
      
      







以下の点に詳細に興味があります。

1)
 import ModuleName 1.0
      
      



-したがって、QMLエンジンに、どのモジュールでタイプを探すかを伝えます。

2)
 TypeName{ id: myObj someProperty: 10 }
      
      





実際にタイプのオブジェクトを作成し、プロパティを作成します。

3)
 text: "My property is: " + myObj.someProperty
      
      



-私たちの財産を読んで。



コンパイルして実行します。

画像



QML C ++からメソッドを呼び出せるようにするには、それらをスロットとして定義するか、Q_INVOKABLEマクロを使用する必要があります。



 class TestClass : public QObject { Q_OBJECT Q_PROPERTY(int someProperty READ getSomeProperty WRITE setSomeProperty NOTIFY somePropertyChanged) public: explicit TestClass(QObject *parent = 0); int getSomeProperty()const; void setSomeProperty(const int &); Q_INVOKABLE void myMethod(); private: int someProperty; signals: void somePropertyChanged(); public slots: void mySlot(); }; void TestClass::myMethod() { qDebug() << "I am Method"; someProperty++; } void TestClass::mySlot() { qDebug() << "I am SLOT"; someProperty--; }
      
      







QMLファイルを変更します。

 import QtQuick 1.0 import ModuleName 1.0 Rectangle { width: 360 height: 360 TypeName{ id: myObj someProperty: 10 } Text { text: "My property is: " + myObj.someProperty anchors.centerIn: parent } Rectangle{ width: 20 height: 20 color: "red" MouseArea { anchors.fill: parent onClicked: { myObj.mySlot(); } } } Rectangle{ anchors.right: parent.right width: 20 height: 20 color: "blue" MouseArea { anchors.fill: parent onClicked: { myObj.myMethod(); } } } }
      
      







コンパイル、実行、四角をクリックし、デバッグ出力ですべてが機能することがわかります。プロパティの変更のみがインターフェイスに影響を与えません。 しかし、これを予見し、プロパティを宣言するときにNOTIFY somePropertyChangedを示し、プロパティが変更されたときにsomePropertyChanged信号が発行されるようにメソッドとスロットを変更しました。

 void TestClass::myMethod() { qDebug() << "I am Method"; someProperty++; emit somePropertyChanged(); } void TestClass::mySlot() { qDebug() << "I am SLOT"; someProperty--; emit somePropertyChanged(); }
      
      







コンパイルして実行し、再びお楽しみください-それは反応します。

しかし、QMLコードからC ++オブジェクトによって発信された信号を処理したい場合はどうでしょうか。 すべてがシンプルです。 シグナルをクラスに追加し、必要なときに生成します。

 void TestClass::mySlot() { qDebug() << "I am SLOT"; someProperty--; emit somePropertyChanged(); if(someProperty < 0) emit someSignal(); }
      
      







この信号をQMLでキャッチするには、オブジェクトにonSomeSignalイベントハンドラが必要です。QMLのイベント名は、信号の最初の文字を大文字に変換し、onプレフィックスを追加することによって取得されます。

 TypeName{ id: myObj someProperty: 10 onSomeSignal: { Qt.quit(); } }
      
      







これは、QMLファイルでイベントハンドラーを使用してオブジェクトを作成する方法です。

実際に私が伝えたかったのはそれだけです。 ご清聴ありがとうございました。



All Articles