2012-12-17 11 views

Odpowiedz

14

Nie można używać typeof tego bezpośrednio, ponieważ zawsze będzie powrót „przedmiot” jako rodzaj jakiegokolwiek elementu QML. Istnieje jednak kilka alternatyw, z których można skorzystać. Jedną z nich jest ustawienie objectName każdego elementu na jego typ i sprawdzenie w pętli lub zdefiniowanie właściwości i sprawdzenie tej właściwości. Będzie to wymagało nieco więcej pracy, ale możesz stworzyć element qml, który ma tę właściwość i używać go tam, gdzie jest to potrzebne. Oto przykładowy kod:

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") 
     } 
    } 
    } 
} 
9

Oto kolejny podejście użyciu toString() (które może nie być przenośne do przyszłej wersji 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 
    } 
} 
+1

Nicea podstęp. Zmodyfikuję instrukcję return dla wygody: 'return str.indexOf (className +" (") == 0 || str.indexOf (className +" _QML ") == 0 || qmltypeof (obj," QQuick " + className); ' – hedayat

+1

Nawet jeśli nie jest przenośny,' toString' doskonale nadaje się do debugowania. –

0

Tak, ten wątek jest o 2 lat życia ale może moja odpowiedź może pomóc komuś tam.

Dla mnie było wystarczająco dobre użycie JSON.stringify() do porównania elementów QML. Oczywiście, jeśli dwa różne elementy mają dokładnie takie same właściwości i wartości, dałoby to fałszywe pozytywne wyniki. (np. gdy jeden element znajduje się na drugim z tego samego koloru, x, y itp.)

ToString() nie działało dla mnie, ponieważ stworzyłem wiele instancji z tego samego komponentu podstawowego. Ustawienie objectName na każde wystąpienie byłoby trochę za duże dla mojego przypadku użycia.

2

Od Qt 5.10, można wreszcie korzystać instanceof, by sprawdzić, czy zmienna jest pewnego rodzaju QML: https://v-play.net/updates/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)) 
    } 
}