{"id":3642,"date":"2026-01-02T10:45:47","date_gmt":"2026-01-02T01:45:47","guid":{"rendered":"https:\/\/www.freelifemakers.org\/wordpress\/?p=3642"},"modified":"2026-01-03T12:32:51","modified_gmt":"2026-01-03T03:32:51","slug":"qt1-reading-text-files","status":"publish","type":"post","link":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/2026\/01\/02\/qt1-reading-text-files\/","title":{"rendered":"[QT QML] \ud14d\uc2a4\ud2b8 \ud30c\uc77c \uc77d\uae30 \/ Reading text files"},"content":{"rendered":"\n<p>\ud83d\udc49\ud83c\udffb \uc544\ub798\ub294 \ud14d\uc2a4\ud2b8 \ud30c\uc77c\uc744 \uc77d\uc5b4 \uc624\ub294 \uac04\ub2e8\ud55c \uc571\uc785\ub2c8\ub2e4.<br>Below is a simple app that reads a text file.<\/p>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb UI\ub294 QML\ub85c \uad6c\uc131\ud558\uace0 \ud30c\uc77c\uc744\uc77d\uc5b4 \uc624\ub294 \ubd80\ubd84\uc740 C++\uc785\ub2c8\ub2e4.<br>The UI is composed of QML and the part that reads files is in C++.<\/p>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb \uc124\uba85\uc740 \uc8fc\uc11d\uc744 \ucc38\uace0 \ud558\uc2dc\uae38 \ubc14\ub78d\ub2c8\ub2e4.<br>Please refer to the comments for explanation.<\/p>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb\ucf54\ub4dc \/  Code<\/p>\n\n\n\n<p>\u2714\ufe0f CMakeLists.txt<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cmake_minimum_required(VERSION 3.16)\n\nproject(ReadFile 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(appReadFile\n    main.cpp\n)\n\nqt_add_qml_module(appReadFile\n    URI ReadFile\n    QML_FILES\n        Main.qml\n        SOURCES filehelper.h filehelper.cpp\n)\n\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(appReadFile PROPERTIES\n#    MACOSX_BUNDLE_GUI_IDENTIFIER com.example.appReadFile\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(appReadFile\n    PRIVATE Qt6::Quick\n)\n\ninclude(GNUInstallDirs)\ninstall(TARGETS appReadFile\n    BUNDLE DESTINATION .\n    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}\n    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}\n)\n<\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f filehelpher.h<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#ifndef FILEHELPER_H\n#define FILEHELPER_H\n\n#include &lt;QObject>\n#include &lt;QUrl>\n\nclass FileHelper : public QObject\n{\n    Q_OBJECT\npublic:\n    explicit FileHelper(QObject *parent = nullptr);\n\n    \/\/ \u2b50\ufe0f Q_INVOKABLE Qt\uc758 \ub9e4\ud06c\ub85c\ub85c, \uc774 \ub9e4\ud06c\ub85c\uac00 \ubd99\uc740 \uba64\ubc84 \ud568\uc218\ub294 QML\uc5d0\uc11c \uc9c1\uc811 \ud638\ucd9c(invoke)\ud560 \uc218 \uc788\uac8c \ub9cc\ub4e4\uc5b4\uc90d\ub2c8\ub2e4.\n    \/\/    \uc774 \ub9e4\ud06c\ub85c\uac00 \uc5c6\uc73c\uba74 QML\uc5d0\uc11c \ud574\ub2f9 \ud568\uc218\ub97c \ud638\ucd9c\ud558\ub824\uace0 \ud558\uba74 \"ReferenceError: readFile is not defined\" \uac19\uc740 \uc624\ub958\uac00 \ubc1c\uc0dd\ud569\ub2c8\ub2e4.\n    \n    \/\/ Q_INVOKABLE is a Qt macro that allows member functions marked with this macro to be directly invoked from QML. \n    \/\/ Without this macro, attempting to call the function from QML would result in an error like \"ReferenceError: readFile is not defined.\"\n\n    \/\/ \ud30c\uc77c \uc77d\uae30 \/ read file\n    Q_INVOKABLE QString readFile(const QUrl &amp;fileUrl);\n\n};\n\n#endif\n<\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f filehelper.cpp<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include \"FileHelper.h\"\n#include &lt;QFile>\n#include &lt;QTextStream>\n#include &lt;QDebug>\n\nFileHelper::FileHelper(QObject *parent) : QObject(parent)\n{\n}\n\nQString FileHelper::readFile(const QUrl &amp;fileUrl)\n{\n    \/\/ QUrl\uc744 \ub85c\uceec \uacbd\ub85c \ubb38\uc790\uc5f4\ub85c \ubcc0\ud658\n    \/\/ Convert QUrl to local path string\n    QString path = fileUrl.toLocalFile();\n\n    QFile file(path);\n    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {\n        qWarning() &lt;&lt; \"\ud30c\uc77c \uc5f4\uae30 \uc2e4\ud328\/File open failed:\" &lt;&lt; path;\n        return QString();\n    }\n\n    QTextStream in(&amp;file);\n    QString content = in.readAll();\n    file.close();\n    return content;\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#include &lt;QQmlContext&gt;  \/\/ setContextProperty\n#include \"FileHelper.h\"\n\nint main(int argc, char *argv&#91;])\n{\n    QGuiApplication app(argc, argv);\n\n    \/\/ fileHelper \uc778\uc2a4\ud134\uc2a4 \uc0dd\uc131\n    \/\/ Create a fileHelper instance\n    FileHelper fileHelper;\n\n    QQmlApplicationEngine engine;\n\n    \/\/ QML \uc5d4\uc9c4\uc5d0 C++ \uac1d\uccb4 \ub4f1\ub85d (QML\uc5d0\uc11c 'fileHelper'\ub77c\ub294 \uc774\ub984\uc73c\ub85c \uc811\uadfc \uac00\ub2a5)\n    \/\/ engine.loadFromModule \ud638\ucd9c \uc804\uc5d0 \ub4f1\ub85d\ud574\uc57c \ud569\ub2c8\ub2e4.\n    \/\/ Register a C++ object with the QML engine (accessible from QML as 'fileHelper')\n    \/\/ Must be registered before calling engine.loadFromModule.\n    engine.rootContext()-&gt;setContextProperty(\"fileHelper\", &amp;fileHelper);\n\n    QObject::connect(\n        &amp;engine,\n        &amp;QQmlApplicationEngine::objectCreationFailed,\n        &amp;app,\n        &#91;]() { QCoreApplication::exit(-1); },\n        Qt::QueuedConnection);\n\n    \/\/ \uae30\ubcf8\uac12:\ubaa8\ub4c8 \ub85c\ub4dc (Qt6 \ubc29\uc2dd)\n    \/\/ \"ReadFile\"\uc740 CMakeLists.txt\uc758 qt_add_qml_module\uc5d0 \uc815\uc758\ub41c URI\uc5ec\uc57c \ud569\ub2c8\ub2e4.\n    \/\/ Default: Module loading (Qt6 style)\n    \/\/ \"ReadFile\" must be a URI defined in qt_add_qml_module in CMakeLists.txt.\n    engine.loadFromModule(\"ReadFile\", \"Main\");\n\n    return app.exec();\n}\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\nimport QtQuick.Window\nimport QtQuick.Controls\nimport QtQuick.Dialogs\nimport QtCore  \/\/ StandardPaths\n\nWindow {\n    width: 800\n    height: 600\n    visible: true\n    title: qsTr(\"Qt6 \ud30c\uc77c \uc77d\uae30 \uc608\uc81c\/Qt6 file reading example\")\n\n    FileDialog {\n        id: fileDialog\n        title: \"\uc77d\uc744 \ud30c\uc77c\uc744 \uc120\ud0dd\ud558\uc138\uc694\/Select a file to read\"\n\n\n        currentFolder: StandardPaths.writableLocation(StandardPaths.HomeLocation)\n        nameFilters: &#91;\"Text files (*.txt)\", \"All files (*)\"]\n\n        onAccepted: {\n            \/\/ fileDialog.selectedFile\uc740 QUrl \ud0c0\uc785\uc744 \ubc18\ud658\ud569\ub2c8\ub2e4.\n            let content = fileHelper.readFile(fileDialog.selectedFile)\n\n            if (content.length &gt; 0) {\n                textArea.text = content\n                statusText.text = \"\uc131\uacf5\/success: \" + fileDialog.selectedFile\n                statusText.color = \"darkgreen\"\n            } else {\n                statusText.text = \"\ud30c\uc77c\uc744 \uc77d\uc744 \uc218 \uc5c6\uac70\ub098 \ub0b4\uc6a9\uc774 \uc5c6\uc2b5\ub2c8\ub2e4.\/The file is unreadable or contains no content.\"\n                statusText.color = \"red\"\n            }\n        }\n    }\n\n    Column {\n        anchors.centerIn: parent\n        spacing: 20\n\n        Button {\n                    id: openButton\n                    text: \"\ud30c\uc77c \uc120\ud0dd \ud6c4 \uc77d\uae30 \/ Select file and read\"\n                    anchors.horizontalCenter: parent.horizontalCenter\n\n                    \/\/ \ubc84\ud2bc\uc774 \uc548 \ubcf4\uc77c \ub54c\ub97c \ub300\ube44\ud574 \ubc30\uacbd\uc0c9\uacfc \uae00\uc790\uc0c9 \uac15\uc81c \uc9c0\uc815 \uac00\ub2a5 (\uc120\ud0dd \uc0ac\ud56d)\n                    \/\/ Optionally force background and text colors to be set when the button is not visible.\n                    contentItem: Text {\n                        text: openButton.text\n                        font.pixelSize: 16\n                        color: \"white\" \/\/ font color\n                        horizontalAlignment: Text.AlignHCenter\n                        verticalAlignment: Text.AlignVCenter\n                    }\n\n                    background: Rectangle {\n                        implicitWidth: 150\n                        implicitHeight: 40\n                        color: openButton.down ? \"#2980b9\" : \"#3498db\" \/\/ \ud074\ub9ad \uc2dc \ub354 \uc5b4\ub450\uc6b4 \ud30c\ub780\uc0c9\n                        radius: 4\n                    }\n\n                    onClicked: fileDialog.open()\n        }\n\n        ScrollView {\n            width: 700\n            height: 400\n            TextArea {\n                id: textArea\n                placeholderText: \"\uc5ec\uae30\uc5d0 \ud30c\uc77c \ub0b4\uc6a9\uc774 \ud45c\uc2dc\ub429\ub2c8\ub2e4... \/ Here are the file contents...\"\n                wrapMode: TextArea.Wrap\n                selectByMouse: true\n                font.pixelSize: 14\n            }\n        }\n\n        Text {\n            id: statusText\n            text: \"\uc900\ube44 \uc644\ub8cc \/ Ready\"\n            font.pixelSize: 14\n            anchors.horizontalCenter: parent.horizontalCenter\n        }\n    }\n}\n<\/code><\/pre>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb \uc2a4\ud06c\ub9b0 \uc0f7 \/ ScreenShot<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"803\" src=\"https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/01\/1-1024x803.png\" alt=\"\" class=\"wp-image-3648\" srcset=\"https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/01\/1-1024x803.png 1024w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/01\/1-300x235.png 300w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/01\/1-768x602.png 768w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/01\/1-1536x1205.png 1536w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/01\/1-400x314.png 400w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/01\/1-800x628.png 800w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/01\/1.png 1596w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"804\" src=\"https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/01\/2-1024x804.png\" alt=\"\" class=\"wp-image-3649\" srcset=\"https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/01\/2-1024x804.png 1024w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/01\/2-300x236.png 300w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/01\/2-768x603.png 768w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/01\/2-1536x1206.png 1536w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/01\/2-400x314.png 400w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/01\/2-800x628.png 800w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/01\/2.png 1592w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\ud83d\udc49\ud83c\udffb \uc544\ub798\ub294 \ud14d\uc2a4\ud2b8 \ud30c\uc77c\uc744 \uc77d\uc5b4 \uc624\ub294 \uac04\ub2e8\ud55c \uc571\uc785\ub2c8\ub2e4.Below is a simple app that reads a text file. \ud83d\udc49\ud83c\udffb UI\ub294 QML\ub85c \uad6c\uc131\ud558\uace0 \ud30c\uc77c\uc744\uc77d\uc5b4 \uc624\ub294 \ubd80\ubd84\uc740 C++\uc785\ub2c8\ub2e4.The UI is composed of QML and the part that reads files is in C++. \ud83d\udc49\ud83c\udffb \uc124\uba85\uc740 \uc8fc\uc11d\uc744 \ucc38\uace0 \ud558\uc2dc\uae38 \ubc14\ub78d\ub2c8\ub2e4.Please refer to the comments for explanation. \ud83d\udc49\ud83c\udffb\ucf54\ub4dc \/ Code \u2714\ufe0f [&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-3642","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\/3642","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=3642"}],"version-history":[{"count":10,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/3642\/revisions"}],"predecessor-version":[{"id":3689,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/3642\/revisions\/3689"}],"wp:attachment":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/media?parent=3642"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/categories?post=3642"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/tags?post=3642"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}