Qt 프로그램 이해

gichang·2025년 11월 10일

2526VEDA

목록 보기
2/13
post-thumbnail

=========================================================================

[ 00. 요약 ]

Qt => GUI => UX => MMI => HMI (based on C++, Widget's => class)

★ Qt 프로그래밍의 주요 개념은 크로스 플랫폼 개발, 시그널 및 슬롯 메커니즘, 객체 모델(QObject), 위젯, 그리고 QML이다. ★

★ UI 구현) Qt를 통한 것과 Web 프론트엔드 기반의 차이 ★


[ 01. 학습내용_1일차 ]

Qt 프로그래밍

1-1. 개요

"CMake" 사용, Qt Creator "IDE" 통합 개발 환경. Qt Designer
Qt Designer는 C++ 기반의 GUI를 제작하는 툴이며,
Qt Design Studio 는 QML를 작성하는 툴이다.
: (이건 강의때 사용 x)
# 참고 : 예제 프로젝트 open할 때, "CMakeLists.txt"파일 열기. (Configure Project 클릭하면 자동으로 연계 파일 열림.)

(1) Windows : ---> dos ---> GUI oriented
visual studio ---> GUI ---> button (by. mouse)
(2) Linux : bash shell ---> GUI (X11 GNome)
typing by keyboard : faster ! , more efficient !

1-2. 파일내용

a.c		int main()	{	funcb(); funcc();	}
b.c		int funcb()
c.c		int funcc()			// source 예제

$ cc -c a.c // 소스파일 compile
$ cc -c b.c
$ cc -c c.c
a.o b.o c.o // object file
$ cc a.o b.o c.o -o hello // link
hello
Makefile
how to compile
how to link... // 문법 기록
(1) make.exe <- Makefile // CMake, qmake로 분할
(2) qmake.exe // console, pro 파일 생성.
(3) cmake.exe <- CMakeLists.txt // build
-> Makefile -> make
// Build Ctrl+B, Run Ctrl+R.
qmake 형식으로 만들기
Files to be added in
D:\work\LQT6\ex1\console: // 생성파일

Files to be added in
D:\work\LQT6\ex1\widgets: // 생성파일

CMakeLists.txt
main.cpp
widget.cpp
widget.h
widget.ui		// Qwidget 기반 파일 생성

1-3. "connect 함수"에 대한 내용

1-3-1. 함수 선언.

1-3-2. Forms의 widget.ui 파일에 Design 기능 실행.

1-3-3. 생성되는 UI : Button을 누르면 애플리케이션 창에 문장이 출력된다.

# 참고 : slots로 선언되면 나중에 헷갈린다. (s 유무의 차이)

[ 02. 학습내용_2일차 ]

2-1. Qt에서 제공하는 데이터 타입과 클래스 (★ 위젯 구현 예제 ★)

2-1-1. QDateEdit 예시 (이하 widget.ui가 아니라 코드형태 구현)

: # 참고 : 하단부 "Wed Jun 26 2002, Tue Jun 26 1900"은 라벨이다.

2-1-2. QTimeEdit 예시

: # 참고 : 하단부 "03:32:00"은 라벨이다.

2-1-3. QDial 예시

: # 참고 : example 예시 06_QDial 파일 사용.
: 그래픽 ui로 구현된 다이얼을 마우스 클릭으로 돌리면, "3. Application Output"창에 QDial l value값이 변화하는 것을 확인할 수 있다. (0~100)

2-1-4. QPushButton 예시

: # 참고 : example 예시 08_QPushButton 파일 사용.
: ui에서 구현된 QPushButton의 버튼을 클릭하면, "3. Application Output"창에 'Button Released', 'Button Click' 메시지가 출력되는 것을 확인할 수 있다.

2-1-5. (*내용 중간 점검) widget.h파일과 main.cpp, 그리고 widget.cpp의 코드

: # 참고 : example 예시 09_QFontComboBox 파일 사용.

: 먼저, widget.h 파일을 보자.

: 두 번째로, main.cpp 파일을 보자.

: 마지막으로, widget.cpp 파일을 보자.

: 결론 - 09_QFontComboBox 파일을 (Ctrl+R)을 누르고 (build & run) 시행하면?

2-1-6. 예제 10_QLabel_QLCDNumber에 관하여.

: # 참고 : example 예시 10_QLabel_QLCDNumber 파일 사용.

