33

我想浏览 QML 组件列表并选择一种类型:

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

如何做到这一点?

4

4 回答 4

28

从 Qt 5.10 开始,您终于可以使用instanceOf来检查变量是否属于某个 QML 类型,请参阅“QML Support for Enum and InstanceOf Type Checks”

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))
  }
}
于 2018-01-26T11:36:26.350 回答
21

您不能直接为此使用typeof,因为它总是将“object”作为任何 QML 元素的类型返回给您。但是,您可以使用多种替代方法。一种是将每个元素的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")
        }
    }
  }
}
于 2012-12-18T07:33:50.163 回答
14

这是使用 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
   }
}
于 2015-02-07T15:59:58.063 回答
0

是的,这个线程已有 2 年历史,但也许我的回答可以帮助那里的人。

JSON.stringify()对我来说,比较 QML 元素就足够了。当然,如果两个不同的元素具有完全相同的属性和值,这会给您带来误报。(例如,当一个元素以相同的颜色、x、y 等位于另一个元素之上时)

toString() 对我不起作用,因为我从同一个基本组件创建了许多实例。将objectName设置为每个实例对于我的用例来说有点太多了。

于 2017-05-19T01:15:09.403 回答