프로그래밍 시작하기 Qt Widgets
Qt Widgets 기반 메모장 애플리케이션을 위한 튜토리얼입니다.
이 주제에서는 C++와 모듈을 사용하여 간단한 메모장 애플리케이션을 구현함으로써 기본적인 Qt 지식을 배웁니다. Qt Widgets 모듈을 이용해 간단한 메모장 애플리케이션을 구현합니다. 이 애플리케이션은 텍스트 파일을 생성하고, 저장하고, 인쇄하거나, 다시 열어 편집할 수 있는 작은 텍스트 편집기입니다. 사용할 글꼴도 설정할 수 있습니다.
예제 실행하기
에서 예제를 실행하려면 Qt Creator에서 Welcome 모드를 열고 Examples 에서 예제를 선택합니다. 자세한 내용은 예제 빌드 및 실행하기를 참조하세요.
메모장 프로젝트 만들기
Qt Creator 에서 새 프로젝트를 설정하면 프로젝트 생성 과정을 단계별로 안내하는 마법사의 도움을 받을 수 있습니다. 마법사는 특정 유형의 프로젝트에 필요한 설정을 입력하라는 메시지를 표시하고 프로젝트를 만들어 줍니다.
참고: Qt Creator 의 UI 텍스트와 생성된 파일의 내용은 사용하는 Qt Creator 버전에 따라 다릅니다.
메모장 프로젝트를 만들려면 File > New Project > Application (Qt) > Qt Widgets Application > Choose 를 선택하고 마법사의 지시를 따릅니다. Class Information 대화 상자에서 클래스 이름으로 Notepad를 입력하고 기본 클래스로 QMainWindow 을 선택합니다.
마법사가 Qt Widgets Application 마법사는 기본 소스 파일과 사용자 인터페이스(메모장 위젯)를 지정하는 파일 집합을 포함하는 프로젝트를 만듭니다:
- CMakeLists.txt - 프로젝트 파일입니다.
- main.cpp - 애플리케이션의 메인 소스 파일입니다.
- notepad.cpp - 메모장 위젯의 메모장 클래스의 소스 파일입니다.
- notepad.h - 메모장 위젯의 메모장 클래스의 헤더 파일입니다.
- notepad.ui - 메모장 위젯의 UI 양식입니다.
이 파일에는 프로젝트를 빌드하고 실행하는 데 필요한 상용구 코드가 함께 제공됩니다. 다음 섹션에서 파일 내용을 자세히 살펴보겠습니다.
자세히 알아보기
About | 여기 |
---|---|
사용 Qt Creator | Qt Creator |
다른 종류의 애플리케이션 만들기 Qt Creator | Qt Creator 튜토리얼 |
메인 소스 파일
마법사는 main.cpp 파일에 다음 코드를 생성합니다:
#include "notepad.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); Notepad w; w.show(); return a.exec(); }
코드를 한 줄씩 살펴보겠습니다. 다음 줄에는 메모장 위젯과 QApplication 에 대한 헤더 파일이 포함되어 있습니다. 모든 Qt 클래스에는 그 이름을 딴 헤더 파일이 있습니다.
#include "notepad.h" #include <QApplication>
다음 줄은 모든 C 및 C++ 기반 애플리케이션의 진입점인 메인 함수를 정의합니다:
int main(int argc, char *argv[])
다음 줄은 QApplication 객체를 생성합니다. 이 객체는 응용 프로그램 전체의 리소스를 관리하며 Qt Widgets 을 사용하는 모든 Qt 프로그램을 실행하는 데 필요합니다. argv
에서 실행되는 argc
명령줄 인수를 사용하여 애플리케이션 객체를 구성합니다( Qt Widgets 를 사용하지 않는 GUI 애플리케이션의 경우 QGuiApplication 를 대신 사용할 수 있습니다).
QApplication a(argc, argv);
다음 줄은 메모장 객체를 생성합니다. 이 객체는 마법사가 클래스와 UI 파일을 생성한 객체입니다. 사용자 인터페이스에는 Qt에서 widgets
이라고 하는 시각적 요소가 포함되어 있습니다. 위젯의 예로는 텍스트 편집, 스크롤 막대, 레이블 및 라디오 버튼이 있습니다. 위젯은 다른 위젯, 예를 들어 대화상자나 메인 애플리케이션 창을 위한 컨테이너가 될 수도 있습니다.
Notepad w;
다음 줄은 화면의 메모장 위젯을 자체 창에 표시한 것입니다. 위젯은 컨테이너로도 기능할 수 있습니다. 예를 들어 QMainWindow 에는 여러 종류의 위젯이 들어 있는 경우가 많습니다. 위젯은 기본적으로 표시되지 않지만 show() 함수를 사용하면 위젯을 표시할 수 있습니다.
w.show();
다음 줄은 QApplication 을 이벤트 루프로 진입시킵니다. Qt 애플리케이션이 실행 중일 때 이벤트가 생성되어 애플리케이션의 위젯으로 전송됩니다. 이벤트의 예로는 마우스 누름과 키 입력이 있습니다.
return a.exec();
더 알아보기
About | 여기 |
---|---|
위젯과 창 지오메트리 | 창 및 대화 상자 위젯 |
이벤트 및 이벤트 처리 | 이벤트 시스템 |
UI 디자인하기
마법사는 XML 형식의 사용자 인터페이스 정의인 notepad.ui를 생성합니다. notepad.ui 파일을 Qt Creator 에서 열면 통합된 Qt Widgets Designer 에서 자동으로 열립니다.
애플리케이션을 빌드하면 Qt Creator 에서 .ui 파일을 읽고 해당 C++ 헤더 파일인 ui_notepad.h를 생성하는 Qt User Interface Compiler (uic) 를 실행합니다.
사용 Qt Widgets Designer
마법사는 QMainWindow 을 사용하는 애플리케이션을 생성합니다. 이 애플리케이션에는 메뉴 모음, 도크 위젯, 도구 모음 및 상태 표시줄을 추가할 수 있는 자체 레이아웃이 있습니다. 가운데 영역은 모든 종류의 위젯이 차지할 수 있습니다. 마법사는 메모장 위젯을 여기에 배치합니다.
위젯을 추가하려면 Qt Widgets Designer:
- Qt Creator Edit 모드에서 Projects 보기의 notepad.ui 파일을 두 번 클릭하여 통합된 Qt Widgets Designer 에서 파일을 실행합니다.
- 위젯 텍스트 편집(QTextEdit)을 양식으로 끌어다 놓습니다.
- Ctrl+A (또는 Cmd+A)를 눌러 위젯을 선택하고 Lay out Vertically (또는 Ctrl+L)을 클릭하여 세로 레이아웃(QVBoxLayout)을 적용합니다.
- Ctrl+S (또는 Cmd+S)를 눌러 변경 내용을 저장합니다.
이제 UI는 Qt Widgets Designer 에서 다음과 같이 표시됩니다:
코드 편집기에서 생성된 XML 파일을 볼 수 있습니다:
<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>Notepad</class> <widget class="QMainWindow" name="Notepad"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>800</width> <height>400</height> </rect> </property> <property name="windowTitle"> <string>Notepad</string> </property> <widget class="QWidget" name="centralWidget"> <layout class="QVBoxLayout" name="verticalLayout"> <item> <widget class="QTextEdit" name="textEdit"/> </item> </layout> </widget> <widget class="QMenuBar" name="menuBar"> ...
다음 줄에는 문서에 사용되는 XML 버전과 문자 인코딩을 지정하는 XML 선언이 포함되어 있습니다:
<?xml version="1.0" encoding="UTF-8"?>
파일의 나머지 부분은 메모장 위젯을 정의하는 ui
요소를 지정합니다:
<ui version="4.0">
UI 파일은 메모장 클래스의 헤더 및 소스 파일과 함께 사용됩니다. 나머지 UI 파일에 대해서는 이후 섹션에서 살펴보겠습니다.
메모장 헤더 파일
마법사는 필수 #include, 생성자, 소멸자 및 Ui 객체가 있는 메모장 클래스에 대한 헤더 파일을 생성했습니다. 파일은 다음과 같습니다:
#include <QMainWindow> QT_BEGIN_NAMESPACE namespace Ui { class Notepad; } QT_END_NAMESPACE class Notepad : public QMainWindow { Q_OBJECT public: explicit Notepad(QWidget *parent = nullptr); ~Notepad(); private: Ui::Notepad *ui; QString currentFile; };
다음 줄에는 기본 애플리케이션 창을 제공하는 QMainWindow 이 포함되어 있습니다:
#include <QMainWindow>
다음 줄은 uic
도구로 .ui 파일에서 생성된 UI 클래스의 표준 네임스페이스인 Ui 네임스페이스에서 Notepad 클래스를 선언합니다:
namespace Ui { class Notepad; }
클래스 선언에는 Q_OBJECT
매크로가 포함되어 있습니다. 이 매크로는 클래스 정의에서 가장 먼저 와야 하며, 클래스를 QObject 로 선언해야 합니다. 당연히 QObject 에서도 상속해야 합니다. QObject 는 일반 C++ 클래스에 몇 가지 어빌리티를 추가합니다. 특히 런타임에 클래스 이름과 슬롯 이름을 쿼리할 수 있습니다. 또한 슬롯의 매개변수 유형을 쿼리하여 호출할 수도 있습니다.
class Notepad : public QMainWindow { Q_OBJECT
다음 줄은 parent
라는 기본 인수를 가진 생성자를 선언합니다. 값 0은 위젯에 부모가 없음을 나타냅니다(최상위 위젯입니다).
public: explicit Notepad(QWidget *parent = nullptr);
다음 줄은 객체의 수명 주기 동안 획득한 리소스를 해제하는 가상 소멸자를 선언합니다. C++ 명명 규칙에 따르면 소멸자는 물결표(~)가 앞에 붙는 연관된 클래스와 동일한 이름을 갖습니다. QObject 에서 소멸자는 가상의 것으로, 기본 클래스에 대한 포인터를 통해 객체가 삭제될 때 파생 클래스의 소멸자가 제대로 호출되도록 하기 위한 것입니다.
~Notepad();
다음 줄은 메모장 UI 클래스에 대한 포인터인 멤버 변수를 선언합니다. 멤버 변수는 특정 클래스와 연관되어 있으며 모든 메서드에 액세스할 수 있습니다.
private: Ui::Notepad *ui; QString currentFile; };
메모장 소스 파일
마법사가 메모장 클래스에 대해 생성한 소스 파일은 다음과 같습니다:
#include "notepad.h" #include "ui_notepad.h" Notepad::Notepad(QWidget *parent) : QMainWindow(parent), ui(new Ui::Notepad) { ui->setupUi(this); }
다음 줄에는 마법사가 생성한 메모장 클래스 헤더 파일과 uic
도구에서 생성한 UI 헤더 파일이 포함되어 있습니다:
#include "notepad.h" #include "ui_notepad.h"
다음 줄은 Notepad
생성자를 정의합니다:
Notepad::Notepad(QWidget *parent) :
다음 줄은 메모장 클래스의 기본 클래스인 QMainWindow 생성자를 호출합니다:
QMainWindow(parent),
다음 줄은 UI 클래스 인스턴스를 생성하고 ui
멤버에 할당합니다:
ui(new Ui::Notepad)
다음 줄은 UI를 설정합니다:
{ ui->setupUi(this);
소멸자에서 ui
:
Notepad::~Notepad() { delete ui; }
프로젝트 파일
마법사는 다음 프로젝트 파일인 CMakeLists.txt
을 생성합니다:
# Copyright (C) 2022 The Qt Company Ltd. # SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause cmake_minimum_required(VERSION 3.16) project(notepad LANGUAGES CXX) find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets OPTIONAL_COMPONENTS PrintSupport ) qt_standard_project_setup() qt_add_executable(notepad main.cpp notepad.cpp notepad.h notepad.ui ) set_target_properties(notepad PROPERTIES WIN32_EXECUTABLE TRUE MACOSX_BUNDLE TRUE ) target_link_libraries(notepad PRIVATE Qt6::Core Qt6::Gui Qt6::Widgets ) if(TARGET Qt6::PrintSupport) target_link_libraries(notepad PRIVATE Qt6::PrintSupport) endif() # Resources: set(notepad_resource_files "images/bold.png" "images/copy.png" "images/create.png" "images/cut.png" "images/edit_redo.png" "images/edit_undo.png" "images/exit.png" "images/font.png" "images/info.png" "images/italic.png" "images/new.png" "images/open.png" "images/paste.png" "images/pencil.png" "images/print.png" "images/save.png" "images/save_as.png" "images/underline.png" ) qt_add_resources(notepad "notepad" PREFIX "/" FILES ${notepad_resource_files} ) install(TARGETS notepad BUNDLE DESTINATION . RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ) qt_generate_deploy_app_script( TARGET notepad OUTPUT_SCRIPT deploy_script NO_UNSUPPORTED_PLATFORM_ERROR ) install(SCRIPT ${deploy_script})
프로젝트 파일은 프로젝트에 포함된 소스, 헤더 및 UI 파일을 지정합니다.
자세히 알아보기
About | 여기 |
---|---|
사용 Qt Widgets Designer | Qt Widgets Designer Manual |
레이아웃 | 레이아웃 관리, 위젯과 레이아웃, 레이아웃 예제 |
Qt와 함께 제공되는 위젯들 | Qt 위젯 갤러리 |
메인 윈도우와 메인 윈도우 클래스 | 어플리케이션 메인 윈도우, 메인 윈도우 예제 |
Q 객체와 Qt 객체 모델 (Qt를 이해하는 데 필수) | 객체 모델 |
qmake와 Qt 빌드 시스템 | qmake 매뉴얼 |
사용자 상호작용 추가하기
에디터에 기능을 추가하려면 먼저 도구 모음에 메뉴 항목과 버튼을 추가합니다.
"여기에 입력"을 클릭하고 새로 만들기, 열기, 저장, 다른 이름으로 저장, 인쇄 및 종료 옵션을 추가합니다. 이렇게 하면 아래의 작업 편집기에 5줄이 생성됩니다. 동작을 슬롯에 연결하려면 동작을 마우스 오른쪽 버튼으로 클릭하고 Go to slot > triggered() 을 선택한 다음 해당 슬롯에 대한 코드를 완성합니다.
또한 툴바에 동작을 추가하려면 QAction 에 각각 아이콘을 할당하고 QAction 을 툴바로 드래그하면 됩니다. 해당 작업의 아이콘 속성에 아이콘 이름을 입력하여 아이콘을 할당합니다. QAction 을 도구 모음으로 드래그한 후 아이콘을 클릭하면 연결된 슬롯이 실행됩니다.
메서드를 완료합니다 newDocument()
:
void Notepad::newDocument() { currentFile.clear(); ui->textEdit->setText(QString()); }
currentFile
변수는 현재 편집 중인 파일을 포함하는 전역 변수이며 clear()
은 텍스트 버퍼를 지웁니다. currentFile
변수는 notepad.h의 비공개 부분에 정의되어 있습니다:
private: Ui::Notepad *ui; QString currentFile;
파일 열기
notepad.ui
에서 actionOpen
을 마우스 오른쪽 버튼으로 클릭하고 Go to Slot 을 선택합니다.
메서드 완료 open()
.
void Notepad::open() { QString fileName = QFileDialog::getOpenFileName(this, "Open the file"); if (fileName.isEmpty()) return; QFile file(fileName); currentFile = fileName; if (!file.open(QIODevice::ReadOnly | QFile::Text)) { QMessageBox::warning(this, "Warning", "Cannot open file: " + file.errorString()); return; } setWindowTitle(fileName); QTextStream in(&file); QString text = in.readAll(); ui->textEdit->setText(text); file.close(); }
QFileDialog::getOpenFileName
파일을 선택할 수 있는 대화 상자가 열립니다. QFile 객체 myfile
에는 선택된 file_name
이 매개변수로 있습니다. 나중에 사용할 수 있도록 선택한 파일도 전역 변수 currentFile
에 저장합니다. file.open
을 사용하여 파일을 읽기 전용 텍스트 파일로 엽니다. 파일을 열 수 없으면 경고가 표시되고 프로그램이 중지됩니다.
매개변수 myfile
에 대해 QTextStream instream
을 정의합니다. myfile
파일의 내용이 QString text
에 복사됩니다. setText(text)
편집기의 버퍼를 text
로 채웁니다.
파일 저장하기
파일 열기와 동일한 방법으로 파일을 저장하는 메서드를 만듭니다. actionSave
을 마우스 오른쪽 버튼으로 클릭하고 Go to Slot 을 선택합니다.
void Notepad::save() { QString fileName; // If we don't have a filename from before, get one. if (currentFile.isEmpty()) { fileName = QFileDialog::getSaveFileName(this, "Save"); if (fileName.isEmpty()) return; currentFile = fileName; } else { fileName = currentFile; } QFile file(fileName); if (!file.open(QIODevice::WriteOnly | QFile::Text)) { QMessageBox::warning(this, "Warning", "Cannot save file: " + file.errorString()); return; } setWindowTitle(fileName); QTextStream out(&file); QString text = ui->textEdit->toPlainText(); out << text; file.close(); }
QFile 객체 myfile
는 작업 중인 파일이 포함된 변수인 전역 변수 current_file
에 연결됩니다. myfile
을 열 수 없으면 오류 메시지가 표시되고 메서드가 중지됩니다. QTextStream outstream
을 만듭니다. 편집기 버퍼의 내용이 일반 텍스트로 변환된 다음 outstream
에 기록됩니다.
다른 이름으로 파일 저장하기
void Notepad::saveAs() { QString fileName = QFileDialog::getSaveFileName(this, "Save as"); if (fileName.isEmpty()) return; QFile file(fileName); if (!file.open(QFile::WriteOnly | QFile::Text)) { QMessageBox::warning(this, "Warning", "Cannot save file: " + file.errorString()); return; } currentFile = fileName; setWindowTitle(fileName); QTextStream out(&file); QString text = ui->textEdit->toPlainText(); out << text; file.close(); }
이 절차는 파일 저장과 동일하지만, 여기서 생성할 파일의 새 파일 이름을 입력해야 한다는 점만 다릅니다.
파일 인쇄
인쇄 기능을 사용하려면 프로젝트 파일에 PrintSupport
을 추가해야 합니다:
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets OPTIONAL_COMPONENTS PrintSupport )
notepad.cpp
에서 printDev
이라는 QPrinter 객체를 선언합니다:
void Notepad::print() { #if defined(QT_PRINTSUPPORT_LIB) && QT_CONFIG(printer) QPrinter printDev; #if QT_CONFIG(printdialog) QPrintDialog dialog(&printDev, this); if (dialog.exec() == QDialog::Rejected) return; #endif // QT_CONFIG(printdialog) ui->textEdit->print(&printDev); #endif // QT_CONFIG(printer) }
프린터 대화 상자를 실행하고 선택한 프린터를 printDev
객체에 저장합니다. Cancel
을 클릭하고 프린터를 선택하지 않은 경우 메서드가 반환됩니다. 실제 프린터 명령은 QPrinter 객체를 매개변수로 사용하여 ui->textEdit->print
로 전달됩니다.
글꼴 선택
void Notepad::selectFont() { bool fontSelected; QFont font = QFontDialog::getFont(&fontSelected, this); if (fontSelected) ui->textEdit->setFont(font); }
QFontDialog 로 글꼴을 선택했는지 여부를 나타내는 부울을 선언합니다. 그렇다면 ui->textEdit->setFont(myfont)
로 글꼴을 설정합니다.
복사, 잘라내기, 붙여넣기, 실행 취소 및 다시 실행하기
텍스트를 선택한 후 클립보드에 복사하려면 ui->textEdit
의 적절한 메서드를 호출합니다. 잘라내기, 붙여넣기, 실행 취소 및 다시 실행도 마찬가지입니다.
이 표에는 사용할 메서드 이름이 나와 있습니다.
작업 | 호출되는 메서드 |
---|---|
복사 | ui->textEdit->copy() |
Cut | ui->textEdit->cut() |
Paste | ui->textEdit->paste() |
Undo | ui->textEdit->undo() |
Redo | ui->textEdit->redo() |
더 알아보기
About | 여기 |
---|---|
파일 및 입출력 장치 | QFile, QIODevice |
tr() 및 국제화 | Qt Linguist 매뉴얼, 번역을 위한 소스 코드 작성, Qt로 국제화하기 |
명령줄에서 빌드 및 실행하기
명령줄에서 예제 애플리케이션을 빌드하려면 해당 애플리케이션의 빌드 디렉터리를 만듭니다. 빌드 디렉토리로 전환하고 qt-cmake
을 실행하여 빌드할 프로젝트를 구성합니다. 프로젝트가 성공적으로 구성되면 생성된 파일을 통해 프로젝트를 빌드할 수 있습니다.
md <build_directory> cd <build_directory> <qt_installation_directory>\bin\qt-cmake -GNinja <source_directory> <generator>
이 명령은 빌드 디렉터리에 실행 파일을 만듭니다. CMake
도구는 프로젝트 파일을 읽고 애플리케이션을 빌드하는 방법에 대한 지침을 생성합니다. 그런 다음 생성기는 이 지침을 사용하여 실행 가능한 바이너리를 생성합니다.
예를 들어 Windows에서 메모장 예제를 빌드하려면 Ninja를 생성기로 사용하는 경우 다음 명령을 입력합니다:
md notepad-build cd notepad-build C:\Qt\6.8.2\msvc2019_64\bin\qt-cmake -GNinja C:\Examples\notepad ninja
Ninja를 생성기로 사용하지 않는 경우, 생성기와 독립적인 CMake 명령을 사용하여 ninja
대신 애플리케이션을 빌드합니다:
cmake --build
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.