C++을 사용하여 QT 프로젝트를 진행하는 방법을 알려주도록 하겠다.
1. QT c++ 프로젝트 생성
QT를 실행하게 되면 다음과 비슷한 화면이 나온다.
QT로 제작된 예제들과 프로젝트를 생성하거나 열 수 있다.
c++ 프로젝트를 생성하기 위해 Create Project를 클릭한다.
UI를 사용할 예정이기 때문에 Qt Widgets Application을 선택해 준다.
프로젝트의 이름과 프로젝트를 생성할 경로를 설정해 준다. 여기서 설정한 프로젝트명은 빌드 시스템의 프로젝트 명으로 지정된다.
Build 시스템을 설정한다. qmake / CMake / Qbs 가 있으며 나는 CMake를 사용한다.
c++ 클래스에 대해 설정해준다. QMainWindow를 상속받는 Class를 자동으로 선언해준다. 여기서 헤더 파일과 소스 파일의 이름, UI 파일의 이름을 설정해 줄 수 있다.
번역 설정이다. 추후에 Qt로 개발한 프로그램에 언어 선택 기능을 넣을 계획이 있다면 설정해 준다.
QT 버전과 컴파일러를 설정하는 화면이다. 나는 Qt 5.15.2 MinGW와 Qt 6.7.2 MinGW를 선택하였다(Windows 기준). Linux환경에서는 gcc 또는 clang을 사용한다.
프로젝트의 버전, git 연동 등을 설정하는 창이다.
2. c++ 프로젝트 템플릿 (mjlee111 qt_template)
기본적으로 생성되는 Qt Widgets Application은 개인적으로 불편한 점이 많다. QT 버전 설정, OS 설정등을 프로젝트를 생성할 때마다 진행해 주어야 하고 CMakeLists를 수정해야한다. 아래 링크에 기존의 템플릿에서 일부를 수정한 템플릿을 첨부해 두었다.
https://github.com/mjlee111/qt_template.git
GitHub - mjlee111/qt_template: QT C++ template repository. Supports Qt5, Qt6 and multi-OS
QT C++ template repository. Supports Qt5, Qt6 and multi-OS - mjlee111/qt_template
github.com
해당 템플릿의 구조는 다음과 같다.
qt_template
├── CMakeLists.txt
├── include
│ └── mainwindow.h
├── resources
│ ├── images
│ │ └── icon.png
│ └── resources.qrc
├── src
│ ├── main.cpp
│ └── mainwindow.cpp
└── ui
└── mainwindow.ui
소스 파일과 헤더 파일의 내용은 기존 템플릿과 큰 차이가 없고 CMakeLists에서 일부를 수정하였다. 수정한 내용은 아래에서 설명하겠다.
CMake 버전 설정 및 프로젝트 기본 정보
cmake_minimum_required(VERSION 3.5)
project(qt_template VERSION 1.0 LANGUAGES CXX)
# Set C++ standard
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
해당 템플릿에서는 CMake 3.5 이상의 버전, c++11을 사용하도록 하였다.
project명령어를 통해 qt_template 라고 프로젝트명을 지정해 주었고, 버전, 언어를 정의하였다. CMAKE_CXX_STANDART를 통해서 c++11표준을 설정해 주었다.
Qt6 또는 Qt5 패키지 설정
find_package(Qt6 COMPONENTS Widgets QUIET)
if(Qt6_FOUND)
set(QT_VERSION_MAJOR 6)
message(STATUS "Found Qt6: ${Qt6_VERSION}")
else()
find_package(Qt5 COMPONENTS Widgets REQUIRED)
set(QT_VERSION_MAJOR 5)
message(STATUS "Found Qt5: ${Qt5_VERSION}")
endif()
if(NOT Qt5_FOUND AND NOT Qt6_FOUND)
message(FATAL_ERROR "Qt5 or Qt6 not found. Please install Qt.")
endif()
Qt5와 Qt6는 호환성이 다르고, 다양한 환경에서 빌드가 가능하도록 위와 같이 두 버전 모두를 지원하도록 설정하였다. find_package 명령어를 통해 Qt의 설치 여부를 확인할 수 있다. 우선 최신 버전인 Qt6를 QUIET 옵션을 통해 찾도록 한 뒤, 찾지 못하면 Qt5를 REQUIRED 옵션을 통해 검색하도록 하였다. 만약 두 버전의 Qt를 찾을 수 없다면 에러를 출력하고 빌드를 중단하도록 하였다.
소스 파일 및 헤더 파일 설정
프로젝트에 사용되는 소스 파일(.c, .cpp)과 헤더 파일(.h, .hpp)을 정의하는 부분이다. src 폴더에 소스 파일을, include 폴더에 헤더 파일을 위치하였다.
# Source files
set(SOURCES
src/main.cpp
src/mainwindow.cpp
)
# Header files
set(HEADERS
include/mainwindow.h
)
# UI files
set(UI_FILES
ui/mainwindow.ui
)
# Resource file
set(RESOURCE_FILES
resources/resources.qrc
)
코드에 사용되는 소스 파일, 헤더 파일, UI 파일, 리소스 파일을 각각 SOURCES, HEADERS, UI_FILES, RESOURCE_FILES로 정의하여 CMake에 추가하였다.
MOC, UI 및 리소스 파일 처리
Qt에서는 기본적으로 MOC(Meta-Object Compiler)를 사용하여 signal, slot등의 시스템을 지원한다. qt5_wrap_cpp 또는 qt6_wrap_cpp 명령어를 사용하여 헤더 파일에 대한 MOC 파일을 생성한다.
if(QT_VERSION_MAJOR EQUAL 6)
qt6_wrap_cpp(MOC_SOURCES ${HEADERS})
qt6_wrap_ui(UIC_SOURCES ${UI_FILES})
qt_add_resources(RESOURCE_SOURCES ${RESOURCE_FILES})
else()
qt5_wrap_cpp(MOC_SOURCES ${HEADERS})
qt5_wrap_ui(UIC_SOURCES ${UI_FILES})
qt5_add_resources(RESOURCE_SOURCES ${RESOURCE_FILES})
endif()
Qt5와 Qt6의 차이를 고려하여 각각의 버전에 맞는 명령어를 사용하여 MOC 파일, UI 파일, 리소스 파일을 처리하도록 하였다.
실행 파일 생성 및 링크 설정
모든 파일들을 링크하여 최종 실행 파일을 생성한다.
add_executable(${PROJECT_NAME} ${SOURCES} ${MOC_SOURCES} ${UIC_SOURCES} ${RESOURCE_SOURCES})
# Link the appropriate Qt Widgets library
if(QT_VERSION_MAJOR EQUAL 6)
target_link_libraries(${PROJECT_NAME} Qt6::Widgets)
else()
target_link_libraries(${PROJECT_NAME} Qt5::Widgets)
endif()
add_executable 명령어로 프로젝트명과 같은 실행 파일을 생성하고, 필요한 파일들과 라이브러리들을 링크해 준다.
OS별 설정
프로젝트를 빌드하는 OS환경에 따라 각각 설정해 줘야하는 부분이 다른 경우가 잦다. 예를 들어 Windows에서는 windows.h를 사용하여 키보드 입출력을 구현할 수 있지만 리눅스에서는 X11과 같은 외부 라이브러리를 포함해 주어야한다. 아래와 같이 설정을 통해 OS별로 설정을 다르게 해줄수 있다.
if(WIN32)
# Windows-specific settings (if any)
elseif(UNIX)
# Linux-specific settings (if any)
endif()
3. Qt UI 구성 방법
QT를 통해 프로젝트를 생성하거나, qt_template를 활용하면 .ui 파일이 존재한다. 이 파일을 사용해서 UI를 구성하고 수정할 수 있다.
.ui 파일은 기본적으로 xml 형식을 사용하고 있으며 각각의 요소에 대한 설정을 할 수 있다. Qt는 xml 편집을 하지 않고 Qt Designer 프로그램 또는 Qt Creator의 Design 모드를 사용해서 UI를 편집할 수 있게 하고 있다.
좌측 패널에는 Qt에서 제공하는 UI 구성요소들, 중간에는 UI의 모습, 우측 패널에는 각각의 요소들의 설정을 할 수 있는 창이 있다. UI 구성요소들은 StyleSheet라는 CSS 형태의 스타일 설정을 지원한다. Qt의 장점 중 하나인 UI 구성 요소를 좌측 패널에서 드래그 앤 드롭으로 간단하게 사용할 수 있다.
간단한 QPushButton을 사용하는 예제를 작성해 보겠다.
QPushButton을 좌측 패널에서 드래그 해서 중앙의 UI Widget에 위치한다.
우측 패널에서 다음과 같이 버튼의 이름과 설정을 해줄수 있다.
버튼을 눌렀을 때 실행할 코드를 작성하기 위해 위에서 언급하였던 signal과 slot을 활용하게 된다. Qt는 Design 모드에서 signal과 slot을 자동으로 설정하는 기능을 제공한다. Widget에 위치하였던 QPushButton을 우클릭하면 아래와 같은 창이 나온다.
여기서 Go to slot...을 선택한다.
여기서 QPushButton에서 발행할 수 있는 signal을 선택할 수 있다. 이번 예제에서는 clicked() signal을 사용할 것이다.
clicked()를 선택하면 mainwindow.cpp, mainwindow.h 파일에 자동으로 signal과 slot이 등록된다. signal과 slot은 용어에서 알 수 있듯이 signal이 발행되면 slot이 실행되는 구조로 사용된다.
Qt에서 UI요소의 signal과 slot은 on_{구성요소이름}_{시그널명}();와 같은 형태로 선언된다.
mainwindow.cpp에 생겨난 on_start_btn_clicked()의 경우에는 start_btn이라는 이름을 가진 QPushButton에서 clicked() signal이 발생했을 때 실행되는 slot을 의미한다. Qt에서 제공하는 UI 요소들의 signal을 확인하기 위해서는 Qt Docs를 참고하면 설명이 잘 되어있는 것을 확인할 수 있다.
Qt Documentation | Home
doc.qt.io
이제 on_start_btn_clicked()에 간단한 cout 구문을 추가해서 버튼을 클릭할때마다 Hello World를 출력하게 해보겠다.
void MainWindow::on_start_btn_clicked()
{
std::cout << "Hello World" << std::endl;
}
이렇게 코드를 수정한 뒤 실행해 보면 아래와 같은 실행 결과가 나타난다.
'C, C++ > QT' 카테고리의 다른 글
[QT] v4l2 camera C++ 프로젝트 (0) | 2024.10.05 |
---|---|
[QT] 002 : QT 설치 (1) | 2024.09.25 |
[QT] 001 : QT란? (7) | 2024.09.25 |