Qt 는 원하는 GUI 를 쉽게 빠르게 구현할 수 있도록 Qt Designer 를 제공한다. QtDesigner 는 사용자가 GUI 상에 배치할 위젯을 마우스로 드래그 하면서 위젯을 배치할 수 있다.
확장자가 ui 파일인 GUI 파일은 아래 소스코드와 같이 XML 포맷으로 되어 있다. 이 파일은 사용자가 마우스를 이용해 위젯을 배치하면 Qt Creator 의 Designer 툴이 자동으로 XML 로 작성한다. 그리고 빌드를 하게 되면 XML 로 되어 있는 GUI 파일을 C++ 소스코드로 변환 후 빌드 한다.
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Widget</class>
<widget class="QWidget" name="Widget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>338</width>
<height>178</height>
</rect>
</property>
<property name="windowTitle">
<string>Widget</string>
</property>
<widget class="QWidget" name="horizontalLayoutWidget">
Qt Designer 를 이용한 예제
새프로젝트 생성 → Qt Widgets Application → CMake → Base Class : Qwidget
widget.ui 소스코드를 더블 클릭하면 Designer 화면으로 전환된다.
여기까지만 하고 출력하면 위젯이 이렇게 화면으로 출력된다.
하지만, 이 위젯은 아직 connect되지 않은 상황이기 때문에, 시그널이 발생해도 값에는 아무 변화가 없다.
slide 눈금을 움직이면 spinbox의 값이 바뀌도록 설정 하는 코드를 작성해 보겠다.
<widget.h>
#ifndef WIDGET_H // 중복 포함 방지를 위한 매크로 정의 시작
#define WIDGET_H
#include <QWidget> // QWidget 클래스 포함
// Ui 네임스페이스 안에 Widget 클래스 선언 (UI 관련 코드 자동 생성)
namespace Ui { class Widget; }
// Widget 클래스 정의 (QWidget을 상속)
class Widget : public QWidget
{
Q_OBJECT // Qt의 시그널과 슬롯을 사용하기 위해 필요한 매크로
public:
// 생성자: 부모 위젯을 선택적으로 받을 수 있음
Widget(QWidget *parent = nullptr);
// 소멸자: 메모리 해제를 처리
~Widget();
private:
// UI 구성 요소를 위한 포인터 (자동으로 생성된 ui 클래스)
Ui::Widget *ui;
private slots:
// 슬롯 함수들: 슬라이더 값이 변경되면 호출됨
void slider1_valueChanged(int value);
void slider2_valueChanged(int value);
void slider3_valueChanged(int value);
};
#endif // WIDGET_H // 중복 포함 방지를 위한 매크로 정의 끝
더보기
- #ifndef, #define, #endif: 이 매크로는 헤더 가드라고 불리며, 헤더 파일이 여러 번 포함되더라도 중복 포함을 방지합니다. WIDGET_H가 정의되어 있지 않으면, 이 헤더 파일을 포함하겠다는 의미입니다.
- Ui::Widget *ui;: 이 포인터는 Qt의 디자이너 툴에서 생성된 UI 요소를 참조하는 역할을 합니다. Qt 디자이너를 사용해 위젯을 구성하면, 자동으로 ui_widget.h 파일이 생성되는데, 이 파일에 정의된 Ui::Widget 클래스에 접근하기 위한 포인터입니다.
- 슬롯 함수 (private slots): Qt에서 **슬롯(slot)**은 특정 시그널이 발생했을 때 호출되는 함수입니다. 여기서는 세 개의 슬라이더(slider1, slider2, slider3)의 값이 변경될 때 각각 대응하는 슬롯 함수가 호출됩니다. 각각의 슬롯은 해당 슬라이더 값에 따라 스핀박스 값을 변경하는 역할을 합니다.
- private slots:를 새로 선언하고, 슬라이더의 값을 변경할 함수를 선언한다.
- widget.h 헤더파일에서 ui 를 선언한 Object 명이 있다.
- 이 오브젝트 명이 Designer 툴에서 배치한 위젯을 접근할 수 있는 접근자이다.
<widget.cpp>
#include "widget.h" // Widget 클래스 헤더 파일 포함
#include "./ui_widget.h" // Qt 디자이너로부터 생성된 UI 파일 포함
// 생성자: 부모 위젯을 선택적으로 받음, ui 객체를 초기화
Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget)
{
// UI를 설정하는 함수, ui 위젯들을 초기화
ui->setupUi(this);
// 슬라이더와 슬롯을 연결 (구 스타일, SIGNAL과 SLOT 사용)
connect(ui->slider1, SIGNAL(valueChanged(int)),
this, SLOT(slider1_valueChanged(int)));
connect(ui->slider2, SIGNAL(valueChanged(int)),
this, SLOT(slider2_valueChanged(int)));
connect(ui->slider3, SIGNAL(valueChanged(int)),
this, SLOT(slider3_valueChanged(int)));
}
// 소멸자: 동적으로 할당된 ui 포인터 삭제
Widget::~Widget()
{
delete ui; // 동적으로 할당된 ui 메모리 해제
}
// slider1의 값이 변경되었을 때 호출되는 슬롯 함수
void Widget::slider1_valueChanged(int value)
{
// slider1의 값을 spinBox1에 반영
ui->spinBox1->setValue(value);
}
// slider2의 값이 변경되었을 때 호출되는 슬롯 함수
void Widget::slider2_valueChanged(int value)
{
// slider2의 값을 spinBox2에 반영
ui->spinBox2->setValue(value);
}
// slider3의 값이 변경되었을 때 호출되는 슬롯 함수
void Widget::slider3_valueChanged(int value)
{
// slider3의 값을 spinBox3에 반영
ui->spinBox3->setValue(value);
}
더보기
- 생성자 (Widget::Widget):
- new Ui::Widget을 사용하여 ui 객체를 동적으로 할당하고, setupUi(this)를 호출하여 UI 요소를 초기화합니다. 이는 .ui 파일에서 설정된 위젯과 레이아웃을 실제 객체로 생성하는 역할을 합니다.
- connect() 함수는 슬라이더의 값이 변경되었을 때 해당 슬롯 함수를 호출하도록 시그널-슬롯 연결을 설정합니다. Qt의 구 스타일로 시그널과 슬롯을 연결할 때는 SIGNAL()과 SLOT() 매크로를 사용합니다.
- 소멸자 (Widget::~Widget):
- 동적으로 할당한 ui 객체를 삭제합니다. 이는 메모리 누수 방지를 위해 필수적인 작업입니다.
- 슬롯 함수들:
- slider1_valueChanged, slider2_valueChanged, slider3_valueChanged는 각각 슬라이더의 값이 변경될 때 호출됩니다. 전달된 값(int value)을 해당 스핀박스의 값으로 설정하는 역할을 합니다. 예를 들어, slider1의 값이 변경되면 spinBox1에 그 값이 반영됩니다.
- 위의 예제에서 한가지 주의해야 할 점은 connect( ) 함수의 인자를 Old Style 형태로사용했다는 점이다.
- 만약 New Style 을 사용하면 “no matching member function for callto ‘connect’” 라는 에러가 발생한다.
- 이런 에러가 발생하는 이유는 QSpinBox 에서제공하는 valueChanged( ) 멤버 함수는 Overloaded 된 멤버 함수로 int 형과 QString형인 두가지 멤버 함수를 제공하기 때문이다.
- Overloaded 된 시그널이 있다면 Old Style 을 사용해야 한다.
'Qt프로그램' 카테고리의 다른 글
QMainWindow 를 이용한 GUI 구현 (1) | 2024.10.08 |
---|---|
다이얼로그 (0) | 2024.10.08 |
Signal and Slot (1) | 2024.10.08 |
Layout (0) | 2024.10.08 |
Qt GUI widgets(2) (1) | 2024.10.08 |
댓글