我想知道是否有一种方法可以用var在javascript函数中选择具有特定id
或objectName
的已创建QML对象(var是与QML对象ID对应的字符串参数或名称)。
例如:
// main.qml
ApplicationWindow {
RoundButton {
id: btn1
}
RoundButton {
id: btn2
}
RoundButton {
id: btn3
}
// ...
function foo(qmlObjectNameOrId) {
qmlObjectNameOrId.text = "qmlObjectNameOrId is already in the document and has a property text that I want to set";
// Qt.findQmlObject(id) would have been great !
}
}
Qt.createQmlObject
不是解决方案,因为我想使用已经创建的QML对象。
在C ++中,实现此目的的方法是使用QQmlApplicationEngine
对象,然后使用QML根对象通过QML对象名执行选择:
int main(int argc, char *argv[])
{
QQmlApplicationEngine engine;
QString objectName = someFunction();
QObject* qmlObject = engine.rootObjects()[0]->findChild<QObject*>(objectName);
// use your qmlObject ...
}
将使用QMetaObject::invokeMethod(appWindow, "foo", Q_ARG(QVariant, "bar"));
在C ++中调用javascript函数
谢谢
[编辑1]尝试Roman Sverdlov的答案:
ApplicationWindow {
id: appWindow
objectName: "appWindow"
// ...
Pane {
id: buttonsContainer
objectName: "buttonsContainer"
property string disposition : "circular_1"
property int btnWidth : 130
property int btnHeight : 130
property int btnIconWidth : 40
property int btnIconHeight : 40
property int btnRadius : btnWidth / 2
property int btnMargin : 40
property int btnZ : 4
property int btnPressedBackground: Material.Purple
anchors.right: parent.right
anchors.left: parent.left
anchors.top: instructionContainer.bottom
anchors.bottom: parent.bottom
visible: false
Image {
id: background
height: buttonsContainer.height - 100
x: (buttonsContainer.width - width) / 2
y: (buttonsContainer.height - height) / 2
source: "qrc:///images/circle_background.png"
horizontalAlignment: Image.AlignHCenter
verticalAlignment: Image.AlignVCenter
fillMode: Image.PreserveAspectFit
}
Rectangle {
id: topLeft
color: Material.color(Material.Red)
x: 0
z: 1
height: parent.height / 2
width: parent.width / 2
}
Rectangle {
id: topRight
color: Material.color(Material.Green)
x: parent.width / 2
z: 1
anchors.top: parent.top
height: parent.height / 2
width: parent.width / 2
}
Label {
id: backgroundTextTop
text: "MONTER"
font.pixelSize: 40
x: (parent.width - width) / 2
y: (parent.height - height) / 2 - 50
z: 2
}
Rectangle {
id: bottomLeft
color: Material.color(Material.Green)
x: 0
z: 1
anchors.bottom: parent.bottom
height: parent.height / 2
width: parent.width / 2
}
Rectangle {
id: bottomRight
color: Material.color(Material.Red)
x: parent.width / 2
z: 1
anchors.bottom: parent.bottom
height: parent.height / 2
width: parent.width / 2
}
Label {
id: backgroundTextBottom
text: "PLONGER"
font.pixelSize: 40
x: (parent.width - width) / 2
y: (parent.height - height) / 2 + 200
z: 2
}
RoundButton {
id: btnB1MB
objectName: "btnB1MB"
width: buttonsContainer.btnWidth
height: buttonsContainer.btnHeight
radius: buttonsContainer.btnRadius
z: buttonsContainer.btnZ
display: AbstractButton.TextUnderIcon
onPressed: {
TestsRun.pressButton(Buttons.B1MB);
}
onReleased: {
TestsRun.releaseButton(Buttons.B1MB);
}
}
RoundButton {
id: btnB4MT
objectName: "btnB4MT"
width: buttonsContainer.btnWidth
height: buttonsContainer.btnHeight
radius: buttonsContainer.btnRadius
z: buttonsContainer.btnZ
display: AbstractButton.TextUnderIcon
onPressed: {
TestsRun.pressButton(Buttons.B4MT);
}
onReleased: {
TestsRun.releaseButton(Buttons.B4MT);
}
}
RoundButton {
id: btnB3MB
objectName: "btnB3MB"
width: buttonsContainer.btnWidth
height: buttonsContainer.btnHeight
radius: buttonsContainer.btnRadius
z: buttonsContainer.btnZ
display: AbstractButton.TextUnderIcon
onPressed: {
TestsRun.pressButton(Buttons.B3MB);
}
onReleased: {
TestsRun.releaseButton(Buttons.B3MB);
}
}
RoundButton {
id: btnB4PB
objectName: "btnB4PB"
width: buttonsContainer.btnWidth
height: buttonsContainer.btnHeight
radius: buttonsContainer.btnRadius
z: buttonsContainer.btnZ
display: AbstractButton.TextUnderIcon
onPressed: {
TestsRun.pressButton(Buttons.B4PB);
}
onReleased: {
TestsRun.releaseButton(Buttons.B4PB);
}
}
RoundButton {
id: btnB2MT
objectName: "btnB2MT"
width: buttonsContainer.btnWidth
height: buttonsContainer.btnHeight
radius: buttonsContainer.btnRadius
z: buttonsContainer.btnZ
display: AbstractButton.TextUnderIcon
onPressed: {
TestsRun.pressButton(Buttons.B2MT);
}
onReleased: {
TestsRun.releaseButton(Buttons.B2MT);
}
}
RoundButton {
id: btnB1PT
objectName: "btnB1PT"
width: buttonsContainer.btnWidth
height: buttonsContainer.btnHeight
radius: buttonsContainer.btnRadius
z: buttonsContainer.btnZ
display: AbstractButton.TextUnderIcon
onPressed: {
TestsRun.pressButton(Buttons.B1PT);
}
onReleased: {
TestsRun.releaseButton(Buttons.B1PT);
}
}
RoundButton {
id: btnB2PB
objectName: "btnB2PB"
width: buttonsContainer.btnWidth
height: buttonsContainer.btnHeight
radius: buttonsContainer.btnRadius
z: buttonsContainer.btnZ
display: AbstractButton.TextUnderIcon
onPressed: {
TestsRun.pressButton(Buttons.B2PB);
}
onReleased: {
TestsRun.releaseButton(Buttons.B2PB);
}
}
RoundButton {
id: btnB3PT
objectName: "btnB3PT"
width: buttonsContainer.btnWidth
height: buttonsContainer.btnHeight
radius: buttonsContainer.btnRadius
z: buttonsContainer.btnZ
display: AbstractButton.TextUnderIcon
onPressed: {
TestsRun.pressButton(Buttons.B3PT);
}
onReleased: {
TestsRun.releaseButton(Buttons.B3PT);
}
}
Component.onCompleted: {
setButtonsPosition(buttonsContainer.disposition);
}
}
/**
* Get a QML element by objectName property
*
* @todo Not working
*
* @param {String} objectName - The QML object name to get
*/
function getQmlObjectByName(objectName) {
console.log("buttonsContainer.children.length", buttonsContainer.children.length);
return getQmlObjectByNameRecursive(buttonsContainer, objectName)
}
/**
* Get a QML element by objectName property
*
* @todo Not working
*
* @param {Object} object - The QML object to find the QML element in
* @param {String} objectName - The QML object name to get
*/
function getQmlObjectByNameRecursive(object, objectName) {
for (let child in object.children) {
console.log(object.children[child].objectName);
if (object.children[child].objectName === objectName) {
console.log('found');
return object.children[child];
}
if (typeof object.children[child].children !== 'undefined') {
console.log('children', object.children[child]);
return getQmlObjectByNameRecursive(object.children[child], objectName);
}
}
}
输出
qml: buttonsContainer.children.length 2
qml: Pane
qml: children QQuickContentItem(0x55c4e2a145d0, "Pane")
qml:
qml: children QQuickImage(0x55c4e2a1cc80)
qml: undefined
答案 0 :(得分:1)
如果您为对象设置了objectName
属性,则可以使用类似的
ApplicationWindow {
id: appWin
RoundButton {
id: btn1
objectName: "btn1"
}
RoundButton {
id: btn2
objectName: "btn2"
}
// ...
function foo(objectName) {
for(var child in appWin.children) {
if(appWin.children[child].objectName === objectName) {
appWin.children[child].text = "qmlObjectNameOrId is already in the document and has a property text that I want to set";
break
}
}
}
}
当然看起来很丑,但是如果您非常需要它...
答案 1 :(得分:1)
通过遍历一个我想通过objectName属性在其中找到QML对象的QML容器解决了问题。
由于罗马·斯维尔德洛夫,“ DOM遍历”是通过contentChildren
属性而不是children
属性完成的。
/**
* Get a QML element by objectName property in buttonsContainer container
*
* @param {String} objectName - The QML object name to get
*/
function getQmlObjectByName(objectName) {
for (let child in buttonsContainer.contentChildren) {
if (buttonsContainer.contentChildren[child].objectName === objectName) {
return buttonsContainer.contentChildren[child];
}
}
}