QPixmap 클래스는 이미지를 GUI상에 랜더링 하기 위해 제공되는 API이다. QPixmap 클래스를 이용해 이미지를 QLabel 위젯의 setPixmap( ) 멤버 함수를 이용하면 GUI상에 표시할 수 있다.

2-1-7. 예제 15_QScrollArea에 관하여.

: # 참고 : example 예시 15_QScrollArea 파일 사용.

: 핵심 내용은 이미지 첨부 이후에 ui를 통해 상.하.좌.우로 스크롤 하는 것

2-1-8. 예제 16_QScrollBar 내용 (15_QScrollArea의 연장선.)

: 2-1-7에 이어서, connect 함수에 대해 중점적으로 공부해보자.
-> UI 내에서 함수끼리 연동해 움직이는 코드를 작성해야 함.

: connect 함수 밑에 정의된 value값 변경을 위한 함수.

: 최종 UI - 좌측 스크롤의 움직임에 따라 우측 Bar가 동시에 이동함.

2-1-9 예제 19_QTabWidget의 이해

: 핵심 내용은 ui의 'Browser' 탭과 'Users' 탭의 토글링이다. "Application Output"창에 Current Tab 값이 어떻게 바뀌는지에 주목해야 한다.

2-1-10 예제 20_QToolBar의 이해

: 핵심 내용은 png 이미지로 구현된 아이콘을 누를 때 각 라벨이 출력되도록 코드를 구현하는 것이다.

  • 트리거를 통해 각 라벨 출력 케이스를 나눠줘야 한다.
  • 최종 UI는 다음과 같다. (4개의 아이콘은 각각 다른 라벨을 출력한다.)

2-1-11 예제 21_QWidget의 이해 (중요)

  • 먼저, 헤더파일을 보면 접근지정자로 protected가 선언됨을 확인할 수 있다. (virtual 함수와 상속, 오버라이딩 개념이 사용될 것이다.)

# 21_Qwidget 파일의 소스코드 (widget.cpp)를 분석해보자.

#include "widget.h"
Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    edit = new QLineEdit("", this);
    edit->setGeometry(120, 20, 100, 30);
}
void Widget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);
    QString img_full_name;
    QPainter painter(this);
    img_full_name = QString(":resources/browser.png");
    QImage image(img_full_name);
    painter.drawPixmap(0, 0,
            QPixmap::fromImage(image.scaled(100, 100,
                               Qt::IgnoreAspectRatio,
                               Qt::SmoothTransformation)));
    painter.end();
}
void Widget::resizeEvent(QResizeEvent *event)
{
    Q_UNUSED(event);
    qDebug("[Resize Event call]");
    qDebug("width : %d, height : %d", this->width(), this->height());
}
void Widget::mousePressEvent(QMouseEvent *event)
{
    qDebug() << "[Mouse Press] x, y : " << event->pos();
}
void Widget::mouseReleaseEvent(QMouseEvent *event)
{
    qDebug() << "[Mouse Release] x, y : " << event->pos();
}
void Widget::mouseDoubleClickEvent(QMouseEvent *event)
{
    qDebug() << "[Mouse Double clicked] x, y : " << event->pos();
}
void Widget::mouseMoveEvent(QMouseEvent *event)
{
    qDebug() << "[Mouse Move] x, y : " << event->pos();
}
void Widget::keyPressEvent(QKeyEvent *event)
{
    qDebug("Key Press Event.");
    switch(event->key())
    {
    case Qt::Key_A :
        if(event->modifiers())
            qDebug("A");
        else
            qDebug("a");
        qDebug("%x", event->key());
    break;
    default:
    break;
    }
}
void Widget::keyReleaseEvent(QKeyEvent *event)
{
    Q_UNUSED(event);
    qDebug("Key Release Event.");
}
void Widget::focusInEvent(QFocusEvent *event)
{
    Q_UNUSED(event);
    qDebug("focusInEvent Event.");
}
void Widget::focusOutEvent(QFocusEvent *event)
{
    Q_UNUSED(event);
    qDebug("focusOutEvent Event.");
}
Widget::~Widget()
{
}
  • 최종적으로 코드로 구현된 ui는 아래와 같다. (지금까지 공부한 예제 중 가장 집약적이고 복합적이라고 생각이 된다.)

2-2. Container Class

2-2-1. < 컨테이너 클래스란? >

