Signals with custom objects in QML
-
Hi everyone,
I'm playing with custom objects and signals in QML and I have a problem with making the signal parameter to be correctly visible by the script handling the signal. I'm extending the BirthdayParty/Persons example from here http://doc.qt.nokia.com/4.7-snapshot/declarative-cppextensions-referenceexamples-properties.html and I have all classes in my custom namespace (issue being solved using this topic: http://developer.qt.nokia.com/forums/viewthread/9509/ ) Anyway I added PersonEvent class, and somethingHappened(PersonEvent *event) signal to Person class. Later I register PersonEvent class using qmlRegisterTypeXX::PersonEvent(); The class declaration is something like this:
@
class PersonEvent;class Person : public SuperPerson
{
Q_OBJECT
Q_PROPERTY(int shoeSize READ shoeSize WRITE setShoeSize)
public:
virtual ~Person();
int shoeSize() const;
void setShoeSize(int);
void triggerEvent(PersonEvent *event);
protected:
Person();
Q_SIGNALS:
void somethingHappened(XX::PersonEvent *event);
private:
int m_shoeSize;
Q_DISABLE_COPY(Person)
};class PersonEvent: public QObject/, QEvent/ {
Q_OBJECT
Q_PROPERTY(bool lifeThreatening READ isLifeThreatening)
Q_PROPERTY(XX::Person* causingPerson READ causingPerson)
public:
PersonEvent(Person *causingPerson, bool isLifeThreatening);
virtual ~PersonEvent();
bool isLifeThreatening() const;
XX::Person * causingPerson() const;
private:
bool m_isLifeThreatening;
Person *m_causingPerson;
Q_DISABLE_COPY(PersonEvent)
};
@Now when I call triggerEvent(PersonEvent*) this function just simply emits the signal (emit somethignHappened(event))). In C++ I can easily connect to this signal and I get the correct event. In QML, however, I'm trying to process the event using this snippet:
@
import People 1.0BirthdayParty {
host: Girl {
name: "Jean Jones"
onSomethingHappened: {
console.log(" something happened !!! " +somethingHappened);
console.log(" is it life threating? " + somethingHappened.isLifeThreatening);
}
}
guests: [
Boy { name: "Leo Hodges" },
Boy { name: "Jack Smith" },
Girl { name: "Anne Brown" }
]
}
@The signal gets fired correctly, the problem I have is with accessing the properties of the PersonEvent object. When running the qml code above (and firing the signal by calling host->triggerEvent(PersonEvent*)) the output is like this:
something happened !!! [object Object]
is it life threating? undefinedSo the signal is emitted correctly, the qml handler is called correctly, but the actual signal parameter does not seem to be visible from QML. Is there anything I need to do specifically in the event object to make sure it is visible to the script?
-
-
Make sure that the name of the signal parameter and the parameters in the qml code are the same. When doing so it works for me in the example below. If the name differs, I get the same problem you are having. Does the example below work correctly for you?
@
#include <QtGui>
#include <QtDeclarative>namespace YY {
class PersonEvent: public QObject {
Q_OBJECT
Q_PROPERTY(bool lifeThreatening READ isLifeThreatening)
public:
PersonEvent()
{}
bool isLifeThreatening() const
{
return true;
}
};
}using namespace YY;
QML_DECLARE_TYPE(PersonEvent)
class Person : public QObject
{
Q_OBJECT
public:Q_INVOKABLE void triggerEvent(PersonEvent * event)
{
emit somethingHappened(event);
}
Person()
{
qDebug() << "timer triggers";
startTimer(1000);
}
void timerEvent(QTimerEvent *e)
{
PersonEvent *myEvent = new PersonEvent();
triggerEvent(myEvent);
}
signals:
void somethingHappened(PersonEvent *event);
};
QML_DECLARE_TYPE(Person)#include "main.moc"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
qmlRegisterType<Person>("People", 1, 0, "Person");
qmlRegisterType<PersonEvent>("People", 1, 0, "PersonEvent");
Person myObj;
PersonEvent personEvent;
QDeclarativeView view;
view.rootContext()->setContextProperty("rootItem", (Person *)&myObj);
view.rootContext()->setContextProperty("eventItem", (PersonEvent *)&personEvent);view.setSource(QUrl::fromLocalFile("main.qml"));
view.resize(200,100);
view.show();
return app.exec();
}@
@main.qml
import People 1.0
import QtQuick 1.0
Text {Person {
onSomethingHappened: {
console.log(" something happened !!! " +event);
console.log(" is it life threating? " + event.lifeThreatening);
}
}
}
@ -
Thanks!!! This was it. The problem I was seeing I guess was I used the same name of the javascript variable as the signal, but it contained the signal itself as some sort of object (and thus not failing), but it was not the actual event parameter. When I changed it to "event", everything works. Thanks again!