如何将qml子组件信号连接到c++插槽

How to connect a qml child component signal to a c++ slot

本文关键字:连接 c++ 插槽 信号 组件 qml      更新时间:2023-10-16

我想将子项目组件信号连接到c++插槽,但它不工作。我有一个文件 ButtonItem。qml中的代码类似于

Item {
    id: button
    property string label
    property alias cellColor : rectangle.color
    Rectangle {
        id : rectangle
        objectName : "rectangle"
        height : 40
        width : 50
        radius: 10
        color: "gray"
        Text {
            anchors.centerIn: parent
            font.pixelSize: 20
            text: button.label
            color: "white"
        }
    }
}

,主文件为 button.qml

Rectangle {
    id : rect
    width: systemWidth
    height: systemHeight.getHeight()
    Text{
        id : text
        objectName : "text"
        height : 20
        width : 10
        anchors.centerIn : parent
        text : systemHeight.getText()
    }
        ButtonItem {
            signal qmlMsg(string msg)
            objectName : "button"
            id : button3
            cellColor : "blue"
            label : "3"
            MouseArea {
                anchors.fill : parent
                onClicked : button3.qmlMsg("Hello World")
            }
        }
}

和在我的主源文件中的代码是

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent)
{
    QDeclarativeView *qmlView = new QDeclarativeView;
    qmlView->rootContext()->setContextProperty("systemWidth", 1000);
    Sample sObj;
    qmlView->rootContext()->setContextProperty("systemHeight", &sObj);
    this->setCentralWidget(qmlView);
    qmlView->setSource(QUrl::fromLocalFile("E:/samplecode/qmlsample/button.qml"));
    QObject *obj = qmlView->rootObject();
    QObject *childObj = obj->findChild<QObject *>("button");
    connect(childObj, SIGNAL(qmlMsg(QString)), this, SLOT(printData(QString)));
}

void MainWindow::printData(QString message)
{
    qDebug()<<message;
}

但是没有插槽正在接收呼叫。如果我将父信号连接到c++插槽,则工作正常。

问题不在于孩子的信号/槽,它的MouseArea的大小为零。在ButtonItem.qml中为根条目添加宽度高度

Item {   
    id: button
    width: 40  // add this
    height: 40 // add this
    ...    
}

或者直接添加到按钮。也qml

ButtonItem {
    signal qmlMsg(string msg)
    objectName : "button"
    id : button3
    cellColor : "blue"
    label : "3"
    width: 40  // add this
    height: 40 // add this
    ...    
}

要使用QObject::findChild()查找QML子项目,它应该有一个名称。所以应该是这样的:

Item {
    id: button
    objectName: "button"
    ...
}

现在你可以访问它:

QObject *obj = qmlView->rootObject();
QObject *childObj = obj->findChild<QObject *>("button");
if (childObj)
{
    connect(childObj, SIGNAL(qmlMsg(QString)), this, SLOT(printData(QString)));
}