목적 : 다양한 타입의 데이터를 저장하기 위한 클래스 세트

특징 : STL 컨테이너보다 더 가볍고 안전하며 사용하기 쉬운 편

(예시) : QList<Qstring>은 크기 조정이 가능한 QString 배열을 생성할 때 사용

2-3. Signal and Slot

2-3-1. < 시그널과 슬롯이란? >

시그널 : 객체가 이벤트를 알리기 위해 발송하는 메시지 (클래스 내부에서 정의하며, 특정 조건이 만족될 때 emit 키워드를 사용하여 발송) 함수처럼 호출되지만, 직접 실행되지 않고 연결된 슬롯을 호출

슬롯 : 시그널을 수신하여 동작하는 함수 (시그널이 발생하면 슬롯이 호출되어 특정 작업을 수행) connect 함수를 통해 특정 시그널과 슬롯을 연결

[ 03. 학습내용_3일차 ]

3-0. Layout

3-0-1. 예제 ch06 : 00_Layout 내용

3-1. (Qt에서 제공하는 데이터 타입과 클래스) ---- ... C++ 클래스 라이브러리 공부가 더 중요 ... ----

3-1-2.

3-1-3.

3-2. Qt Designer를 이용한 GUI 설계

3-2-1. 예제 ch10 : 00_Designer 파일

  • Qt Designer 는 사용자가 GUI상에 배치할 위젯을 마우스로 드래그 하면서 위젯을 배치할 수 있다. (code로 구현할 필요가 없다.)
  • 확장자가 ui 파일인 GUI 파일은 XML 포맷으로 되어 있다. 이 파일은 사용자가 마우스를 이용해 위젯을 배치하면 Qt Creator 의 Designer 툴이 자동으로 XML 로 작성한다.

    그리고 빌드를 하게 되면, XML 로 되어 있는 GUI 파일을 C++ 소스코드로 변환한 후에 진행하게 된다.

  • 이 예제도 마찬가지로 connect 함수가 중요하다.
    # 참고 : (widget.cpp) 파일 코드 내용
  • 위와 같은 코드와 Qt Designer로 구현된 UI는 붉은색 네모 창과 같다.

3-2-2. (*짚고 넘어가기) connect 함수에 대한 이해.

  • Qt 프로그래밍에서 connect 함수는 시그널(Signal)과 슬롯(Slot) 메커니즘의 핵심으로, 객체 간의 통신을 가능하게 하는 역할. 특정 이벤트(시그널)가 발생했을 때, 미리 지정된 함수(슬롯)가 자동으로 호출되도록 연결. 이는 객체들이 서로의 구현을 알지 못한 채 느슨하게 결합하여 통신할 수 있도록 함. (Observer 패턴 구현).

    *매개변수*에 대한 내용을 제대로 확인해야 한다.
  • static 멤버함수에 대한 내용.

3-3. 다이얼로그

3-3-1.

3-4. QMainWindow를 이용한 GUI 구현

# 지금까지 다룬 방식은 QWidget 을 이용해 한 개의 윈도우 화면만 존재하는 방식으로 GUI를 구성.

  • 복잡한 윈도우 GUI를 구현해야 한다면 QMainWindow와 더불어 QMdiArea 클래스를 함께 사용하는 것을 권장.
  • ( ex ) Menu Bar, Toolbars, Status Bar, Dock Widget, Central Widget 등으로 위젯들을 특정 영역에 배치할 수 있다.
    (우리 실습 수준에서는 MDI까지는 사용하지 않는다.)

3-5. Stream (데이터를 특정 변수에 Write/Read 를 쉽게 하기 위한 방법)

  • quint32 타입(4 Bytes)의 변수 데이터를 QByteArray 에 Write/Read 해야 하는 경우, Qt 에서 제공하는 QDataStream 또는 QTextStream 을 사용하면 쉽게 핸들링 가능.
    • QDataStream 은 Binary 데이터를 Write/Read 하는데 사용.
    • QTextStream 은 Text기반의 데이터를 Write/Read 하는데 사용.

3-5. 파일입출력

3-5-1.

3-5-2.

3-5-3.

[ 04. 학습내용_4일차 ]

