<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Registering an Instantiable Object Type (Official Example)]]></title><description><![CDATA[<p dir="auto">I'm following the official example from <a href="https://doc.qt.io/qt-6/qtqml-cppintegration-definetypes.html#registering-an-instantiable-object-type" target="_blank" rel="noopener noreferrer nofollow ugc">here</a>, but either I'm getting something wrong, or there is something missing in the guide.</p>
<p dir="auto">I'm trying to register a C++ type into QML, to be able to instantiate it in a QML document. I'm following the guide as well as the worked example, but I'm always getting the</p>
<p dir="auto"><strong>QQmlApplicationEngine failed to load component<br />
qrc:/exampleDir/Main.qml:3:1: module "myclass" is not installed</strong></p>
<p dir="auto">error.</p>
<p dir="auto">I've created a new, empty Qt Quick project, and added a minimalist C++ class, almost identical to the example, just replacing the identifier <code>Message</code> with <code>MyClass</code>:</p>
<pre><code>#ifndef MYCLASS_H
#define MYCLASS_H

#include &lt;QObject&gt;
#include &lt;qqmlregistration.h&gt;

class MyClass : public QObject
{
	Q_OBJECT
	Q_PROPERTY(QString author READ getAuthor WRITE setAuthor NOTIFY authorChanged)
	QML_ELEMENT

public:
	explicit MyClass(QObject *parent = nullptr);

public slots:
  QString getAuthor(void);
  void    setAuthor(const QString&amp;);

signals:
  void authorChanged(void);

private:
  QString m_author = "Author's Name";
};

#endif // MYCLASS_H
</code></pre>
<p dir="auto">Then, by following the guide, I added this snippet of code in <code>CMakeLists.txt</code>, just after the already existing <code>qt_add_qml_module</code> invokation for the main project:</p>
<pre><code>qt_add_qml_module(myClass
    URI myclass
    VERSION 1.0
    SOURCES
    myclass.cpp myclass.h
)
</code></pre>
<p dir="auto">This is <code>Main.qml</code>:</p>
<pre><code>import QtQuick
import QtQuick.Window
import myclass

Window
{
	width: 640
	height: 480
	visible: true
	title: qsTr("Hello World")

	MyClass
	{}
}
</code></pre>
<p dir="auto">When I try to compile, I'm always getting the <strong>module "myClass" is not installed</strong> error.</p>
<p dir="auto"><strong>NOTE</strong>: if I add these lines to <code>main.cpp</code>:</p>
<pre><code>  const char *packageName = "myclass";
  const char *QMLTypeName = "MyClass";
  const int   majorVerNum = 1;
  const int   minorVerNum = 0;
  qmlRegisterType&lt;MyClass&gt;(packageName, majorVerNum, minorVerNum, QMLTypeName);
</code></pre>
<p dir="auto">The project compiles and works correctly. However, the usage of <code>qmlRegisterType</code> isn't mentioned anywhere in the <a href="https://doc.qt.io/qt-6/qtqml-cppintegration-definetypes.html#registering-an-instantiable-object-type" target="_blank" rel="noopener noreferrer nofollow ugc">documentation</a>, which makes me think that it should <em>not</em> be necessary to add the call to <code>qmlRegisterType</code> in <code>main.cpp</code>, because the call to <code>qt_add_qml_module</code> in <code>CMakeLists.txt</code> should take care of everything, together with the <code>QML_ELEMENT</code> macro in the class header file. In fact, after having added the the call to <code>qmlRegisterType</code> in <code>main.cpp</code>, the <code>qt_add_qml_module</code> snippet can be safely removed from <code>CMakeLists.txt</code>.</p>
<p dir="auto">What am I missing here?</p>
<ul>
<li>Qt version: 6.5.1</li>
<li>Qt Creator version: 10.0.2</li>
<li>OS: Windows 10</li>
<li>Filesystem:<br />
<img src="https://ddgobkiprc33d.cloudfront.net/db2bb3a5-211d-4b63-90d6-68f20a5c0e0c.png" alt="6fcf88f9-aea0-407b-83cd-d5d4c55216c0-image.png" class=" img-fluid img-markdown" /></li>
</ul>
]]></description><link>https://forum.qt.io/topic/145977/registering-an-instantiable-object-type-official-example</link><generator>RSS for Node</generator><lastBuildDate>Wed, 15 Apr 2026 11:17:53 GMT</lastBuildDate><atom:link href="https://forum.qt.io/topic/145977.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 24 Jun 2023 15:52:39 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Registering an Instantiable Object Type (Official Example) on Wed, 17 Jul 2024 17:00:44 GMT]]></title><description><![CDATA[<p dir="auto"><img src="https://ddgobkiprc33d.cloudfront.net/70c67ef6-d086-421f-9a72-360548e81058.png" alt="image.png" class=" img-fluid img-markdown" /></p>
<p dir="auto"><img src="https://ddgobkiprc33d.cloudfront.net/8859d229-d717-4f7d-a6ec-075f8a8ca212.png" alt="image.png" class=" img-fluid img-markdown" /></p>
<p dir="auto">I found this mismatch. Maybe you should try to capitalize the first character exactly the URI in your CMakeLists</p>
]]></description><link>https://forum.qt.io/post/805006</link><guid isPermaLink="true">https://forum.qt.io/post/805006</guid><dc:creator><![CDATA[TonyNguyen147]]></dc:creator><pubDate>Wed, 17 Jul 2024 17:00:44 GMT</pubDate></item><item><title><![CDATA[Reply to Registering an Instantiable Object Type (Official Example) on Mon, 12 Feb 2024 20:50:03 GMT]]></title><description><![CDATA[<p dir="auto">I know this is an old topic but thank you very much, Gamma Sigma, for summarizing this.  I want to use the current practices for adding modules without registration but nothing worked despite following Qt's blogs and documentation.  I got a test case to work.  Now<br />
I need to figure out how to get C++ Classes that are in subdirectories working.</p>
]]></description><link>https://forum.qt.io/post/789656</link><guid isPermaLink="true">https://forum.qt.io/post/789656</guid><dc:creator><![CDATA[RangerQT]]></dc:creator><pubDate>Mon, 12 Feb 2024 20:50:03 GMT</pubDate></item><item><title><![CDATA[Reply to Registering an Instantiable Object Type (Official Example) on Sun, 25 Jun 2023 19:57:28 GMT]]></title><description><![CDATA[<p dir="auto">I think I have found a workaround to the problem. Unfortunately, I cannot explain much of what I've done, because I am quite confused myself about how Qt manages resources through the Resource System, and the recent <a href="https://doc.qt.io/qt-6/qt-cmake-policy-qtp0001.html" target="_blank" rel="noopener noreferrer nofollow ugc">policy modification</a> makes things even worse.</p>
<p dir="auto">Start by creating a new Qt Quick project with Qt Creator's wizard, selecting CMake as the build system; I called mine <code>testIntegration</code>. Qt Creator's wizard will auto-generate <code>CMakeLists.txt</code>, <code>main.cpp</code>, and <code>Main.qml</code> for you.</p>
<p dir="auto">The first problem that needs tackling is the <a href="https://doc.qt.io/qt-6/qt-cmake-policy-qtp0001.html" target="_blank" rel="noopener noreferrer nofollow ugc">Qt policy QTP0001 is not set</a> warning message. To fix this, either add the <code>qt_policy(SET QTP0001 NEW)</code> command in <code>CMakeLists.txt</code> (before <code>qt_add_executable</code>), or add a <code>RESOURCE_PREFIX</code> argument to the <code>qt_add_qml_module</code> command in <code>CMakeLists.txt</code>. I did both, just to be safe (I used <code>RESOURCE_PREFIX /</code>).</p>
<p dir="auto">Then add a new C++ class, selecting <code>QObject</code> as base class (use Qt Creator's wizard to save yourself some effort). Call it whatever you like: I called mine <code>MyClass</code>.</p>
<p dir="auto">Now <code>CMakeLists.txt</code> needs to be edited again. Find the <code>qt_add_qml_module</code> command, and add the source files for your class, by passing the <code>SOURCES myclass.h myclass.cpp</code> argument.</p>
<p dir="auto">Edit your <code>myclass.h</code> header file, and add <code>#include &lt;qqmlregistration.h&gt;</code>. This inclusion will allow you to use the <code>QML_ELEMENT</code> macro. I put <code>QML_ELEMENT</code> immediately after the <code>Q_OBJECT</code> macro.</p>
<p dir="auto">I also added a <code>qDebug</code> statement in the constructor of <code>MyClass</code> (<code>qDebug() &lt;&lt; "Class instantiated";</code>), to ascertain that the class has actually been instantiated. You will need to <code>#include &lt;QDebug&gt;</code> to use <code>qDebug()</code>.</p>
<p dir="auto">Now edit <code>Main.qml</code> and add this import statement: <code>import testIntegration</code>. You will notice that it is the same identifier as the <code>URI testIntegration</code> argument used in the <code>qt_add_qml_module</code> command in <code>CMakeLists.txt</code>. You can now declare a <code>MyClass</code> object in your QML code. In my case, I simply created an empty <code>MyClass{}</code> inside the main <code>Window</code>.</p>
<p dir="auto">This way I managed to compile and run the project without issues, getting a nice "Class instantiated" debug message in Application Output.</p>
<p dir="auto"><strong>NOTE</strong>: As you can see, no <code>qmlRegisterType</code> was used in <code>main.cpp</code>. However, it looks like Qt / QML / CMake / whatever is (are?) extremely finicky for what concerns the identifiers you use. You can choose whatever URI you like in <code>qt_add_qml_module</code>, but you have to make sure that it is the same both in the QML document and in <code>main.cpp</code>. For example, if in <code>CMakeLists.txt</code> you use the <code>URI MyBeautifulURI</code> argument for <code>qt_add_qml_module</code>, then you'll have to update <code>Main.qml</code> and <code>main.cpp</code> accordingly:</p>
<ul>
<li><code>import MyBeautifulURI</code> in <code>Main.qml</code></li>
<li><code>const QUrl url(u"qrc:/MyBeautifulURI/Main.qml"_qs);</code> in <code>main.cpp</code></li>
</ul>
<p dir="auto">If you are interested, here are the full source files:</p>
<p dir="auto">***** <code>CMakeLists.txt</code> *****</p>
<pre><code>cmake_minimum_required(VERSION 3.16)

project(testIntegration VERSION 0.1 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(Qt6 6.4 REQUIRED COMPONENTS Quick)

qt_policy(SET QTP0001 NEW) # Suppress warning https://doc.qt.io/qt-6/qt-cmake-policy-qtp0001.html

qt_standard_project_setup()

qt_add_executable(apptestIntegration
    main.cpp
)

qt_add_qml_module(apptestIntegration
    URI testIntegration
    RESOURCE_PREFIX /
    VERSION 1.0
    QML_FILES Main.qml
    SOURCES myclass.h myclass.cpp
)

set_target_properties(apptestIntegration PROPERTIES
    MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com
    MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
    MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
    MACOSX_BUNDLE TRUE
    WIN32_EXECUTABLE TRUE
)

target_link_libraries(apptestIntegration
    PRIVATE Qt6::Quick
)

install(TARGETS apptestIntegration
    BUNDLE DESTINATION .
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
</code></pre>
<p dir="auto">***** <code>main.cpp</code> *****</p>
<pre><code>#include &lt;QGuiApplication&gt;
#include &lt;QQmlApplicationEngine&gt;

int main(int argc, char *argv[])
{
  QGuiApplication app(argc, argv);

  QQmlApplicationEngine engine;
  const QUrl url(u"qrc:/testIntegration/Main.qml"_qs);
  QObject::connect(&amp;engine, &amp;QQmlApplicationEngine::objectCreationFailed,
    &amp;app, []() { QCoreApplication::exit(-1); },
    Qt::QueuedConnection);
  engine.load(url);

  return app.exec();
}
</code></pre>
<p dir="auto">***** <code>Main.qml</code> *****</p>
<pre><code>import QtQuick
import QtQuick.Window
import testIntegration

Window
{
  width: 640
  height: 480
  visible: true
  title: qsTr("Hello World")

  MyClass{}
}
</code></pre>
<p dir="auto">***** <code>myclass.h</code> *****</p>
<pre><code>#ifndef MYCLASS_H
#define MYCLASS_H

#include &lt;QObject&gt;
#include &lt;qqmlregistration.h&gt;

class MyClass : public QObject
{
  Q_OBJECT
  QML_ELEMENT

public:
  explicit MyClass(QObject *parent = nullptr);

signals:
};

#endif // MYCLASS_H
</code></pre>
<p dir="auto">***** <code>myclass.cpp</code> *****</p>
<pre><code>#include &lt;QDebug&gt;
#include "myclass.h"

MyClass::MyClass(QObject *parent)
  : QObject{parent}
{
  qDebug() &lt;&lt; "Class instantiated";
}
</code></pre>
]]></description><link>https://forum.qt.io/post/762574</link><guid isPermaLink="true">https://forum.qt.io/post/762574</guid><dc:creator><![CDATA[Gamma_Sigma]]></dc:creator><pubDate>Sun, 25 Jun 2023 19:57:28 GMT</pubDate></item><item><title><![CDATA[Reply to Registering an Instantiable Object Type (Official Example) on Sat, 24 Jun 2023 20:06:13 GMT]]></title><description><![CDATA[<p dir="auto">I gave another unsuccessful try. This time I tried to be even more minimalist than before, to no avail.</p>
<p dir="auto">This is what I did:</p>
<ul>
<li>Create a new "Qt Quick Application" project named <code>testIntegration</code></li>
<li>Select CMake as build system</li>
<li>Select "Desktop Qt 6.5.1 MinGW 64-bit" as kit</li>
<li>Add new C++ class named <code>Message</code> (source files <code>message.cpp</code> and <code>message.h</code>), derived from <code>QObject</code> and adding the <code>Q_OBJECT</code> macro</li>
<li>Adding source files <code>message.h</code> and <code>message.cpp</code> to <code>qt_add_executable</code> in <code>CMakeLists.txt</code></li>
<li>Add <code>#include &lt;QtQml/qqmlregistration.h&gt;</code> to <code>message.h</code> to be able to use the <code>QML_ELEMENT</code> macro in class <code>Message</code></li>
<li>Add <code>qt_add_qml_module</code> statement to <code>CMakeLists.txt</code></li>
<li>Add <code>import</code> statement and instantiate <code>Message</code> class in <code>Main.qml</code> inside <code>Window</code></li>
</ul>
<p dir="auto">Now, two error messages are possible, depending on the case of the URI (lowercase <code>messagingUri</code> or uppercase <code>MessagingUri</code>):</p>
<ol>
<li>If i add <code>URI messagingUri</code> in <code>qt_add_qml_module</code> (in <code>CMakeLists.txt</code>) and <code>import messagingUri</code> (in <code>Main.qml</code>), i get this error message: "QQmlApplicationEngine failed to load component qrc:/testIntegration/Main.qml:3:1: module "messagingUri" is not installed"</li>
<li>If i add <code>URI MessagingUri</code> in <code>qt_add_qml_module</code> (in <code>CMakeLists.txt</code>) and <code>import MessagingUri</code> (in <code>Main.qml</code>), i get this error message: ":-1: error: ninja: build stopped: subcommand failed."</li>
</ol>
<p dir="auto">In both cases, i get the warning message "D:\Qt\6.5.1\mingw_64\lib\cmake\Qt6Qml\Qt6QmlMacros.cmake:794: warning: The messagingModule target is a QML module with target path MessagingUri. It uses an OUTPUT_DIRECTORY of D:/Qt_6/build-testIntegration-Desktop_Qt_6_5_1_MinGW_64_bit-Debug, which should end in the same target path, but doesn't. Tooling such as qmllint may not work correctly. D:/Qt/6.5.1/mingw_64/lib/cmake/Qt6Qml/Qt6QmlMacros.cmake:1840 (_qt_internal_target_enable_qmllint) D:/Qt/6.5.1/mingw_64/lib/cmake/Qt6Qml/Qt6QmlMacros.cmake:625 (qt6_target_qml_sources) D:/Qt/6.5.1/mingw_64/lib/cmake/Qt6Qml/Qt6QmlMacros.cmake:684 (qt6_add_qml_module) CMakeLists.txt:24 (qt_add_qml_module)"</p>
<p dir="auto">Again, if i add these lines to <code>main.cpp</code> (as well as <code>#include "message.h"</code>):</p>
<pre><code>const char *packageName = "messagingUri";
const char *QMLTypeName = "Message";
const int   majorVerNum = 1;
const int   minorVerNum = 0;
qmlRegisterType&lt;Message&gt;(packageName, majorVerNum, minorVerNum, QMLTypeName);
</code></pre>
<p dir="auto">Everything works perfectly: no error messages, no warnings, no nothing.</p>
<p dir="auto">At this point, I'm really stumped. The example from Qt documentation <em>never</em> mentions the usage of <code>qmlRegisterType</code>, but it looks like it is inevitable.</p>
<p dir="auto">Here are the full source files:</p>
<p dir="auto">***** <code>CMakeLists.txt</code> *****<br />
(mostly auto-generated. I only added the <code>qt_policy</code> command to suppress a warning, the source files for <code>Message</code> class to <code>qt_add_executable</code>, and the full <code>qt_add_qml_module</code> command, copied from the example, only changing the package's name and the URI)</p>
<pre><code>cmake_minimum_required(VERSION 3.16)

project(testIntegration VERSION 0.1 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(Qt6 6.4 REQUIRED COMPONENTS Quick)

qt_standard_project_setup()

qt_policy(SET QTP0001 OLD) # Suppress warning https://doc.qt.io/qt-6/qt-cmake-policy-qtp0001.html

qt_add_executable(apptestIntegration
    main.cpp
    message.h message.cpp
)

qt_add_qml_module(apptestIntegration
    URI testIntegration
    VERSION 1.0
    QML_FILES Main.qml
)

qt_add_qml_module(messagingModule
    URI MessagingUri
    VERSION 1.0
    SOURCES
    message.cpp message.h
)

set_target_properties(apptestIntegration PROPERTIES
    MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com
    MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
    MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
    MACOSX_BUNDLE TRUE
    WIN32_EXECUTABLE TRUE
)

target_link_libraries(apptestIntegration
    PRIVATE Qt6::Quick
)

install(TARGETS apptestIntegration
    BUNDLE DESTINATION .
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
</code></pre>
<p dir="auto">***** <code>main.cpp</code> *****<br />
(fully auto-generated. Nothing was added or modified by me here)</p>
<pre><code>#include &lt;QGuiApplication&gt;
#include &lt;QQmlApplicationEngine&gt;

int main(int argc, char *argv[])
{
  QGuiApplication app(argc, argv);

  QQmlApplicationEngine engine;
  const QUrl url(u"qrc:/testIntegration/Main.qml"_qs);
  QObject::connect(&amp;engine, &amp;QQmlApplicationEngine::objectCreationFailed,
    &amp;app, []() { QCoreApplication::exit(-1); },
    Qt::QueuedConnection);
  engine.load(url);

  return app.exec();
}
</code></pre>
<p dir="auto">***** <code>message.h</code> *****</p>
<pre><code>#ifndef MESSAGE_H
#define MESSAGE_H

#include &lt;QObject&gt;
#include &lt;QtQml/qqmlregistration.h&gt;

class Message : public QObject
{
    Q_OBJECT
    QML_ELEMENT

public:
    explicit Message(QObject *parent = nullptr);

signals:
};

#endif // MESSAGE_H
</code></pre>
<p dir="auto">***** <code>message.cpp</code> *****</p>
<pre><code>#include "message.h"

Message::Message(QObject *parent)
    : QObject{parent}
{;}
</code></pre>
<p dir="auto">***** <code>Main.qml</code> *****</p>
<pre><code>import QtQuick
import QtQuick.Window
import messagingUri

Window
{
  width: 640
  height: 480
  visible: true
  title: qsTr("Hello World")

  Message
  {}
}
</code></pre>
]]></description><link>https://forum.qt.io/post/762536</link><guid isPermaLink="true">https://forum.qt.io/post/762536</guid><dc:creator><![CDATA[Gamma_Sigma]]></dc:creator><pubDate>Sat, 24 Jun 2023 20:06:13 GMT</pubDate></item><item><title><![CDATA[Reply to Registering an Instantiable Object Type (Official Example) on Sat, 24 Jun 2023 16:44:27 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/sgaist">@<bdi>SGaist</bdi></a> Hello, thank you for your reply.</p>
<p dir="auto">Later I will start this example from scratch, and I will try to use unique identifiers instead of repeating variations of "MyClass", so that it will be easier to track them, and identify where the case usage might go wrong. If the problem does not disappear, I will post the whole source files, together with the <code>CMakeLists.txt</code> file.</p>
]]></description><link>https://forum.qt.io/post/762526</link><guid isPermaLink="true">https://forum.qt.io/post/762526</guid><dc:creator><![CDATA[Gamma_Sigma]]></dc:creator><pubDate>Sat, 24 Jun 2023 16:44:27 GMT</pubDate></item><item><title><![CDATA[Reply to Registering an Instantiable Object Type (Official Example) on Sat, 24 Jun 2023 16:26:06 GMT]]></title><description><![CDATA[<p dir="auto">Hi and welcome to devnet,</p>
<p dir="auto">I haven't done that yet but one thing that is important with QML is the casing. You QML classes should always start with an uppercased letter and I see that you have myClass in your declaration rather than MyClass.</p>
]]></description><link>https://forum.qt.io/post/762525</link><guid isPermaLink="true">https://forum.qt.io/post/762525</guid><dc:creator><![CDATA[SGaist]]></dc:creator><pubDate>Sat, 24 Jun 2023 16:26:06 GMT</pubDate></item></channel></rss>