Есть ли способ перечислить все элементы/свойства объекта в QML и Qt 5.1?
Например:
var obj=myQObject;
console.log(obj)
// expected output:
// obj { x:123..... }
Это будет очень полезно для отладки.
Есть ли способ перечислить все элементы/свойства объекта в QML и Qt 5.1?
Например:
var obj=myQObject;
console.log(obj)
// expected output:
// obj { x:123..... }
Это будет очень полезно для отладки.
Прямой javascript предлагает то, что вы ищете:
JSON.stringify(anything)
Он работает с элементами QML, такими как Rectangle, и также работает на большинстве произвольных объектов!
С помощью метаобъектов вы можете отлаживать все свойства любого QML obj
(т.е. QQuickItem).
Вам нужен С++ для получения метаобъекта компонента QML и возврата имен и значений свойств в текст в QML.
Сначала вы создаете класс QMLDebugger
в С++ с помощью метода 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;
}
Эта функция может быть статической или случайной, не имеет значения. QML в любом случае не поддерживает экспорт статических методов из С++ в QML. Я использую заголовок:
public:
Q_INVOKABLE static QString properties(QQuickItem *item, bool linebreak = true);
Теперь вы экспортируете класс в QML. В вас main.cpp
добавьте
#include "qmldebugger.h"
и
qmlRegisterType<QMLDebugger>("MyDemoLibrary", 1, 0, "QMLDebugger");
В вашем файле QML импортируйте новую библиотеку, создайте экземпляр QMLDebugger и начните счастливую отладку:
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));
}
}
Полный исходный код доступен как минимальный проект Qt Creator на: https://github.com/webmaster128/QMLDebugger
Просто преобразуйте компонент/объект QML/С++ в объект JavaScript var и используйте синтаксис for-each для отображения всего свойства:
function listProperty(item)
{
for (var p in item)
console.log(p + ": " + item[p]);
}
в вашем файле QML, просто позвоните
onClicked:
{
listProperty(ItemID)
//or with this to list self properties
listProperty(this)
}
в случае, если кто-либо хочет перечислить только свойства объекта, никаких сигналов и слотов вы не сможете использовать этот
function listProperty(item)
{
for (var p in item)
{
if( typeof item[p] != "function" )
if(p != "objectName")
console.log(p + ":" + item[p]);
}
}
Я еще не видел решения для повторения всех свойств. Но, возможно, это поможет вам в качестве первого шага.
Для каждого Quick Item вы можете распечатать свойства 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));
}
Вывод:
{'activeFocus': false, 'activeFocusOnTab': false, 'anchors.alignWhenCentered': true, 'anchors.baseline': QVariant (QQuickAnchorLine), 'anchors.baselineOffset': 0, 'anchors.bottom': QVariant (QQuickAnchorLine), 'anchors.bottomMargin': 0, 'anchors.centerIn': QQuickRectangle_QML_0 (0x29857d0), 'anchors.fill': null, 'anchors.horizontalCenter': QVariant (QQuickAnchorLine), 'anchors.horizontalCenterOffset': 0, 'anchors.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,' children ': [object Object], 'childrenRect.height': 0, 'childrenRect.width': 0, 'childrenRect.x': 0, 'childrenRect.y': 0, 'clip': false, 'data': [object Object ], '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,' opacity ': 1, 'parent': QQuickRectangle_QML_0 (0x29857d0), 'resources': [object Object], 'rotation': 0, 'scale': 1, 'smooth': true, 'state':, 'states': [object Object], 'transform': [object Object], 'transformOrigin': 4, 'transitions': [object Object], 'visible': true, 'visibleChildren': [object Object], 'width': 80.5625, 'x': 139.71875, 'y': 171, 'z': 0,}
Если вас интересует не только консольная отладка, есть программа GammaRay от KDAB (ссылка), которая позволяет вам изменить все свойства во время выполнения программы QWidgets или QtQuick. Довольно аккуратно!