{"id":2247,"date":"2025-10-11T13:32:24","date_gmt":"2025-10-11T04:32:24","guid":{"rendered":"https:\/\/www.freelifemakers.org\/wordpress\/?p=2247"},"modified":"2026-07-29T11:06:29","modified_gmt":"2026-07-29T02:06:29","slug":"qt-example3-qml","status":"publish","type":"post","link":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/2025\/10\/11\/qt-example3-qml\/","title":{"rendered":"[QT]example3-QML+C++(1)"},"content":{"rendered":"\n<p>\ud83d\udc49 QML\uc744 \ud1b5\ud574\uc11c \uc785\ub825\ub41c \ub0b4\uc6a9\uc744 \uc9c1\uc811 \ud654\uba74\uc5d0 \ucd9c\ub825 \ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<br>You can directly display the content entered through QML on the screen.<\/p>\n\n\n\n<p>\ud83d\udc49 \uc774 \ubd80\ubd84\uc740 \ucd9c\ub825\uc740 C++\uc774 \uc218\ud589\ud558\uace0 C++\ucf54\ub4dc\ub97c QML\uc5d0 \uc5f0\uacb0\ud558\ub294 \uac83\uc5d0 \ub300\ud55c \uc124\uba85\uc785\ub2c8\ub2e4.<br>This part explains how the output is done in C++ and how to connect the C++ code to QML.<\/p>\n\n\n\n<p><strong>\ud83d\udcc11.\ud504\ub85c\uc81d\ud2b8 \/ Project<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"849\" height=\"513\" src=\"https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2025\/10\/example3-1.png\" alt=\"\" class=\"wp-image-2269\" srcset=\"https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2025\/10\/example3-1.png 849w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2025\/10\/example3-1-300x181.png 300w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2025\/10\/example3-1-768x464.png 768w\" sizes=\"auto, (max-width: 849px) 100vw, 849px\" \/><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>\ud83d\udcc1 <strong>2.C++ \uacfc qml \uc5f0\uacb0<\/strong> \/ Connecting C++ and QML<\/p>\n\n\n\n<p>\u2714\ufe0f myconnector.h\uc640 myconnector.cpp\ud30c\uc77c\uc5d0 qml\uc5d0\uc11c \uc0ac\uc6a9\ud560 \uc2dc\uadf8\ub110\uacfc \ud568\uc218\ub97c \uc124\uc815\ud569\ub2c8\ub2e4.<br>Define the signals and functions to be used in QML within the myconnector.h and myconnector.cpp files.<\/p>\n\n\n\n<p>\u2714\ufe0f \uc544\ub798\uc758 \ucf54\ub4dc\ub294 \ud5e4\ub354\ud30c\uc77c\uc758 \ucf54\ub4dc\uc785\ub2c8\ub2e4.<br>The code below is from the header file.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#ifndef MYCONNECTOR_H\n#define MYCONNECTOR_H\n\n\/\/ MyConnector.h\n\n#include &lt;QObject&gt;\n#include &lt;QString&gt;\n\nclass MyConnector : public QObject {\n    Q_OBJECT\n\npublic:\n    explicit MyConnector(QObject *parent = nullptr);\n\n    Q_INVOKABLE void <strong>updateText(<\/strong>const QString &amp;text1, const QString &amp;text2);\n\nsignals:\n    void <strong>resultReady<\/strong>(const QString &amp;result);\n};\n\n#endif \/\/ MYCONNECTOR_H\n<\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f updateText\ub294 qml(Screen01.qml)\uc5d0\uc11c \uc544\ub798\uc640 \uac19\uc774 \uc0ac\uc6a9\ud569\ub2c8\ub2e4.<br>updateText is used in QML (Screen01.qml) as shown below.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>        Button {\n            id: button\n            text: qsTr(\"Button\")\n            \/\/ === \ucf54\ub4dc\ucd94\uac00:\ud074\ub9ad \uc774\ubca4\ud2b8 ===\n            \/\/ === Add code:Click Event ===\n            onClicked: <strong>myConnector.updateText<\/strong>(textEdit.text, textEdit2.text)\n\n        }<\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f QML\uc5d0 \uac1d\uccb4 \ub4f1\ub85d\ud558\uae30(C++\uacfc QML \uc5f0\uacb0)<br>Registering Objects in QML (Connecting C++ and QML)<\/p>\n\n\n\n<p>&#8212; Main.cpp\uc5d0 \uc544\ub798\ucc98\ub7fc  myConnector\ud074\ub798\uc2a4\ub97c QML\uac1d\uccb4\ub85c \ub4f1\ub85d\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<br>You can register the <code>myConnector<\/code> class as a QML object in <code>Main.cpp<\/code> as shown below.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/\u2705 QML\uc5d0 C++ \uac1d\uccb4\ub97c \ub4f1\ub85d\ud558\uae30 \uc704\ud574 \ud544\uc694\n\/\/ Required to register C++ objects in QML\n#include &lt;QQmlContext>\n\n\/\/\u2705 MyConnector \ud074\ub798\uc2a4 \uc120\uc5b8 \ud3ec\ud568\n\/\/ Include MyConnector class declaration\n#include \"MyConnector.h\"\n\n... \uc911\ub7b5 \/ Omitted ...    \n\nMyConnector connector;\nengine.rootContext()->setContextProperty(\"myConnector\", &amp;connector);<\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f QML\uc5d0\uc11c \uc0ac\uc6a9\ud558\uae30 \/ Using in QML<\/p>\n\n\n\n<p>&#8212; <code>onResultReady<\/code>\ub294 <code>myConnector<\/code>\ub77c\ub294 \uac1d\uccb4\uac00 \uac00\uc9c4 <strong><code>resultReady<\/code>\ub77c\ub294 \uc2dc\uadf8\ub110(Signal)<\/strong> \uc774\ub984 \uc55e\uc5d0 <code>on<\/code>\uc744 \ubd99\uc5ec\uc11c \ub9cc\ub4e0 \uc2dc\uadf8\ub110 \ud578\ub4e4\ub7ec(\uc2ac\ub86f)\uc785\ub2c8\ub2e4.<br><code>onResultReady<\/code> is a signal handler (or slot) created by prefixing &#8220;on&#8221; to the name of the <code>resultReady<\/code> signal belonging to the object named <code>myConnector<\/code>.<\/p>\n\n\n\n<p>1)Screen01.qml(on+ResultReady)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>        Connections {\n            target: myConnector\n            function <strong>onResultReady<\/strong>(result) {\n                text1.text = result\n            }\n        }<\/code><\/pre>\n\n\n\n<p>2)Myconnector.h\uc5d0 \uc2dc\uadf8\ub110 \uc120\uc5b8<br>Declare the signal in Myconnector.h<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>signals:\n    void <strong>resultReady<\/strong>(const QString &amp;result);\n};<\/code><\/pre>\n\n\n\n<p>3)Myconnector.cpp\uc5d0 \uc2dc\uadf8\ub110 \ubc1c\uc0dd<br>Signal generation in Myconnector.cpp<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void MyConnector::updateText(const QString &amp;text1, const QString &amp;text2) {\n    QString combined = text1 + \" \" + text2;\n    <strong>emit resultReady(combined);<\/strong>\n}<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>\ud83d\udcc1<strong>3.\ucf54\ub4dc\uc124\uba85 \/ Code Description<\/strong><\/p>\n\n\n\n<p>\u2714\ufe0fMyconnector.h<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#ifndef MYCONNECTOR_H\n#define MYCONNECTOR_H\n\n\/\/ MyConnector.h\n\n#include &lt;QObject&gt;\n#include &lt;QString&gt;\n\nclass MyConnector : public QObject {\n    Q_OBJECT\n\npublic:\n    explicit MyConnector(QObject *parent = nullptr);\n\n    Q_INVOKABLE void updateText(const QString &amp;text1, const QString &amp;text2);\n\nsignals:\n    void resultReady(const QString &amp;result);\n};\n\n#endif \/\/ MYCONNECTOR_H\n<\/code><\/pre>\n\n\n\n<p>&#8212; \ud5e4\ub354\uac00 \ub2e4\ub978 \ud074\ub798\uc2a4 \ud30c\uc77c\uc5d0 \ub450\ubc88 \uc0bd\uc785\ub418\uba74 \ucef4\ud30c\uc77c \uc624\ub958\uac00 \ub0a9\ub2c8\ub2e4.<br>If a header is inserted twice in different class files, a compilation error occurs.<\/p>\n\n\n\n<p>&#8212; \uc704\uc758 \ucf54\ub4dc\uc5d0\uc11c \uc544\ub798\uc640 \uac19\uc774 \uc791\uc131\ud558\uba74 \uc911\ubcf5 \uc0bd\uc785 \uc624\ub958\uac00 \ubc1c\uc0dd\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.<br>If you write the code above as follows, a duplicate insertion error will not occur.<\/p>\n\n\n\n<p>&#8212; \uc774\ubbf8 \ud5e4\ub354\uac00 C++ \ud074\ub798\uc2a4 \ud30c\uc77c\uc5d0 \ud3ec\ud568\ub418\uc5b4 \uc788\uc73c\uba74 \ubb34\uc2dc\ud569\ub2c8\ub2e4.<br>If the header is already included in the C++ class file, it is ignored.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> #ifndef MYCONNECTOR_H\n #define MYCONNECTOR_H\n\n  \ucf54\ub4dc \/ CODE\n\n #endif \/\/ MYCONNECTOR_H <\/code><\/pre>\n\n\n\n<p>\u2714\ufe0fqml\/Screen01.qml<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\nimport QtQuick\nimport QtQuick.Controls\n\n\nRectangle {\n    \/\/ id: rectangle\n    \/\/ width: Constants.width\n    \/\/ height: Constants.height\n\n    \/\/ color: Constants.backgroundColor\n\n    \/\/ \uc0c1\uc218 \uc9c1\uc811 \uc120\uc5b8. \/ Direct declaration of constants\n    property int widthConst: 1920\n    property int heightConst: 1080\n    property color backgroundColorConst: \"#EAEAEA\"\n\n    width: widthConst\n    height: heightConst\n    color: backgroundColorConst\n\n    Column {\n        id: column\n        width: 200\n        anchors.centerIn: parent\n        spacing: 10\n\n        Rectangle {\n            width: 180\n            height: 30\n            color: \"white\"\n            border.color: \"black\"\n\n            TextEdit {\n                id: textEdit\n                anchors.fill: parent\n                width: 80\n                height: 20\n                text: qsTr(\"\uc785\ub8251\/input1\")\n                font.pixelSize: 12\n            }\n        }\n\n        Rectangle {\n            width: 180\n            height: 30\n            color: \"white\"\n            border.color: \"black\"\n\n            TextEdit {\n                id: textEdit2\n                width: 80\n                height: 20\n                text: qsTr(\"\uc785\ub8252\/input2\")\n                font.pixelSize: 12\n            }\n        }\n\n        Text {\n            id: text1\n            text: qsTr(\"\uac12\ucd9c\ub825\/Print Value\")\n            font.pixelSize: 12\n        }\n\n        Button {\n            id: button\n            text: qsTr(\"Button\")\n            \/\/ === \ucf54\ub4dc\ucd94\uac00:\ud074\ub9ad \uc774\ubca4\ud2b8 ===\n            \/\/ === Add code:Click Event ===\n            <strong>onClicked: myConnector.updateText(textEdit.text, textEdit2.text)<\/strong>\n\n        }\n        \/\/ === \ucf54\ub4dc\ucd94\uac00:\uc5f0\uacb0 ===\n        \/\/ === Add code:connection ===\n<strong>        Connections {\n            target: myConnector\n            function onResultReady(result) {\n                text1.text = result\n            }\n        }<\/strong>\n\n    }\n}\n<\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f main.cpp<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;QGuiApplication&gt;\n#include &lt;QQmlApplicationEngine&gt;\n\n\/\/ QML\uc5d0 C++ \uac1d\uccb4\ub97c \ub4f1\ub85d\ud558\uae30 \uc704\ud574 \ud544\uc694\n\/\/ Required to register C++ objects in QML\n#include &lt;QQmlContext&gt;\n\n\/\/ MyConnector \ud074\ub798\uc2a4 \uc120\uc5b8 \ud3ec\ud568\n\/\/ Include MyConnector class declaration\n#include \"MyConnector.h\"\n\nint main(int argc, char *argv&#91;])\n{\n    QGuiApplication app(argc, argv);\n\n    QQmlApplicationEngine engine;\n\n    QObject::connect(\n        &amp;engine,\n        &amp;QQmlApplicationEngine::objectCreationFailed,\n        &amp;app,\n        &#91;]() { QCoreApplication::exit(-1); },\n        Qt::QueuedConnection);\n\n    \/\/ === \ucf54\ub4dc \ucd94\uac00 \/ Add code ===\n    MyConnector connector;\n    engine.rootContext()-&gt;setContextProperty(\"myConnector\", &amp;connector);\n\n    \/\/ === \uc5ec\uae30\uae4c\uc9c0 \/ Up to here ===\n    engine.loadFromModule(\"example3\", \"Main\");\n\n    return app.exec();\n}<\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f main.qml<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import QtQuick\n\nWindow {\n    width: 640\n    height: 480\n    visible: true\n    title: qsTr(\"Example3\")\n\n    \/\/ UI \ud30c\uc77c \ub85c\ub529 \/ UI file loading\n    Loader {\n        anchors.fill: parent\n        source: \"qml\/Screen01.qml\"\n    }\n}\n<\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f Myconnector.cpp<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ MyConnector.cpp\n#include \"MyConnector.h\"\n\nMyConnector::MyConnector(QObject *parent) : QObject(parent) {}\n\nvoid MyConnector::updateText(const QString &amp;text1, const QString &amp;text2) {\n    QString combined = text1 + \" \" + text2;\n    emit resultReady(combined);\n}\n<\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f CmakeLists.txt<\/p>\n\n\n\n<p>\u2714\ufe0f \uc544\ub798\uc758 \uad75\uc740 \uae00\uc528\uac00 \ud30c\uc77c \ucd94\uac00\ub41c \ubd80\ubd84\uc785\ub2c8\ub2e4.<br>The bold text below is the added portion of the file.<\/p>\n\n\n\n<p>\u2714\ufe0f \ubc14\ub85c \uc544\ub798\uc758 \ucf54\ub4dc\ub294 \uc9c1\uc811 \ucd94\uac00\ud55c \ucf54\ub4dc \uc785\ub2c8\ub2e4.<br>The code right below is the code I added myself.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong>qml\/Screen01.qml<\/strong><\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f\ubc14\ub85c \uc544\ub798\uc758 \ucf54\ub4dc\ub294 \uc790\ub3d9\uc73c\ub85c \uc218\uc815\ub41c \ub0b4\uc6a9\uc785\ub2c8\ub2e4<br>The code directly below is automatically corrected.<\/p>\n\n\n\n<p>\u2714\ufe0fQT Creator\uc758 Souce Files\uc5d0\uc11c \ub9c8\uc6b0\uc2a4 \uc624\ub978\ucabd \ud074\ub9ad,Add New\ub97c \uc0ac\uc6a9\ud55c \uacbd\uc6b0 \uc790\ub3d9\uc73c\ub85c \uc544\ub798\uc758 \ub0b4\uc6a9\uc774 \ucd94\uac00\ub429\ub2c8\ub2e4.<br>If you right-click on Source Files in QT Creator and use Add New, the following will be added automatically.<\/p>\n\n\n\n<p>\u2714\ufe0f\uc5ec\uae30\uc11c\ub294 \ud074\ub798\uc2a4 \ud30c\uc77c\uacfc \ud5e4\ub354\ud30c\uc77c\uc744 \ucd94\uac00\ud588\uc2b5\ub2c8\ub2e4.<br>Here we have added the class file and header file.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SOURCES MyConnector.h\nSOURCES MyConnector.cpp<\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f CmakeLists\uc804\uccb4 \ucf54\ub4dc \/ CmakeLists Full Code<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cmake_minimum_required(VERSION 3.16)\n\nproject(example3 VERSION 0.1 LANGUAGES CXX)\n\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\n\nfind_package(Qt6 REQUIRED COMPONENTS Quick)\n\nqt_standard_project_setup(REQUIRES 6.8)\n\nqt_add_executable(appexample3\n    main.cpp\n)\n<strong>\nqt_add_qml_module(appexample3\n    URI example3\n    VERSION 1.0\n    QML_FILES\n        Main.qml\n        qml\/Screen01.qml\n        SOURCES MyConnector.h\n        SOURCES MyConnector.cpp\n)\n<\/strong>\n# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.\n# If you are developing for iOS or macOS you should consider setting an\n# explicit, fixed bundle identifier manually though.\nset_target_properties(appexample3 PROPERTIES\n#    MACOSX_BUNDLE_GUI_IDENTIFIER com.example.appexample3\n    MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}\n    MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}\n    MACOSX_BUNDLE TRUE\n    WIN32_EXECUTABLE TRUE\n)\n\ntarget_link_libraries(appexample3\n    PRIVATE Qt6::Quick\n)\n\ninclude(GNUInstallDirs)\ninstall(TARGETS appexample3\n    BUNDLE DESTINATION .\n    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}\n    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}\n)\n<\/code><\/pre>\n\n\n\n<p><strong>3.\uc2e4\ud589 \/ Run<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"714\" height=\"594\" src=\"https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2025\/10\/example3-2.png\" alt=\"\" class=\"wp-image-2270\" srcset=\"https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2025\/10\/example3-2.png 714w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2025\/10\/example3-2-300x250.png 300w\" sizes=\"auto, (max-width: 714px) 100vw, 714px\" \/><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>\ud83d\udc49 QML\uc744 \ud1b5\ud574\uc11c \uc785\ub825\ub41c \ub0b4\uc6a9\uc744 \uc9c1\uc811 \ud654\uba74\uc5d0 \ucd9c\ub825 \ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.You can directly display the content entered through QML on the screen. \ud83d\udc49 \uc774 \ubd80\ubd84\uc740 \ucd9c\ub825\uc740 C++\uc774 \uc218\ud589\ud558\uace0 C++\ucf54\ub4dc\ub97c QML\uc5d0 \uc5f0\uacb0\ud558\ub294 \uac83\uc5d0 \ub300\ud55c \uc124\uba85\uc785\ub2c8\ub2e4.This part explains how the output is done in C++ and how to connect the C++ code to QML. \ud83d\udcc11.\ud504\ub85c\uc81d\ud2b8 \/ Project [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[17,1],"tags":[],"class_list":["post-2247","post","type-post","status-publish","format-standard","hentry","category-qt","category-uncategorized","missing-thumbnail"],"_links":{"self":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/2247","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/comments?post=2247"}],"version-history":[{"count":47,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/2247\/revisions"}],"predecessor-version":[{"id":6894,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/2247\/revisions\/6894"}],"wp:attachment":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/media?parent=2247"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/categories?post=2247"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/tags?post=2247"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}