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:
// 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
}
}
}
// 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 {
return QDateTime::currentDateTime();
}
signals:
void singleValueChanged();
// THIS is the signal I want to connect to
void signalFromCpp(const QString &passedStr);
public slots:
void somethingHappened();
private:
QString mSingleValue;
};
// 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
}
}
}
To copy to clipboard, switch view to plain text mode
Now here is where I initialize my Qml display and expect to see the result of my signal being emitted:
// 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 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?");
To copy to clipboard, switch view to plain text mode
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.
mQmlInterface->emitCppSignal("this getting to you?");
mQmlInterface->emitCppSignal("this getting to you?");
To copy to clipboard, switch view to plain text mode
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?
Bookmarks