Casting signaled QObjects from C++ code
-
I have noticed that QML behaves differently when these objects are passed to the script as a signal. I have added to the previous code example that reproduces this.
The update adds a singleShot QTimer that passed the object1 twice to the script. Once declared class and the second as a QObject.
When passed as a class it is casted as a QVariant and I will not have access to any properties or slots.
When passed as a QObject I will have access to properties but is also casted differently then when it is passed using the doSomething() function. (Clicking anywhere in the window)
I could not find anyway to cast it from a QVariant in the script so I could access it properly. Also a little confused why it is casting the same object type differently.
-
main.cpp
@
#include <QApplication>#include <qdeclarative.h>
#include <QDeclarativeView>
#include <qdeclarativecontext.h>#include "object1.h"
#include "object2.h"int main(int argc, char *argv[])
{
QApplication app(argc, argv);QDeclarativeView view;
view.setResizeMode(QDeclarativeView::SizeRootObjectToView);qmlRegisterType<Object1>("com.test.object1", 1, 0, "Object1");
qmlRegisterType<Object2>("com.test.object2", 1, 0, "Object2");Object1 *object1 = new Object1();
view.rootContext()->setContextProperty("myObject1",object1);
view.setSource(QUrl::fromLocalFile("main.qml"));
view.show();return app.exec();
}
@main.js
@
function doConnect()
{
myObject1.mySignalSpecific.connect(displayObject)
myObject1.mySignalQObject.connect(displayObject)
}function doSomething()
{
var failedObject = myObject1.getObject2();
print(failedObject);
}function displayObject(obj1)
{
print(obj1);
print(obj1.name);
}
@main.qml
@
import Qt 4.7import "main.js" as MainJS
Rectangle {
id: mainWindowwidth: 640; height: 480
color: "lightgray"MouseArea
{
id: mouseArea
anchors.fill: parent
onClicked:
{
MainJS.doSomething();
}
}Component { Item {} }
Component.onCompleted: MainJS.doConnect();
}
@object1.h
@
#ifndef OBJECT1_H
#define OBJECT1_H#include <QObject>
#include "object2.h"
class Object1 : public QObject
{
Q_OBJECTQ_PROPERTY (QString name READ getName)
public:
Object1(QObject *parent = 0);public slots:
Object2 *getObject2();
void passObject2Script();signals:
void mySignalSpecific(Object1 *obj);
void mySignalQObject(QObject *obj);private:
QString m_name;QString getName();
};
#endif
@object1.cpp
@
#include "object1.h"#include "QTimer"
Object1::Object1(QObject *parent) : QObject(parent)
{
QTimer::singleShot(1000,this,SLOT(passObject2Script()));
m_name = "object1 name property";
}Object2* Object1::getObject2()
{
return new Object2();
}void Object1::passObject2Script()
{
emit mySignalSpecific(this);
emit mySignalQObject(this);
}QString Object1::getName()
{
return m_name;
}
@object2.h
@
#ifndef OBJECT2_H
#define OBJECT2_H#include <QObject>
#include <qdeclarative.h>class Object2 : public QObject
{
Q_OBJECTQ_PROPERTY (QString name READ getName)
public:
Object2(QObject *parent = 0);private:
QString m_name;QString getName();
};
#endif
@object2.cpp
@
#include "object2.h"Object2::Object2(QObject *parent) : QObject(parent)
{
m_name = "object2 name property";
}QString Object2::getName()
{
return m_name;
}
@Console will show the output, click anywhere on the screen for the object passed directly to the view.
-
What version of Qt are you using? This sounds very similar to "QTBUG-13047":http://bugreports.qt.nokia.com/browse/QTBUG-13047, which should be fixed in 4.7.1.
Regards,
Michael -
Some days ago, I tried to write some codes like you. It does not work very well. I find that it's wrong in this way.
if you call :
qmlRegisterType<Object1>("com.test.object1", 1, 0, "Object1");
then you can use Object1 in qml file as Rectangle , Image, Text and so on, Object1 is only a type before you use it in qml. such as Object1{id:object_1}
The following code, you write:
Object1 *object1 = new Object1();
view.rootContext()->setContextProperty("myObject1",object1);
works good, but if you call the method of object1, the method must be Q_INVOKABLE