4-1. QPainter 클래스를 이용한 2D 그래픽스

  • Qt는 GUI 위젯 영역에 QPainter 클래스를 이용해 텍스트, 선(Line), 도형을 표시할 수 있다.
  • 기본적인 드로잉 기능 이외에 QImage, QPixmap, QPicture 클래스를 이용해 이미지파일을 위젯 영역에 표시할 수 있다.
  • Gradients, Transformation, Composition 등과 같은 효과를 QPainter 영역에 적용할 수 있다.

4-1-1. ch17 : "QPaint" 예제에 관하여.

# 참고 : MiterJoin, BevelJoin, RoundJoin은 목수의 건축용어이다.

  • 01_QPen
  • 02_QBrush + 03_Gradients
  • 04_Transform
  • 05_CustomButton >> 이 때, connect 함수에 조금 더 집중해보자.
  • 06_CustomBackgroundWidget>> 생성되는 위젯은 다음과 같다. ( Hello world 버튼을 클릭했을 때, Application Output창에 출력되는 내용도 확인하기.)

4-1-2. ch18 : 00_Chromakey 예제

4-2. Timer (자주 쓰임.)

  • Qt에서 타이머는 특정 시간이 지난 후 코드를 실행하거나, 지정된 간격으로 코드를 반복적으로 실행하는 데 사용됨.
    • 주로 UI 업데이트, 주기적인 데이터 확인, 애니메이션 등에 활용되며, QTimer 클래스가 이 기능을 제공.

📝 활용 예시: 주기적인 UI 업데이트 : 이 예시는 QTimer를 사용하여 1초(1000ms)마다 라벨에 현재 시간을 업데이트 함.

(1) 헤더파일 (.h) 설정

#include <QTimer>
#include <QLabel>
#include <QWidget>
class TimerExampleWidget : public QWidget
{
    Q_OBJECT
public:
    TimerExampleWidget(QWidget *parent = nullptr);
private slots:
    void updateTime(); // 👈 timeout() 시그널과 연결될 슬롯
private:
    QTimer *timer;     // 👈 QTimer 객체 포인터
    QLabel *timeLabel; // 👈 시간을 표시할 라벨
};

(2) 구현파일 (.cpp) 설정

#include "timerexamplewidget.h"
#include <QDateTime>
#include <QVBoxLayout>
TimerExampleWidget::TimerExampleWidget(QWidget *parent)
    : QWidget(parent)
{
    // UI 초기화
    timeLabel = new QLabel("시간 표시 대기...");
    timeLabel->setAlignment(Qt::AlignCenter);
    timeLabel->setStyleSheet("font-size: 24px;");
    QVBoxLayout *layout = new QVBoxLayout(this);
    layout->addWidget(timeLabel);
    // QTimer 객체 생성
    timer = new QTimer(this);
    // 1️⃣ 간격 설정 (1000ms = 1초)
    timer->setInterval(1000); 
    // 2️⃣ 시그널-슬롯 연결
    // timer가 timeout() 시그널을 방출할 때마다 this->updateTime() 슬롯 호출
    connect(timer, &QTimer::timeout, this, &TimerExampleWidget::updateTime);
    // 3️⃣ 타이머 시작
    timer->start(); 
    // 초기 시간 업데이트 (시작 시 즉시 표시)
    updateTime();
}
void TimerExampleWidget::updateTime()
{
    // 현재 시스템 시간을 가져와 라벨에 설정
    QDateTime currentTime = QDateTime::currentDateTime();
    QString timeString = currentTime.toString("yyyy-MM-dd hh:mm:ss");
    timeLabel->setText(timeString);
}

4-3. Thread Programming

- "scheduler" --> processor : core

1) process : Unix, Linux
light weight process == thread == pthread @user / kthread kernel.
2) Thread safe function
전역변수 vs 지역변수 -- 사용하면 안 되는 경우 존재.
: 전역변수 사용 X, 스택 변수 사용 O + 동기화 객체 사용.
메모리 구조중, DATA, BSS, COMMON, STACK 적재 어디? (+) auto 변수

4-4. 예제 02_QtConcurrent에 관한 내용.

  • QtConcurrent를 RUN하면 출력창에 메시지가 나온다.

4-5. DataBase Programming

💾 Qt 프로그래밍과 데이터베이스 (Database) 연동

Qt는 Qt SQL 모듈을 통해 데이터베이스 연동을 매우 강력하고 편리하게 지원한다. 이 모듈을 사용하면 SQL 문을 직접 실행할 수 있을 뿐만 아니라, 데이터베이스의 데이터를 GUI 위젯에 직접 연결하여 표시하고 수정하는 기능을 제공하여 개발 생산성을 크게 높일 수 있다.

