【问题标题】:QML signals connectingQML 信号连接
【发布时间】:2014-10-11 11:26:05
【问题描述】:

我开始使用 QML 编写应用程序(使用 QtQuick 1.1 和 Qt 4.8.1),我有几个关于信号的问题。在我的项目中有以下文件:

main.qml:

Rectangle {
    signal sigExit()
    width: 800
    height: 600
    Text {
        text: qsTr("Hello World")
        anchors.centerIn: parent
    }
    MouseArea {
        anchors.fill: parent
        onClicked: {
            sigExit();
            Qt.quit();
        }
    }
    Button
    {
        x: 10
        y: parent.height-height-5
        text: "someText"
    }
}

Button.qml:

Rectangle {
    signal buttonsig()
    width: 60
    //(...)
    MouseArea
    {
        anchors.fill: parent
        onClicked: buttonsig();
    }
}

当我想将信号从main.qml 连接到 C++ 插槽时,我会这样做:

main.cpp:

QmlApplicationViewer viewer;
viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
viewer.setMainQmlFile(QLatin1String("qml/MyProject/main.qml"));
viewer.showExpanded();

MyClass* obj = new MyClass;
QObject* item = qobject_cast<QObject*>(viewer.rootObject());
QObject::connect(item, SIGNAL(sigExit()), obj, SLOT(onExitWindow()));

它有效。但是当我想将sigbutton()Button.qml 连接到C++ 插槽时怎么办?会是这样吗?

QObject *rect = item->findChild<QObject*>("Button");
QObject::connect(rect, SIGNAL(buttonsig()), obj, SLOT(onExitWindow()));

第二个问题:如何将sigbutton() 连接到main.qml(例如,我想在单击按钮后更改按钮的位置)?

【问题讨论】:

    标签: c++ qt signals qml qt-quick


    【解决方案1】:

    如果您想访问它,您还需要拥有 Button 项目的 objectName 属性:

    Button {
        id: myButton
        objectName: "myButton"
        x: 10
        y: parent.height-height-5
        text: "someText"
    }
    

    现在您可以通过以下方式访问它:

    QObject *rect = item->findChild<QObject*>("myButton");
    

    关于第二个问题,您可以使用Connections 对象将buttonsig() 连接到main.qml 中的某个QML 信号处理程序:

    Rectangle {
        signal sigExit()
        width: 800
        height: 600
    
        Connections{
            target: myButton
            onButtonsig :
            {
                ...
            }
        }
    
        Text {
            text: qsTr("Hello World")
            anchors.centerIn: parent
        }
        MouseArea {
            anchors.fill: parent
            onClicked: {
                sigExit();
                Qt.quit();
            }
        }
        Button
        {
            id: myButton
    
            x: 10
            y: parent.height-height-5
            text: "someText"
        }
    }
    

    请注意,信号处理程序的名称应为on&lt;Signal&gt;(信号字母大写的第一个字母)。 Button 也应该有一个 ID 来在 Connections 中解决它。

    【讨论】:

    • 谢谢!第二个问题呢?是否有可能将来自一个 QML 文件的信号连接到另一个 QML 文件中的插槽(或类似的东西)?
    【解决方案2】:

    访问加载的 qml 元素,将它们转换并将它们的信号连接到您的 C++ 插槽是完全可能的。但是在您的生产代码中应该避免使用这种方法。 See this warning from Qt docs.

    那么从 qml 端调用 C++ 插槽的方法是什么?您可以将需要使用 qml 引擎调用其插槽的对象注册为上下文属性。注册后,可以从 QML 端的任何位置访问这些上下文属性。

    注册为上下文属性的对象槽可以直接在 QML 的信号处理程序中调用 example: onClicked:{&lt;contextPropertyName&gt;.&lt;slotName&gt;()}

    或者,您可以使用 Connections 类型直接将 QML 信号与上下文属性对象的插槽连接。请看this documentation

    有关注册上下文属性的详细信息,请参阅Embedding C++ objects into QML with context properties.

    如果您想查看一些示例,请查看我对这些问题的回答。 Qt Signals and Slots - nothing happensSetting object type property in QML from C++

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多