問題
Q_OBJECTとQ_PROPERTYを使用して、スクリプトからいくつかのオブジェクトにアクセスするプロジェクトを作成しています。私には2つの問題があります:
- 前方宣言を使用するクラスをスクリプト可能にする
- プロパティをポインタとして返す
説明
1.なぜ前方宣言?
Aはテンプレートのためにヘッダーに完全なBタイプを必要とするため、クラスBはAへの前方宣言を取得します。Bはヘッダーに不完全な型(A *)のみを必要とするため、前方宣言は有効です。
2.なぜポインタを返すのですか?
スクリプト内の実際のオブジェクトにアクセスする必要があるため、コピーを返すことはできません。Qtはスロットが参照を返すことを許可しないため、参照を返すことはできません。それらのタイプは無視され、void*のみを返します。
コード
ペーストビンまたはZIPアーカイブとして、または最小限の例のZIPアーカイブとして、テスト/再生用の完全なコードダウンロードが利用可能です。前方宣言とMOCのためにファイルを分割する必要がありました。テストするためにMakefileを追加しました。depsを作成します:g ++、moc、Qt。
重要な部分
class A; // forward declaration necessary, see explanation above
class B : public QObject {
Q_OBJECT
Q_PROPERTY(A a READ GetA) // <-- ERROR HERE
// ...
public slots:
A* GetA() {
return mA;
}
private:
A* mA;
// ...
}
スクリプトのエラー行:
print(bObj.GetA().GetName());
コンパイルエラー
上記のQ_PROPERTYをコメントアウトすると、このエラーは消えます。
tmp/B.moc.hpp:95:51: error: invalid use of incomplete type ‘struct A’
tmp/../B.hpp:10:7: error: forward declaration of ‘struct A’
スクリプト例外
Q_PROPERTYを省略し、スクリプトからスロットとしてGetA()メソッドを呼び出すと、次の例外が発生します。
Line 7: "TypeError: cannot call GetA(): unknown return type `A*'
(register the type with qScriptRegisterMetaType())"
これでA*を登録すると、次のqRegisterMetaType<A*>("A*");
ように変更されます。
Line 7: "TypeError: Result of expression 'bObj.GetA().GetName'
[undefined] is not a function."
これは、GetA()がAオブジェクトを返さないか、何らかの方法でポインターを返すことを示していますが、スクリプトはそれを逆参照できません。GetA()は実際にを返しますがQVariant(A*)
、これはどういうわけか使用できますか?
質問:
- どういうわけか不完全な型からQ_PROPERTYを作成できますか、または前方宣言を回避するにはどうすればよいですか?
- スロットで参照を返すことはできますか(たとえば、ポインタをラップし、
operator.
類似したものが存在する場合はスクリプトを「オーバーライド」するクラスなど、いくつかのトリック)または - QtScriptでQVariant(A *)をAに逆参照することはできますか?