[ 05. 학습내용_5일차 ]

5-1. Qt Graphics View Framework

5-1-1. ShapeDetection 예제에 관한 내용.

  • 설정해준 네모 박스를 마우스 클릭으로 이동하면, 박스끼리 충돌 과정에서 색깔이 변하게 된다.

5-1-2. Animation Framework and State Machine

5-2. Qt Chart (Line, Area, Bar, Pie)

  • 코드 내용
  • view에 표시되는 차트의 UI는 다음과 같다. (Line, Area, Bar, Pie)
    -> 각 차트마다 코드가 어떤 부분에서 변했는지 점검하기.

5-4. Qt Data Visualization (Bar, Scatter, Surface, Contour)

  • 먼저, "Qt Maintainence Tool"을 통해 업데이트를 해줘야 한다.
  • Qt Data Visualization을 실행하려면 Maintenance Tool에서:
    - MaintenanceTool 실행
    - Add or remove components
    - 현재 사용 중인 Qt 버전 선택
    - Qt Data Visualization 체크
    - 설치 실행

Bar 코드의 예시.

  • (Bar, Scatter, Surface, Contour)

5-5. Multimedia

5-5-1. Audio

5-5-2. Video

5-5-3. Camera


[ 06. 느낀 점 ]

# 6-1. Qt Creator를 처음 접하고 사용해봤는데, Visual Studio로 직접 (C/C++) 코딩을 하는 것보다 낯설게 느껴졌다.

# 6-2. 그러나, Qt Creator를 통해 Design ui를 구현하는 일도 결국 C++프로그래밍 역량이 중요한 것임을 느꼈다. (C++기본 문법의 이해와 상속, virtual 함수와 다형성의 개념이 매우 중요하다.)

# 6-3. 아무리 잘 구현된 코드라고 하더라도, 미감이 취약하거나 사용자가 직접 접했을 때 ui나 ux 등의 결함이 많다면 가치가 떨어진다는 것을 항상 염두해야 한다.

# 6-4 예제를 통해 widget 코드를 구현할 때도 C++ 문법과 클래스 세부 정의, 헤더파일과 소스코드의 메모리 접근 메커니즘을 확실히 알아야 한다.

# 6-5 실제로 현업에서 사용되는 Embedded Edge device에서 Qt로 만들어진 UI가 있다면 직접 보고싶었다. 그리고 어떤 클래스 함수가 적용됐는지 궁금했다.

# 6-6 QCreator 프로그램을 사용하면서, 기본으로 제공되는 클래스와 매개변수 등을 온전히 이해하면서 막힘없이 코드로 구현하는 게 과연 가능할 수 있을지 막막했다.

# 6-7 실습평가를 잘 수행하려면, 반드시 따로 시간을 내어 Qt 대표 예제와 핵심 개념 그리고 C++ 클래스 공부를 추가로 해야겠다고 생각했다.


[ 07. 더 알고싶은 내용 ]

# Camera Vision 분야를 뿌리로 시작해서 파생되는 기술들 + 유망 산업군

# 7-0. Qt Creator로 ui를 구현하면 임베디드 시스템에만 쓰이는가? Web Front End 기반 ui 구현과 어떤 차이점이 있는지.

# 7-1. 향후 Camera Vision Detection에 Qt ui를 연동하는 원리.

# 7-2. QtCreator 프로그램에 내장된 기본 클래스 라이브러리의 C++코드 상세 해석. (특히 각 함수의 매개변수에 대한 이해.)

# 7-3. 실제 HW 단의 메모리 접근 및 제어를 더욱 명확하고 체계적으로 하는 방법.

# 7-4. 이미지를 GUI상에 랜더링 하기 위해 제공되는 API의 세부 내용.

# 7-5. NPU와 임베디드 프로그래밍 산업 + Robotics (Physical AI) 분야에 대한 개괄적 이해.

# 7-6 임베디드 프로그래밍 과정에서 PCB를 연동하려면, 전자 회로도는 얼마나 구체적으로 분석할 수 있어야 하는가?(아날로그와 디지털 회로도 구분)

# 7-7 운영체제와 네트워크 중, 임베디드 rtsp 분야 RTSP(Real-Time Streaming Protocol)


0개의 댓글