javascript 如何在 QML 中执行“is_a”、“typeof”或 instanceof?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13923794/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 20:11:29  来源:igfitidea点击:

How to do a "is_a", "typeof" or instanceof in QML?

javascriptqml

提问by Scott Montgomerie

I want to run through a list of QML components and choose one type:

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

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

How does one accomplish this?

如何做到这一点?

采纳答案by JuliusG

You can't use typeoffor this directly because it will always return you 'object'as a type of any QML element. There are several alternatives however that you could use. One is setting the objectNameof the each element to its type and check that in your loop or define a property and check for that property. This will require a bit more work but you could create your qml element that has this property and than use it wherever you need it. Here is a sample code:

您不能直接为此使用typeof,因为它总是将“对象”作为任何 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")
        }
    }
  }
}

回答by user5315753

Since Qt 5.10, you can finally use instanceOfto check whether a variable is of a certain QML type, see "QML Support for Enum and InstanceOf Type Checks".

从 Qt 5.10 开始,您终于可以使用instanceOf来检查变量是否属于某种 QML 类型,请参阅“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))
  }
}

回答by jichi

Here's another approach using toString() (which might not be portable to the future version of QML):

这是使用 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
   }
}

回答by WJR

Yes, this thread is 2 yrs old but perhaps my answer could help someone out there.

是的,这个线程已经 2 岁了,但也许我的回答可以帮助那里的人。

For me, it was good enough use JSON.stringify()to compare QML elements. Of course, if two different elements have exactly the same properties and values, this would give you false positive. (eg when one element is on top of another with same color, x, y, etc)

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

toString() did not work for me since I've created many instances from same base component. Setting objectNameto every instance would have been a bit too much for my use case.

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