2017-01-18 5 views
2

(QMLではなく、C++で定義されている)QMLタイプ考えてみましょう:のQt:どのようにCからチェックする++オブジェクトがQML型であるかどうかはFoo

Foo { 
} 

を私はC++でQQuickItem* item変数を持っていると仮定します。 変数がFoo型であるかどうかを確認するにはどうすればよいですか?

はfooがC++タイプだった場合、私はこれを行うことができます:

qobject_cast<Foo*>(item) == nullptr 

をfooがQMLタイプですので、一つの選択肢は

item->metaObject()->className().beginsWith("Foo") 

className()戻りFoo_QMLTYPE_0のようなものを)

だろう

しかし、それは信頼できないとハックです。

答えて

2

あなたは魔法のキープロパティを使用できます。その後、

Foo { 
    property bool isFoo : true 
} 

そして、C++から:

if (obj->property("isFoo").toBool()) 

オブジェクトがそのプロパティを持っていない場合は、条件が失敗しなければなりません。これはプロパティが "継承"されるので、例えば "Foo"が拡張されているが、必ずしも "FooSomething"という名前ではなく "SomethingFoo"という名前が付いている場合など、 "派生"オブジェクトでも機能します。

もちろん、多くのインスタンスで多くの型チェックが必要なシナリオでは、いくつかのオーバーヘッドが発生する可能性があります。私がする傾向があるのは、単一のquint32 typeプロパティをC++レベルで効率的に実装することです。次に、QMLから、型情報が必要なオブジェクトに明示的に設定されます。この方法でオーバーヘッドが最小化され、property(name)を使用するよりもアクセスが高速になります。

+0

私は、 'objectName'をマジックキーとして使用するようアドバイスしました。この場合、 'obj-> objectName'でアクセスできますし、' rootItem-> findChild ( "myObjectName") 'を使って項目を見つけることもできます。 – folibis

+0

@ddriver:ありがとう、ええ、私はあなたの 'isFoo'ソリューションを現在使用していますが、私はもっとクリーンなものを好むでしょう。私はそれが "派生"されたオブジェクトに対してもうまくいくのが好きです。私の場合は問題ではないが、オーバーヘッドについての有用なメモ。 –

+0

@folibis: 'objectName'は、私が1つのオブジェクトだけを探したい場合に機能します。私は、同じタイプのアイテムをたくさん見つけたいと思っています。 –

0

あなたはそこに行く途中です。あなたの最善の策は、QQuickItem::inheritsQMetaObject::classNameの組み合わせを使用しています。

実際にFooであるか、Fooから派生したものかを調べることができます。

const QByteArray foo = QByteArrayLiteral("Foo"); 

if (item->metaObject()->className() == foo || item->inherits(foo)) { 
    // It's a Foo 
} 
+0

質問に書いたように、 'className()'は "Foo"ではなく "Foo_QMLTYPE_0"のようなものを返します。残念なことにそのことは、実際の文字列を再構成するために使用されます。動作しません。 –

関連する問題