feat(MonitoringTool): Inspect arbitrary model found by objectName
Closes: #14971
This commit is contained in:
parent
2c1806434a
commit
80eaf6ba89
|
@ -0,0 +1,265 @@
|
||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
|
import QtQuick.Layouts 1.15
|
||||||
|
|
||||||
|
import Monitoring 1.0
|
||||||
|
|
||||||
|
|
||||||
|
Pane {
|
||||||
|
property string name
|
||||||
|
property var model
|
||||||
|
readonly property var rootModel: model
|
||||||
|
|
||||||
|
property bool showControls: true
|
||||||
|
|
||||||
|
readonly property var roles: model ? Monitor.modelRoles(model) : []
|
||||||
|
|
||||||
|
readonly property var rolesModelContent: roles.map(role => ({
|
||||||
|
visible: true,
|
||||||
|
name: role.name,
|
||||||
|
width: Math.ceil(fontMetrics.advanceWidth(` ${role.name} `))
|
||||||
|
}))
|
||||||
|
|
||||||
|
onRolesModelContentChanged: {
|
||||||
|
rolesModel.clear()
|
||||||
|
rolesModel.append(rolesModelContent)
|
||||||
|
}
|
||||||
|
|
||||||
|
property int columnsTotalWidth:
|
||||||
|
rolesModelContent.reduce((a, x) => a + x.width, 0)
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: rolesModel
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
clear()
|
||||||
|
append(rolesModelContent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Control {
|
||||||
|
id: helperControl
|
||||||
|
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
FontMetrics {
|
||||||
|
id: fontMetrics
|
||||||
|
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
visible: showControls
|
||||||
|
|
||||||
|
RoundButton {
|
||||||
|
text: "⬅️"
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
inspectionStackView.pop(StackView.Immediate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TextInput {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
|
||||||
|
text: name
|
||||||
|
font.pixelSize: 20
|
||||||
|
font.bold: true
|
||||||
|
|
||||||
|
selectByMouse: true
|
||||||
|
readOnly: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MenuSeparator {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
visible: showControls
|
||||||
|
|
||||||
|
text: "Hint: use right/left button click on a column " +
|
||||||
|
"header to adjust width, press cell content to " +
|
||||||
|
"see full value"
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: model ? `rows count: ${model.rowCount()}` : ""
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
ScrollBar.vertical: ScrollBar {}
|
||||||
|
ScrollBar.horizontal: ScrollBar {}
|
||||||
|
|
||||||
|
clip: true
|
||||||
|
contentWidth: columnsTotalWidth
|
||||||
|
flickableDirection: Flickable.AutoFlickDirection
|
||||||
|
|
||||||
|
model: rootModel
|
||||||
|
|
||||||
|
delegate: Rectangle {
|
||||||
|
implicitWidth: flow.implicitWidth
|
||||||
|
implicitHeight: flow.implicitHeight
|
||||||
|
|
||||||
|
readonly property var topModel: model
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: flow
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: rolesModel
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: label
|
||||||
|
|
||||||
|
width: model.width
|
||||||
|
height: implicitHeight * 1.2
|
||||||
|
|
||||||
|
text: {
|
||||||
|
const value = topModel[model.name]
|
||||||
|
|
||||||
|
if (value === undefined || value === null)
|
||||||
|
return ""
|
||||||
|
|
||||||
|
const isModel = Monitor.isModel(value)
|
||||||
|
|
||||||
|
let text = value.toString()
|
||||||
|
|
||||||
|
if (isModel) {
|
||||||
|
text += " (" + value.rowCount() + ")"
|
||||||
|
}
|
||||||
|
|
||||||
|
return text
|
||||||
|
}
|
||||||
|
|
||||||
|
elide: Text.ElideRight
|
||||||
|
maximumLineCount: 1
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
|
||||||
|
leftPadding: 2
|
||||||
|
rightPadding: 1
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
height: 1
|
||||||
|
color: "gray"
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.left: parent.left
|
||||||
|
width: 1
|
||||||
|
color: "gray"
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: labelMouseArea
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
const value = topModel[model.name]
|
||||||
|
const isModel = Monitor.isModel(value)
|
||||||
|
|
||||||
|
if (isModel)
|
||||||
|
loader.active = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: loader
|
||||||
|
|
||||||
|
active: false
|
||||||
|
sourceComponent: ApplicationWindow {
|
||||||
|
width: 500
|
||||||
|
height: 400
|
||||||
|
visible: true
|
||||||
|
|
||||||
|
onClosing: loader.active = false
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
anchors.fill: parent
|
||||||
|
sourceComponent: modelInspectionComponent
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
item.showControls = false
|
||||||
|
item.model = topModel[model.name]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ToolTip.visible: labelMouseArea.pressed
|
||||||
|
ToolTip.text: label.text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
headerPositioning: ListView.OverlayHeader
|
||||||
|
|
||||||
|
header: Item {
|
||||||
|
implicitWidth: headerFlow.implicitWidth
|
||||||
|
implicitHeight: headerFlow.implicitHeight * 1.5
|
||||||
|
z: 2
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
color: "whitesmoke"
|
||||||
|
anchors.fill: parent
|
||||||
|
border.color: "gray"
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: headerFlow
|
||||||
|
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: rolesModel
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: ` ${model.name} `
|
||||||
|
font.bold: true
|
||||||
|
|
||||||
|
width: model.width
|
||||||
|
elide: Text.ElideRight
|
||||||
|
maximumLineCount: 1
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
const factor = 1.5
|
||||||
|
const oldWidth = model.width
|
||||||
|
const leftBtn = mouse.button === Qt.LeftButton
|
||||||
|
|
||||||
|
const newWidth
|
||||||
|
= Math.ceil(leftBtn ? oldWidth * factor : oldWidth / factor)
|
||||||
|
|
||||||
|
model.width = newWidth
|
||||||
|
columnsTotalWidth += newWidth - oldWidth
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,11 +1,48 @@
|
||||||
import QtQuick 2.14
|
import QtQuick 2.15
|
||||||
import QtQuick.Controls 2.14
|
import QtQuick.Controls 2.15
|
||||||
import QtQuick.Layouts 1.14
|
import QtQuick.Layouts 1.15
|
||||||
|
|
||||||
import Monitoring 1.0
|
import Monitoring 1.0
|
||||||
|
import Qt.labs.settings 1.0
|
||||||
|
|
||||||
|
import AppLayouts.Wallet.stores 1.0 as WalletStores
|
||||||
|
import shared.stores 1.0 as SharedStores
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
Settings {
|
||||||
|
property alias tabIndex: tabBar.currentIndex
|
||||||
|
property alias modelObjectName: objectNameTextFiled.text
|
||||||
|
property alias modelObjectRootName: rootTextField.text
|
||||||
|
}
|
||||||
|
|
||||||
|
TabBar {
|
||||||
|
id: tabBar
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.bottomMargin: 10
|
||||||
|
|
||||||
|
TabButton {
|
||||||
|
text: "Context properties inspection"
|
||||||
|
}
|
||||||
|
TabButton {
|
||||||
|
text: "Models inspection"
|
||||||
|
}
|
||||||
|
|
||||||
|
currentIndex: swipeView.currentIndex
|
||||||
|
}
|
||||||
|
|
||||||
|
StackLayout {
|
||||||
|
id: swipeView
|
||||||
|
|
||||||
|
currentIndex: tabBar.currentIndex
|
||||||
|
//anchors.fill: parent
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
SplitView {
|
SplitView {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
@ -79,257 +116,7 @@ Component {
|
||||||
Component {
|
Component {
|
||||||
id: modelInspectionComponent
|
id: modelInspectionComponent
|
||||||
|
|
||||||
Pane {
|
ModelInspectionPane {}
|
||||||
property string name
|
|
||||||
property var model
|
|
||||||
readonly property var rootModel: model
|
|
||||||
|
|
||||||
property bool showControls: true
|
|
||||||
|
|
||||||
readonly property var roles: Monitor.modelRoles(model)
|
|
||||||
|
|
||||||
readonly property var rolesModelContent: roles.map(role => ({
|
|
||||||
visible: true,
|
|
||||||
name: role.name,
|
|
||||||
width: Math.ceil(fontMetrics.advanceWidth(` ${role.name} `))
|
|
||||||
}))
|
|
||||||
|
|
||||||
onRolesModelContentChanged: {
|
|
||||||
rolesModel.clear()
|
|
||||||
rolesModel.append(rolesModelContent)
|
|
||||||
}
|
|
||||||
|
|
||||||
property int columnsTotalWidth:
|
|
||||||
rolesModelContent.reduce((a, x) => a + x.width, 0)
|
|
||||||
|
|
||||||
ListModel {
|
|
||||||
id: rolesModel
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
clear()
|
|
||||||
append(rolesModelContent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Control {
|
|
||||||
id: helperControl
|
|
||||||
|
|
||||||
font.bold: true
|
|
||||||
}
|
|
||||||
|
|
||||||
FontMetrics {
|
|
||||||
id: fontMetrics
|
|
||||||
|
|
||||||
font.bold: true
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
visible: showControls
|
|
||||||
|
|
||||||
RoundButton {
|
|
||||||
text: "⬅️"
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
inspectionStackView.pop(StackView.Immediate)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TextInput {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.alignment: Qt.AlignVCenter
|
|
||||||
|
|
||||||
text: name
|
|
||||||
font.pixelSize: 20
|
|
||||||
font.bold: true
|
|
||||||
|
|
||||||
selectByMouse: true
|
|
||||||
readOnly: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MenuSeparator {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
visible: showControls
|
|
||||||
|
|
||||||
text: "Hint: use right/left button click on a column " +
|
|
||||||
"header to ajust width, press cell content to " +
|
|
||||||
"see full value"
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
text: `rows count: ${model.rowCount()}`
|
|
||||||
font.bold: true
|
|
||||||
}
|
|
||||||
|
|
||||||
ListView {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
|
|
||||||
clip: true
|
|
||||||
contentWidth: columnsTotalWidth
|
|
||||||
flickableDirection: Flickable.AutoFlickDirection
|
|
||||||
|
|
||||||
model: rootModel
|
|
||||||
|
|
||||||
delegate: Rectangle {
|
|
||||||
implicitWidth: flow.implicitWidth
|
|
||||||
implicitHeight: flow.implicitHeight
|
|
||||||
|
|
||||||
readonly property var topModel: model
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: flow
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
model: rolesModel
|
|
||||||
|
|
||||||
Label {
|
|
||||||
id: label
|
|
||||||
|
|
||||||
width: model.width
|
|
||||||
height: implicitHeight * 1.2
|
|
||||||
|
|
||||||
text: {
|
|
||||||
const value = topModel[model.name]
|
|
||||||
const isModel = Monitor.isModel(value)
|
|
||||||
|
|
||||||
let text = value.toString()
|
|
||||||
|
|
||||||
if (isModel) {
|
|
||||||
text += " (" + value.rowCount() + ")"
|
|
||||||
}
|
|
||||||
|
|
||||||
return text
|
|
||||||
}
|
|
||||||
|
|
||||||
elide: Text.ElideRight
|
|
||||||
maximumLineCount: 1
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
|
|
||||||
leftPadding: 2
|
|
||||||
rightPadding: 1
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
height: 1
|
|
||||||
color: "gray"
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
anchors.left: parent.left
|
|
||||||
width: 1
|
|
||||||
color: "gray"
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: labelMouseArea
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
const value = topModel[model.name]
|
|
||||||
const isModel = Monitor.isModel(value)
|
|
||||||
|
|
||||||
if (isModel)
|
|
||||||
loader.active = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: loader
|
|
||||||
|
|
||||||
active: false
|
|
||||||
sourceComponent: ApplicationWindow {
|
|
||||||
width: 500
|
|
||||||
height: 400
|
|
||||||
visible: true
|
|
||||||
|
|
||||||
onClosing: loader.active = false
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
anchors.fill: parent
|
|
||||||
sourceComponent: modelInspectionComponent
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
item.showControls = false
|
|
||||||
item.model = topModel[model.name]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ToolTip.visible: labelMouseArea.pressed
|
|
||||||
ToolTip.text: label.text
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
headerPositioning: ListView.OverlayHeader
|
|
||||||
|
|
||||||
header: Item {
|
|
||||||
implicitWidth: headerFlow.implicitWidth
|
|
||||||
implicitHeight: headerFlow.implicitHeight * 1.5
|
|
||||||
z: 2
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
color: "whitesmoke"
|
|
||||||
anchors.fill: parent
|
|
||||||
border.color: "gray"
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: headerFlow
|
|
||||||
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
model: rolesModel
|
|
||||||
|
|
||||||
Label {
|
|
||||||
text: ` ${model.name} `
|
|
||||||
font.bold: true
|
|
||||||
|
|
||||||
width: model.width
|
|
||||||
elide: Text.ElideRight
|
|
||||||
maximumLineCount: 1
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
const factor = 1.5
|
|
||||||
const oldWidth = model.width
|
|
||||||
const leftBtn = mouse.button === Qt.LeftButton
|
|
||||||
|
|
||||||
const newWidth
|
|
||||||
= Math.ceil(leftBtn ? oldWidth * factor : oldWidth / factor)
|
|
||||||
|
|
||||||
model.width = newWidth
|
|
||||||
columnsTotalWidth += newWidth - oldWidth
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
|
@ -499,4 +286,90 @@ Component {
|
||||||
SplitView.minimumWidth: 100
|
SplitView.minimumWidth: 100
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Label {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
|
||||||
|
text: "Note: 'applicationWindow' is good root object in"
|
||||||
|
+ " most cases. 'WalletStores.RootStore' and"
|
||||||
|
+ " `SharedStores.RootStore` are also exposed for"
|
||||||
|
+ " convenience for models created within those singletons."
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillHeight: false
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: "Model's object name:"
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField {
|
||||||
|
id: objectNameTextFiled
|
||||||
|
|
||||||
|
selectByMouse: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: "Root:"
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField {
|
||||||
|
id: rootTextField
|
||||||
|
|
||||||
|
text: "applicationWindow"
|
||||||
|
selectByMouse: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
text: "Search"
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
let rootObj = null
|
||||||
|
|
||||||
|
try {
|
||||||
|
rootObj = eval(rootTextField.text)
|
||||||
|
} catch (error) {
|
||||||
|
objLabel.objStr = "Root object not found!"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const obj = Monitor.findChild(
|
||||||
|
rootObj, objectNameTextFiled.text)
|
||||||
|
|
||||||
|
objLabel.objStr = obj && Monitor.isModel(obj)
|
||||||
|
? obj.toString() : "Model not found!"
|
||||||
|
rolesModelContent.model = obj
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: objLabel
|
||||||
|
|
||||||
|
property string objStr
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
visible: objStr !== ""
|
||||||
|
|
||||||
|
text: "Object: " + objStr
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelInspectionPane {
|
||||||
|
id: rolesModelContent
|
||||||
|
|
||||||
|
showControls: false
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,8 @@ public:
|
||||||
Q_INVOKABLE QString typeName(const QVariant &obj) const;
|
Q_INVOKABLE QString typeName(const QVariant &obj) const;
|
||||||
Q_INVOKABLE QJSValue modelRoles(QAbstractItemModel *model) const;
|
Q_INVOKABLE QJSValue modelRoles(QAbstractItemModel *model) const;
|
||||||
|
|
||||||
|
Q_INVOKABLE QObject* findChild(QObject* obj, const QString& name) const;
|
||||||
|
|
||||||
static Monitor& instance();
|
static Monitor& instance();
|
||||||
static QObject* qmlInstance(QQmlEngine *engine, QJSEngine *scriptEngine);
|
static QObject* qmlInstance(QQmlEngine *engine, QJSEngine *scriptEngine);
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,8 @@
|
||||||
#include <QQmlComponent>
|
#include <QQmlComponent>
|
||||||
#include <QQuickWindow>
|
#include <QQuickWindow>
|
||||||
|
|
||||||
void Monitor::initialize(QQmlApplicationEngine* engine) {
|
void Monitor::initialize(QQmlApplicationEngine* engine)
|
||||||
|
{
|
||||||
QObject::connect(engine, &QQmlApplicationEngine::objectCreated, this,
|
QObject::connect(engine, &QQmlApplicationEngine::objectCreated, this,
|
||||||
[engine](QObject *obj, const QUrl &objUrl) {
|
[engine](QObject *obj, const QUrl &objUrl) {
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
|
@ -46,6 +47,11 @@ bool Monitor::isModel(const QVariant &obj) const
|
||||||
return qobject_cast<QAbstractItemModel*>(obj.value<QObject*>()) != nullptr;
|
return qobject_cast<QAbstractItemModel*>(obj.value<QObject*>()) != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QObject* Monitor::findChild(QObject* obj, const QString& name) const
|
||||||
|
{
|
||||||
|
return obj == nullptr ? nullptr : obj->findChild<QObject*>(name);
|
||||||
|
}
|
||||||
|
|
||||||
QString Monitor::typeName(const QVariant &obj) const
|
QString Monitor::typeName(const QVariant &obj) const
|
||||||
{
|
{
|
||||||
if (obj.canConvert<QObject*>())
|
if (obj.canConvert<QObject*>())
|
||||||
|
|
Loading…
Reference in New Issue