Est-il possible de lister tous les objets membres/propriétés dans QML & Qt 5.1?
Tel que:
var obj=myQObject;
console.log(obj)
// expected output:
// obj { x:123..... }
Cela serait très utile pour le débogage.
Straight javascript offre ce que vous recherchez:
JSON.stringify(anything)
Cela fonctionne sur les éléments QML tels que Rectangle, et sur la plupart des objets arbitraires!
Avec les méta-objets, vous pouvez déboguer toutes les propriétés de tout QML obj
(c'est-à-dire QQuickItem ).
Vous avez besoin de C++ pour obtenir le méta-objet d'un composant QML et récupérer les noms et les valeurs des propriétés sous forme de texte au format QML.
Tout d'abord, vous créez une classe QMLDebugger
en C++ avec une méthode properties
:
QString QMLDebugger::properties(QQuickItem *item, bool linebreak)
{
const QMetaObject *meta = item->metaObject();
QHash<QString, QVariant> list;
for (int i = 0; i < meta->propertyCount(); i++)
{
QMetaProperty property = meta->property(i);
const char* name = property.name();
QVariant value = item->property(name);
list[name] = value;
}
QString out;
QHashIterator<QString, QVariant> i(list);
while (i.hasNext()) {
i.next();
if (!out.isEmpty())
{
out += ", ";
if (linebreak) out += "\n";
}
out.append(i.key());
out.append(": ");
out.append(i.value().toString());
}
return out;
}
Cette fonction peut être statique ou instanceiable, peu importe. QML ne prend pas en charge l’exportation de méthodes statiques de C++ vers QML. J'utilise l'en-tête:
public:
Q_INVOKABLE static QString properties(QQuickItem *item, bool linebreak = true);
Vous exportez maintenant la classe au format QML. Dans votre main.cpp
ajouter
#include "qmldebugger.h"
et
qmlRegisterType<QMLDebugger>("MyDemoLibrary", 1, 0, "QMLDebugger");
Dans votre fichier QML, importez votre nouvelle bibliothèque, créez une instance de QMLDebugger et démarrez un débogage heureux:
import QtQuick 2.0
import MyDemoLibrary 1.0
Rectangle {
id: mainRectangle
width: 360
height: 360
color: "silver"
Text {
id: textElement
color: "#d71f1f"
text: qsTr("Hello World")
font.bold: true
font.italic: true
font.underline: true
style: Text.Raised
horizontalAlignment: Text.AlignHCenter
font.pointSize: 16
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
}
QMLDebugger {
id: qmlDebugger
}
Component.onCompleted: {
console.log("Debug mainRectangle:");
console.log(qmlDebugger.properties(mainRectangle));
console.log("Debug textElement:");
console.log(qmlDebugger.properties(textElement, false));
}
}
Le code source complet est disponible en tant que projet minimal de Qt Creator sur: https://github.com/webmaster128/QMLDebugger
Convertissez simplement le composant/objet QML/C++ en objet var JavaScript et utilisez la syntaxe for-each pour répertorier toutes les propriétés
function listProperty(item)
{
for (var p in item)
console.log(p + ": " + item[p]);
}
dans votre fichier QML, appelez simplement
onClicked:
{
listProperty(ItemID)
//or with this to list self properties
listProperty(this)
}
dans le cas où quelqu'un voudrait lister uniquement les propriétés d'un objet, aucun signal ni slot
function listProperty(item)
{
for (var p in item)
{
if( typeof item[p] != "function" )
if(p != "objectName")
console.log(p + ":" + item[p]);
}
}
Si vous n'êtes pas seulement intéressé par le débogage de la console, il existe un programme appelé GammaRay by KDAB ( link ) qui vous permet de visualiser et de modifier toutes les propriétés lors de l'exécution d'un programme basé sur QWidgets ou QtQuick. Génial!
Je n'ai pas encore vu de solution pour itérer toutes les propriétés. Mais peut-être que cela vous aide dans un premier temps.
Pour chaque article rapide vous pouvez imprimer les propriétés de Item
:
import QtQuick 2.0
Rectangle {
width: 360
height: 360
function debugQuickItem(object) {
var properties = {
'activeFocus': object.activeFocus,
'activeFocusOnTab': object.activeFocusOnTab,
'anchors.alignWhenCentered': object.anchors.alignWhenCentered,
'anchors.baseline': object.anchors.baseline,
'anchors.baselineOffset': object.anchors.baselineOffset,
'anchors.bottom': object.anchors.bottom,
'anchors.bottomMargin': object.anchors.bottomMargin,
'anchors.centerIn': object.anchors.centerIn,
'anchors.fill': object.anchors.fill,
'anchors.horizontalCenter': object.anchors.horizontalCenter,
'anchors.horizontalCenterOffset': object.anchors.horizontalCenterOffset,
'anchors.left': object.anchors.left,
'anchors.leftMargin': object.anchors.leftMargin,
'anchors.margins': object.anchors.margins,
'anchors.right': object.anchors.right,
'anchors.rightMargin': object.anchors.rightMargin,
'anchors.top': object.anchors.top,
'anchors.topMargin': object.anchors.topMargin,
'anchors.verticalCenter': object.anchors.verticalCenter,
'anchors.verticalCenterOffset': object.anchors.verticalCenterOffset,
'antialiasing': object.antialiasing,
'baselineOffset': object.baselineOffset,
'children': object.children,
'childrenRect.height': object.childrenRect.height,
'childrenRect.width': object.childrenRect.width,
'childrenRect.x': object.childrenRect.x,
'childrenRect.y': object.childrenRect.y,
'clip': object.clip,
'data': object.data,
'enabled': object.enabled,
'focus': object.focus,
'height': object.height,
'implicitHeight': object.implicitHeight,
'implicitWidth': object.implicitWidth,
'layer.effect': object.layer.effect,
'layer.enabled': object.layer.enabled,
'layer.format': object.layer.format,
'layer.mipmap': object.layer.mipmap,
'layer.samplerName': object.layer.samplerName,
'layer.smooth': object.layer.smooth,
'layer.sourceRect': object.layer.sourceRect,
'layer.textureSize': object.layer.textureSize,
'layer.wrapMode': object.layer.wrapMode,
'opacity': object.opacity,
'parent': object.parent,
'resources': object.resources,
'rotation': object.rotation,
'scale': object.scale,
'smooth': object.smooth,
'state': object.state,
'states': object.states,
'transform': object.transform,
'transformOrigin': object.transformOrigin,
'transitions': object.transitions,
'visible': object.visible,
'visibleChildren': object.visibleChildren,
'width': object.width,
'x': object.x,
'y': object.y,
'z': object.z,
}
var out = "{ "
for (var key in properties)
{
out += "'" + key + "': " + properties[key] + ", "
}
out += "}"
return out;
}
Text {
id: textObject
anchors.centerIn: parent
text: "Hello World"
}
Component.onCompleted: console.log(debugQuickItem(textObject));
}
Sortie:
{'activeFocus': false, 'activeFocusOnTab': false, 'anchors.alignWhenCentered': true, 'anchors.baseline': QVariant (QQuickAnchorLine), 'anchors.baselineOffset': 0, 'anchors.bottom' , 'anchors.bottomMargin': 0, 'anchors.centerIn': QQuickRectangle_QML_0 (0x29857d0), 'anchors.fill': null, 'anchors.horizontalCenter': QVariant (QQuickAnchorLine), 'anchors.horizontalCenterOffset': left ': QVariant (QQuickAnchorLine),' anchors.leftMargin ': 0,' anchors.margins ': 0,' anchors.right ': QVariant (QQuickAnchorLine),' anchors.rightMargin ': 0,' anchors.top ': QVariant (QQuickAnchorLine), 'anchors.topMargin': 0, 'anchors.verticalCenter': QVariant (QQuickAnchorLine), 'anchors.verticalCenterOffset': 0, 'antialiasing': false, 'baselineOffset': 14, 'enfants': 14, 'object Object' ], 'childrenRect.height': 0, 'childrenRect.width': 0, 'childrenRect.x': 0, 'childrenRect.y': 0, 'clip': false, 'data': [objet Objet], ' enabled ': true,' focus ': false,' height ': 17,' implicitHeight ': 17,' implicitWidth ': 80.5625,' layer.effect ': null,' layer.enabled ': false,' layer.format ': 6408,' layer.mipmap ': false,' layer.samplerName ': source,' layer.smooth ' : false, 'layer.sourceRect': QRectF (0, 0, 0, 0), 'layer.textureSize': QSize (-1, -1), 'layer.wrapMode': 0, 'opacité': 1, ' parent ': QQuickRectangle_QML_0 (0x29857d0),' resources ': [objet Object],' rotation ': 0,' scale ': 1,' smooth ': true,' state ':,' states ': [objet Object],' transform ': [objet Object],' transformOrigin ': 4,' transitions ': [objet Object],' visible ': true,' visibleChildren ': [objet Object],' largeur ': 80.5625,' x ': 139.71875, 'y': 171, 'z': 0,}