web-dev-qa-db-ja.com

QMLで「is_a」、「typeof」、またはinstanceofを実行するにはどうすればよいですか?

QMLコンポーネントのリストを調べて、次の1つのタイプを選択したいと思います。

for (var i = 0; i < controls.children.length; ++i) {
     if ( typeof (controls.children[i].height) == "QDeclarativeRectangle")
     {
        // do stuff
     }
}

これをどのように達成しますか?

27

typeofを直接使用することはできません。これは、QML要素のタイプとして常に'object'を返すためです。ただし、使用できるいくつかの選択肢があります。 1つは、各要素のobjectNameをそのタイプに設定し、ループ内でそれを確認するか、プロパティを定義してそのプロパティを確認することです。これにはもう少し作業が必要になりますが、このプロパティを持つqml要素を作成して、必要な場所で使用することができます。サンプルコードは次のとおりです。

Rectangle {
  id: main
  width: 300; height: 400

  Rectangle {
    id: testRect
    objectName: "rect"
    property int typeId: 1
  }

  Item {
    id: testItem
    objectName: "other"
  }

  Component.onCompleted: {
    for(var i = 0; i < main.children.length; ++i)
    {
        if(main.children[i].objectName === "rect")
        {
            console.log("got one rect")
        }
        else
        {
            console.log("non rect")
        }
    }
    for(i = 0; i < main.children.length; ++i)
    {
        if(main.children[i].typeId === 1)
        {
            console.log("got one rect")
        }
        else
        {
            console.log("non rect")
        }
    }
  }
}
18
JuliusG

Qt 5.10以降、最終的にinstanceOfを使用して、変数が特定のQMLタイプであるかどうかを確認できます: https:// v-play .net/downloads/v-play-2-15-0-qt-5-10-qt-creator-4-5-support-firebase-data-structures-and-queries#qt-5-10-qml-enum -instanceof

import VPlayApps 1.0
import QtQuick 2.0

App {
  // two QML items, used for type checking
  Item { id: testItem }
  Rectangle { id: testRect }

  // function to check wheter an item is a Rectangle
  function isRectangle(item) {
    return item instanceof Rectangle
  }

  // type check example
  Component.onCompleted: {
    console.log("testItem is Rectangle? "+isRectangle(testItem))
    console.log("testRect is Rectangle? "+isRectangle(testRect))
  }
}
11
user5315753

ToString()を使用した別のアプローチを次に示します(QMLの将来のバージョンに移植できない可能性があります)。

function qmltypeof(obj, className) { // QtObject, string -> bool
  // className plus "(" is the class instance without modification
  // className plus "_QML" is the class instance with user-defined properties
  var str = obj.toString();
  return str.indexOf(className + "(") == 0 || str.indexOf(className + "_QML") == 0;
}

...

for (var i = 0; i < controls.children.length; ++i) {
   if (qmltypeof(controls.children[i].height, "QDeclarativeRectangle"))
   {
     // do stuff
   }
}
11
jichi

はい、このスレッドは2年前のものですが、おそらく私の答えは誰かを助けることができます。

私にとっては、JSON.stringify()を使用してQML要素を比較するだけで十分でした。もちろん、2つの異なる要素がまったく同じプロパティと値を持っている場合、これは誤検知になります。 (たとえば、ある要素が同じ色、x、yなどで別の要素の上にある場合)

同じベースコンポーネントから多くのインスタンスを作成したため、toString()は機能しませんでした。 objectNameをすべてのインスタンスに設定することは、私のユースケースには少し多すぎたでしょう。

0
WJR