qmake/CMake
qmake란?
qmake는 Qt에서 제공하는 기본 빌드 시스템입니다. Qt 프로젝트를 쉽게 설정하고 빌드할 수 있도록 설계되었습니다.
- Qt에 최적화됨: qmake는 Qt 라이브러리와 통합되어 있으며, Qt에서 제공하는 기능을 자동으로 처리합니다. 예를 들어, MOC(Meta-Object Compiler), UIC(User Interface Compiler) 등을 qmake가 알아서 처리합니다.
- 사용법이 간단함: Qt 프로젝트를 위한 *.pro 파일을 작성하여 qmake를 실행하면, 그에 맞는 Makefile이 생성되고 빌드가 가능합니다.
- Qt 중심의 프로젝트에 적합: qmake는 Qt 프로젝트 전용 도구이므로, 비(非) Qt 라이브러리와 혼합한 복잡한 프로젝트에서는 적합하지 않을 수 있습니다.
- 멀티플랫폼 지원: qmake도 다양한 플랫폼을 지원하지만, 주로 Qt 중심으로 사용됩니다.
CMake란?
CMake는 범용 빌드 시스템으로, Qt뿐만 아니라 다양한 라이브러리와 함께 사용할 수 있는 빌드 도구입니다. CMake는 점점 더 많은 Qt 프로젝트에서 사용되고 있으며, 특히 최신 Qt 6 버전에서는 CMake가 권장되는 빌드 도구로 자리 잡았습니다.
- 더 범용적: CMake는 Qt뿐만 아니라 다양한 다른 라이브러리나 프레임워크도 쉽게 통합할 수 있습니다. 따라서 복잡한 프로젝트나 Qt 이외의 여러 라이브러리와의 연동이 필요한 경우 매우 유용합니다.
- 유연성: CMake는 매우 유연한 설정이 가능하며, 크로스 플랫폼 프로젝트 설정에 강점이 있습니다.
- 모듈화 및 확장성: CMake는 더 복잡한 프로젝트를 다루기 위한 다양한 모듈과 확장이 가능하며, 큰 프로젝트에서 유용합니다.
- Qt 지원 강화: CMake는 Qt 5 및 Qt 6에 대한 모듈을 제공하며, 이를 통해 MOC, UIC, QRC 등의 자동 처리를 지원합니다.
주요 차이점
- 목적: qmake는 Qt에 특화된 빌드 도구인 반면, CMake는 범용 빌드 도구입니다.
- 확장성: CMake는 비 Qt 라이브러리와 함께 더 쉽게 사용할 수 있으며, 다양한 빌드 설정에 대해 더 높은 유연성을 제공합니다.
- Qt 6에서의 권장 도구: Qt 6부터는 qmake 대신 CMake를 사용하는 것이 권장됩니다.
언제 무엇을 선택해야 할까?
- 작고 간단한 Qt 프로젝트를 빠르게 만들고 싶다면 qmake를 사용하는 것이 편할 수 있습니다.
- 복잡한 프로젝트나 다양한 라이브러리와의 연동이 필요한 경우 CMake가 더 적합합니다. 특히, 최신 Qt 6을 사용하는 경우 CMake 사용을 권장합니다.
CMake 를 이용한 Console 어플리케이션 구현
- CMake를 이용해 Console 어플리케이션을 구현해 보도록 하자. 여기서 Console 어플리케이션은 GUI 가 없는 어플리케이션을 의미한다.
- CMakeList.txt 는 이 프로젝트의 빌드하기 위한 프로젝트 파일이다.
#include <QCoreApplication>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug("Hellow world.");
return a.exec();
}
- 첫 번째 QCoreApplication a(argc, argv) 는 필수로 main( ) 함수의 인자인 argc, argv 를 넘겨줘야 한다.
- 지금 실행하는 응용 어플리케이션이 Console 이므로 QCoreApplication이지만 만약, GUI 기반의 어플리케이션인 경우 QGuiApplication를 사용해야 한다.
- qDebug() 는 메시지를 출력한다. 따라서 Console 창에 Hello world.를 출력한다. 마지막 라인은 프로그램이 종료되지 않도록 해주는 역할을 한다.
CMake 를 이용한 GUI 어플리케이션 구현
새프로젝트 생성 → Qt Widget Application → 프로젝트이름/위치 설정 → CMake → Base Class 로 QWidget
widget.ui 파일을 더블 클릭하면 아래 그림에서 보는 것과 같은 화면을 볼 수 있다. 아래 화면에서 QLabel 을 배치하고 그 위젯에 내용을 Hello World 로 바꾼 후 실행해 보도록 하자.
<결과>
- 그럼, 위와 같은 위젯이 생성된다.
- 지금까지 GUI 를 UI Designer를 이용했다. 확장자가 ui 인 파일을 사용할 수도 있지만, ui 파일을 사용하지 않고도 직접 소스코드를 작성하는 방식으로 GUI 코드를 작성할 수있다.
Widget 클래스
main.cpp 에서 Widget 클래스 인스턴스를 생성하고 실행한다.
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
Widget 클래스의 헤더 파일에 보면 private 키워드에 ui 인스턴스가 있는 것을 확인 할수 있을 것이다.
<#include "widget.h"헤더파일>
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
- ui_widget.h 는 uic 가 확장자가 .ui 인 파일을 기반으로 자동으로 소스코드로 변환해 ui_widget.h 파일을 만들어 준다.
- 여기서 단순히 QLabel 을 사용했지만 나중에 복잡한 GUI 를 만들고 해당 이벤트를 처리해주면 된다.
- 예를 들어 GUI 상에서 버튼을 배치하고 버튼을 처리하는 함수를 Widget 클래스 상에서 처리하는 함수를 만들면 된다.
qmake 를 이용한 Console 어플리케이션 구현
새프로젝트 생성 → Qt Consol Application → 프로젝트이름/위치 설정 → qmake
<예제 1>
#include <QCoreApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug() << "Hello world";
return a.exec();
}
<예제 2>
#include <QCoreApplication>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug("Hellow world.");
return a.exec();
}
<결과>
Hello world.
Qt GUI Widgets
qmake 를 이용한 GUI 어플리케이션 구현
새프로젝트 생성 → Qt Widget Application → 프로젝트이름/위치 설정 → qmake → Base Class 로 QWidget
- 프로젝트 생성을 완료하면 위와 같이 소스코드들이 자동으로 생성될 것이다.
- main.cpp 소스코드에서 Widget 이라는 클래스인스턴스를 생성한다.
- 그리고 이 인스턴스의 GUI를 보이기 위해서 show( ) 함수를 호출한다.
- Widget 클래스는 GUI를 구현하기 위한 클래스를 Qt Creator 에서 자동으로 생성해준 클래스이다.
- 그리고 widget.ui 파일도 생성된 것을 확인할 수 있을 것이다. 이 파일은 Qt 에서 제공하는 Qt Designer 툴로 쉽게 마우스로 GUI 위젯들을 드래그해 GUI상에 배치할 수 있다.
- Qt Designer 툴로 배치한 Widget들의 위치 및 특성 정보를 widget.ui 파일에 저장한다. 파일의 형식은 XML이다.
이 파일은 나중에 컴파일 시, Qt가 자동으로 C++ 소스코드로 변환해 준다. widget.ui 는 Widget 클래스와 매핑 되어 있으며 여기서는 클래스 이름과 ui 파일의 이름은 동일하게 저장되어 있지만, 동일하지 않아도 된다. - 또한 여기서는 1개의 ui 파일만 존재하지만 2개 이상의 GUI를 가질 수 도 있다. 예를들어 한 개의 클래스는 여러 개의 ui 파일과 매핑 할 수 있다.
- 여기서 widget.ui 파일을 더블 클릭하면 Qt Designer 가 Qt Creator 창에서 자동으로 실행된다.
- 위의 그림에서 보는 것과 왼쪽 Button 탭에서 Push Button을 마우스로 드래그해 화면에 배치한다. 그리고 버튼의 이름을 위의 그림에서 보는 것과 같이 “Hello world” 로 변경한다.
- 그리고 위의 버튼의 고유한 이름을 변경할 수 있다. 이 인스턴스의 고유한 이름은 우측상단에 표시된다.
- 여기서는 이름을 “kwak”로 하고 ui 파일을 저장(Ctrl + S) 한다. 그리고 Qt Creator 창의 왼쪽에 [Edit] 아이콘을 클릭해 소스코드 창으로 화면을 전환한다.
<widget.h>
소스코드 버튼을 클릭하면 호출되는 Slot 함수(이벤트)를 아래와 같이 작성한다.
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui
{
class Widget;
}
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
Ui::Widget *ui;
private slots: //private에 slots함수 생성
void slot_clicked();
};
#endif // WIDGET_H
<widget.cpp>
이 함수에서는 “Hello world” 를 출력하기 위해서 Qt 에서 제공하는 함수를 사용해 보자. widget.cpp 파일 상단에 QDebug 헤더를 include 한다. 그리고 slot_clicked( ) 함수상에 “Hello world”를 출력하는 소스코드를 작성해 보자.
#include "widget.h"
#include "ui_widget.h"
#include <QDebug> //qt에서 제공하는 함수를 사용하기 위한 헤더파일
void Widget::slot_clicked()
{
qDebug() << "Hello world"; //qt함수 출력문
}
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
connect(ui->kwak, SIGNAL(clicked()), this, SLOT(slot_clicked())); //connect()함수를 이용해 slot함수와 slot_clicked를 연결
}
Widget::~Widget()
{
delete ui;
}
- 위의 connect( ) 함수의 첫 번째 인자는 시그널을 발생하는 오브젝트이다.
- 이 오브젝트의 고유한 이름은 Qt Designer 에서 정의하였다.
- 두 번째 인자는 시그널을 발생하는 종류이다. 클릭, 더블 클릭, 클릭 후 해제 했을 때등 여러 개의 시그널이 존재한다. 여기서는 이 버튼을 클릭했을 때 발생하는 시그널을 명시한다.
- 세 번째 인자는 이 시그널과 연결할 Slot 함수가 있는 인스턴스명을 입력한다. 여기서는 자기 자신을 명시하기때문에 this 을 입력하였다.
- 마지막인자는 호출 할 Slot 함수를 명시한다. 여기서는 slot_clicked( ) 함수를 명시한다.
<결과>
버튼을 누를 때 마다 터미널 창에 Hello world가 입력된다.
'Qt프로그램' 카테고리의 다른 글
Qt Designer 를 이용한 GUI 설계 (3) | 2024.10.08 |
---|---|
Signal and Slot (1) | 2024.10.08 |
Layout (0) | 2024.10.08 |
Qt GUI widgets(2) (1) | 2024.10.08 |
Qt GUI Widgets (0) | 2024.10.07 |
댓글