[SOLVED] Casting QGraphicsObject to QObject for connecting QML signals to C++ slots (Harmattan specific issues?)
-
Hi,
Trying to learn Harmattan development (being a Qt newbie isn't helping) and one of the fundamental things is connecting QML signals to C++ slots (my end goal is to run some XML-import code where the QML signal states which XML file, then the C++ processes the file and then signals the QML back with the extracted data).
So my start page looks like this:
@
import QtQuick 1.1
import com.nokia.meego 1.0Page {
Button {
...
signal importerSignal(string msg);
...
onClicked: {
importerSignal("XMLName");
pageStack.push(Qt.resolvedUrl("NextPage.qml"));
}
}
}
@and that should have the signal taken care of. The slot is defined in the main C++ fille:
@
#include <QtGui/QApplication>
#include <QDebug>
#include "qmlapplicationviewer.h"class MyClass : public QObject{
Q_OBJECTpublic slots:
void LoadXML(const QString &msg){--
qDebug() << "Requesting XML for " << msg;
}
};Q_DECL_EXPORT int main(int argc, char *argv[])
{
QScopedPointer<QApplication> app(createApplication(argc, argv));QmlApplicationViewer viewer; viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto); viewer.setMainQmlFile(QLatin1String("qml/myproject/main.qml")); QObject *rootObject = viewer.rootObject(); MyClass xmlreader; QObject::connect(rootObject, SIGNAL(importerSignal(QString)), &xmlreader, SLOT(LoadXML(QString))); viewer.showExpanded(); return app->exec();
}
@But, I'm getting an error saying that viewer.rootObject() (which was generated by QtCreator) is a QGraphicsObject, not a QObject. Other threads (for non-Harmattan projects) say, OK then just cast viewer.rootObject() as a QObject, but doing so:
@QObject *rootObject = (QObject)viewer.rootObject();@
just gives me errors saying, in essence, that it can't be cast as such (error: no matching function for call to 'QObject::QObject(QGraphicsObject*)'). Is there something I missed, or am I supposed to connect signals to slots differently for N9/N950 development, or...?
My understanding is that I don't need to #include <QDeclarativeView> because qmlapplicationviewer.h already includes it. Also, if it helps for some reason, the build target is for a remote physical N9.
-
qobject_cast is preferred way to cast between qobjects.
-
qobject_cast is not necessary to assign to a QObject pointer, as everything that qobject_cast return is a QObject.
The include
@
#include <QGraphicsObject>
@is missing. The compiler does plainly not know that [[Doc:QGraphicsObject]] inherits from QObject.
-
Thanks Volker, that solved it (not sure why the compiler doesn't know about QGraphicsObject; if QmlApplicationViewer has a function with return type QGraphicsObject then wouldn't the compiler know about QGraphicsObject from QmlApplicationViewer? But I digress...).
Different question comes up now: undefined reference to vtable for the MyClass. A little Googling says this is a common error that indicates that MyClass's moc-generated code isn't linking into the executable, but I don't see where I'm supposed to define that stuff in QtCreator. Furthermore, I'm not certain why it wouldn't be linked correctly; after all, the class is a part of the main.cpp file (bad programming practice, I know, but baby steps first...), which presumably WAS linked properly into the executable, since the initial code builds ran fine.
-
About the QGraphicsObject/QObject pointer:
The method returns a pointer to an object of a certain type. That's all the compiler knows about that method. To decide whether the returned type is compatible with the pointer variable it is assigned to, the compiler needs the class declaration of that object. In most cases, that declaration (read: include file) has already been included by the main class' header. This is one of the exceptions, where it is not needed - so you need to include it maually.For the second problem:
You should put MyClass into a separate header file and add it to the HEADERS variable in the .pro file. Then re-run qmake and build your project. If the error remains, do a complete rebuild of the project. Don't forget to #include it in your main.cpp, of course :-) -
Thanks, all problems solved :)