Connecting QML to a C++ signal - connection doesn't work on the first time
I'm playing around with connections between C++ and QML.
I've found a case in which it seems like a signal connection doesn't work at first, then works on calls from other locations in the code.
A bit of code to clarify:
Code:
// Header
#include <QObject>
#include <QDateTime>
class MyQmlInterface
: public QObject{
Q_OBJECT
public:
Q_PROPERTY(QString singleValue READ singleValue WRITE setSingleValue NOTIFY singleValueChanged
)
const QString &singleValue
() const;
void setSingleValue
(const QString &newSingleValue
);
void emitCppSignal
(const QString &passedStr
);
Q_INVOKABLE
QDateTime getCurrentDateTime
() const { }
signals:
void singleValueChanged();
// THIS is the signal I want to connect to
void signalFromCpp
(const QString &passedStr
);
public slots:
void somethingHappened();
private:
};
// Cpp
const QString &MyQmlInterface
::singleValue() const {
return mSingleValue;
}
void MyQmlInterface
::setSingleValue(const QString &newSingleValue
) {
if (newSingleValue == mSingleValue)
return;
mSingleValue = newSingleValue;
emit singleValueChanged();
}
void MyQmlInterface::somethingHappened()
{
setSingleValue("O RLY");
}
// Method to emit the signal
void MyQmlInterface
::emitCppSignal(const QString &passedStr
) {
emit signalFromCpp(passedStr);
}
// QML
import QtQuick 1.0
Rectangle {
width: 360
height: 360
Text {
id: myText
anchors.centerIn: parent
text: myInterface.singleValue
}
Connections {
target: myInterface
onSignalFromCpp: {
myText.text += passedStr
myText.rotation += 90
}
}
}
Now here is where I initialize my Qml display and expect to see the result of my signal being emitted:
Code:
// The types are what you expect :)
mView = new QDeclarativeView(this);
mEngine = mView->engine();
mContext = mEngine->rootContext();
mQmlInterface = new MyQmlInterface;
QString filePath
= "D:\\QmlTest\\QmlTest.qml";
mView->setSource(filePath);
mContext->setContextProperty("myInterface", mQmlInterface);
mQmlInterface->setSingleValue("Set after context...");
ui.verticalLayout->addWidget(mView);
mView->show();
//! If needed - this is how to clean up in case Qml wants to quit
//connect(mEngine, SIGNAL(quit()), this, SLOT(declarativeEngineQuit()));
// This first signal call doesn't work
mQmlInterface->emitCppSignal("this getting to you?");
The above code runs when I click on a button to "start" the qml test. In a different place in my code (index change of a table widget) I call the same method.
Code:
mQmlInterface->emitCppSignal("this getting to you?");
Current behavior is that only the index change calls are getting through the QML. For my implementation I can live with that but why is it happening? Is this a bug?
Re: Connecting QML to a C++ signal - connection doesn't work on the first time
You have to register your class to qdeclarative engine to be able to connect to C++ object signals which are not notify signals of object properties. Registration can be done using qmlRegisterType template function:
Code:
template<typename T>
int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
For you code it would be for example:
Code:
qmlRegisterType<MyQmlInterface>("MyQmlInterfaceNamespace", 1, 0, "MyQmlInterface");
More info:
http://doc.qt.nokia.com/4.7/qdeclara...mlRegisterType
http://doc.qt.nokia.com/4.7/qml-extending.html
Re: Connecting QML to a C++ signal - connection doesn't work on the first time
Thanks for your reply.
The code given here should still work. And as matter of fact, it does, for any later call to emitCppSignal. That's why I wrote, it doesn't work only for the first call.
I changed some things in my actual project so I don't have this first call in my working code, but if I manage to find time to repeat it I'll try to post a better explanation of the issue.