{"id":190,"date":"2012-03-19T19:41:34","date_gmt":"2012-03-19T17:41:34","guid":{"rendered":"http:\/\/blogs.igalia.com\/xrcalvar\/?p=190"},"modified":"2012-04-29T02:23:15","modified_gmt":"2012-04-29T00:23:15","slug":"mixed-qmlc-objects-reloaded","status":"publish","type":"post","link":"https:\/\/blogs.igalia.com\/xrcalvar\/2012\/03\/19\/mixed-qmlc-objects-reloaded\/","title":{"rendered":"Mixed QML\/C++ objects reloaded"},"content":{"rendered":"<p>Some days ago I was <a href=\"http:\/\/blogs.igalia.com\/xrcalvar\/2012\/02\/24\/mixed-qmlc-objects\/\">writing about how to have mixed QML\/C++ objects<\/a> in a QML application for <a href=\"http:\/\/www.igalia.com\">Igalia<\/a>, but I faced a problem with the code that I had written. And the problem was that I needed to receive some events and from the QML elements I was loading. Retaking that code:<\/p>\n<pre>\r\n#define QML_PATH \"\/path\/to\/the\/qml\/files\/\"\r\n\r\nMyObject::MyObject(QDeclarativeItem *parent = 0) :\r\n    QDeclarativeItem(parent)\r\n{\r\n    QDeclarativeEngine engine;\r\n    QDeclarativeComponent component(&amp;engine,\r\n        QUrl::fromLocalFile(QML_PATH \"MyObject.qml\"));\r\n    QDeclarativeItem *rect =\r\n        dynamic_cast(component.create());\r\n    rect-&gt;setParentItem(this);\r\n}\r\n<\/pre>\n<p><\/p>\n<p>and being MyObject.qml something like:<\/p>\n<pre>\r\nButton {\r\n    id: \"myButton\"\r\n    text: \"Do something cool\"\r\n}\r\n<\/pre>\n<p><\/p>\n<p>The natural way of connecting that button to some slot you are writing would be something like:<\/p>\n<pre>\r\nMyObject::MyObject(QDeclarativeItem *parent = 0) :\r\n    QDeclarativeItem(parent)\r\n{\r\n    QDeclarativeEngine engine;\r\n    QDeclarativeComponent component(&amp;engine,\r\n        QUrl::fromLocalFile(QML_PATH \"MyObject.qml\"));\r\n    QDeclarativeItem *item =\r\n        dynamic_cast(component.create());\r\n    item-&gt;setParentItem(this);\r\n    connect(item, SIGNAL(clicked()), this, SLOT(doCoolStuff()));\r\n}\r\n<\/pre>\n<p><\/p>\n<p>Even if you do this, you are not getting any event in the QML button you declare. It behaves as it were a label or whatever, but the key is the engine. <strong>The engine must live while you need the events of the QML component<\/strong>. And the easiest way of getting that done is adding the engine as a private class attribute:<\/p>\n<pre>\r\n#ifndef MYOBJECT_H\r\n#define MYOBJECT_H\r\n\r\n#include \r\n#include \r\n#include \r\n\r\nclass PostCapture : public QDeclarativeItem\r\n{\r\n    Q_OBJECT\r\n\r\n\/\/ ...\r\n\r\n private slots:\r\n    void doCoolStuff();\r\n\r\n private:\r\n    QDeclarativeEngine m_engine;\r\n};\r\n#endif\r\n<\/pre>\n<p><\/p>\n<p>and of course removing the <em>engine<\/em> stack declaration from the constructor:<\/p>\n<pre>\r\nMyObject::MyObject(QDeclarativeItem *parent = 0) :\r\n    QDeclarativeItem(parent)\r\n{\r\n    QDeclarativeComponent component(&amp;m_engine,\r\n        QUrl::fromLocalFile(QML_PATH \"MyObject.qml\"));\r\n    QDeclarativeItem *item =\r\n        dynamic_cast(component.create());\r\n    item-&gt;setParentItem(this);\r\n    connect(item, SIGNAL(clicked()), this, SLOT(doCoolStuff()));\r\n}\r\n<\/pre>\n<p><\/p>\n<p>Voil\u00e0.<\/p>\n<p>Of course, if you need to connect to any element that is not the root element, you can always forward the signals and properties from the QML root object or just use the <a href=\"http:\/\/qt-project.org\/doc\/qt-4.7\/qobject.html#memberSection\">QObject::findChild<\/a> method to access the right component.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Some days ago I was writing about how to have mixed QML\/C++ objects in a QML application for Igalia, but I faced a problem with the code that I had written. And the problem was that I needed to receive &hellip; <a href=\"https:\/\/blogs.igalia.com\/xrcalvar\/2012\/03\/19\/mixed-qmlc-objects-reloaded\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":31,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,9],"tags":[16,17,18,23,25,26,27,32,31],"class_list":["post-190","post","type-post","status-publish","format-standard","hentry","category-igaliacom","category-planet-igalia","tag-harmattan","tag-igalia","tag-maemo","tag-meego","tag-n9","tag-n950","tag-nokia","tag-qml","tag-qt"],"_links":{"self":[{"href":"https:\/\/blogs.igalia.com\/xrcalvar\/wp-json\/wp\/v2\/posts\/190","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.igalia.com\/xrcalvar\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.igalia.com\/xrcalvar\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.igalia.com\/xrcalvar\/wp-json\/wp\/v2\/users\/31"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.igalia.com\/xrcalvar\/wp-json\/wp\/v2\/comments?post=190"}],"version-history":[{"count":1,"href":"https:\/\/blogs.igalia.com\/xrcalvar\/wp-json\/wp\/v2\/posts\/190\/revisions"}],"predecessor-version":[{"id":282,"href":"https:\/\/blogs.igalia.com\/xrcalvar\/wp-json\/wp\/v2\/posts\/190\/revisions\/282"}],"wp:attachment":[{"href":"https:\/\/blogs.igalia.com\/xrcalvar\/wp-json\/wp\/v2\/media?parent=190"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.igalia.com\/xrcalvar\/wp-json\/wp\/v2\/categories?post=190"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.igalia.com\/xrcalvar\/wp-json\/wp\/v2\/tags?post=190"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}