当前位置: 动力学知识库 > 问答 > 编程问答 >

c++ - QML signals connecting

问题描述:

I started writing application in QML (using QtQuick 1.1 with Qt 4.8.1) and I have a few questions about signals. In my project there are following files:

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();

}

}

When I want to connect signal from main.qml to C++ slot, I do:

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()));

and it works. But what when I want to connect sigbutton() from Button.qml to C++ slot? It will be something like that?

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

QObject::connect(rect, SIGNAL(buttonsig()), obj, SLOT(onExitWindow()));

And the second issue: how can I connect sigbutton() to main.qml (for example, I want to change position of my buttons after clicking them)?

网友答案:

You will also need to have the objectName property of your Button item if you want to access it :

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

Now you can access it by :

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

Regarding the second question, you can use Connections object to connect buttonsig() to some QML signal handler in main.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"
    }
}

Note that the signal handler's name should be on<Signal> (First letter of signal letter Capital). Also Button should have an id to address it in Connections.

网友答案:

Accessing loaded qml elements, casting them and connecting their signals to your C++ slots is perferctly possible. But this method should be avoided in your production code. See this warning from Qt docs.

So what's the way to call a C++ slot from qml side? You can register the object whose slot needs to be called with qml engine as a context property. Once registered, these context properties can be accessed anywhere from QML side.

Slots of objects registered as context properties can be called directly in your signal handler in QML example: onClicked:{<contextPropertyName>.<slotName>()}

Or, you can connect a QML signal with context property object's slot directly using Connections type. Please see this documentation

For details about registering context properties, please see Embedding C++ objects into QML with context properties.

If you want to see some examples, see my answers to these questions. Qt Signals and Slots - nothing happens and Setting object type property in QML from C++

分享给朋友:
您可能感兴趣的文章:
随机阅读: