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



"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 !
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 기반 파일 생성



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

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

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

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

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

: # 참고 : example 예시 09_QFontComboBox 파일 사용.
: 먼저, widget.h 파일을 보자.
: 두 번째로, main.cpp 파일을 보자.
: 마지막으로, widget.cpp 파일을 보자.
: 결론 - 09_QFontComboBox 파일을 (Ctrl+R)을 누르고 (build & run) 시행하면?
: # 참고 : example 예시 10_QLabel_QLCDNumber 파일 사용.
QPixmap 클래스는 이미지를 GUI상에 랜더링 하기 위해 제공되는 API이다. QPixmap 클래스를 이용해 이미지를 QLabel 위젯의 setPixmap( ) 멤버 함수를 이용하면 GUI상에 표시할 수 있다.

: # 참고 : example 예시 15_QScrollArea 파일 사용.
: 핵심 내용은 이미지 첨부 이후에 ui를 통해 상.하.좌.우로 스크롤 하는 것

: 2-1-7에 이어서, connect 함수에 대해 중점적으로 공부해보자.
-> UI 내에서 함수끼리 연동해 움직이는 코드를 작성해야 함.
: connect 함수 밑에 정의된 value값 변경을 위한 함수.
: 최종 UI - 좌측 스크롤의 움직임에 따라 우측 Bar가 동시에 이동함.
: 핵심 내용은 ui의 'Browser' 탭과 'Users' 탭의 토글링이다. "Application Output"창에 Current Tab 값이 어떻게 바뀌는지에 주목해야 한다.
: 핵심 내용은 png 이미지로 구현된 아이콘을 누를 때 각 라벨이 출력되도록 코드를 구현하는 것이다.
- 트리거를 통해 각 라벨 출력 케이스를 나눠줘야 한다.
- 최종 UI는 다음과 같다. (4개의 아이콘은 각각 다른 라벨을 출력한다.)
- 먼저, 헤더파일을 보면 접근지정자로 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는 아래와 같다. (지금까지 공부한 예제 중 가장 집약적이고 복합적이라고 생각이 된다.)
목적 : 다양한 타입의 데이터를 저장하기 위한 클래스 세트
특징 : STL 컨테이너보다 더 가볍고 안전하며 사용하기 쉬운 편
(예시) : QList<Qstring>은 크기 조정이 가능한 QString 배열을 생성할 때 사용
시그널 : 객체가 이벤트를 알리기 위해 발송하는 메시지 (클래스 내부에서 정의하며, 특정 조건이 만족될 때 emit 키워드를 사용하여 발송) 함수처럼 호출되지만, 직접 실행되지 않고 연결된 슬롯을 호출
슬롯 : 시그널을 수신하여 동작하는 함수 (시그널이 발생하면 슬롯이 호출되어 특정 작업을 수행) connect 함수를 통해 특정 시그널과 슬롯을 연결
- Qt Designer 는 사용자가 GUI상에 배치할 위젯을 마우스로 드래그 하면서 위젯을 배치할 수 있다. (code로 구현할 필요가 없다.)
- 확장자가 ui 파일인 GUI 파일은 XML 포맷으로 되어 있다. 이 파일은 사용자가 마우스를 이용해 위젯을 배치하면 Qt Creator 의 Designer 툴이 자동으로 XML 로 작성한다.
그리고 빌드를 하게 되면, XML 로 되어 있는 GUI 파일을 C++ 소스코드로 변환한 후에 진행하게 된다.
- 이 예제도 마찬가지로 connect 함수가 중요하다.
# 참고 : (widget.cpp) 파일 코드 내용
- 위와 같은 코드와 Qt Designer로 구현된 UI는 붉은색 네모 창과 같다.
- Qt 프로그래밍에서 connect 함수는 시그널(Signal)과 슬롯(Slot) 메커니즘의 핵심으로, 객체 간의 통신을 가능하게 하는 역할. 특정 이벤트(시그널)가 발생했을 때, 미리 지정된 함수(슬롯)가 자동으로 호출되도록 연결. 이는 객체들이 서로의 구현을 알지 못한 채 느슨하게 결합하여 통신할 수 있도록 함. (Observer 패턴 구현).
*매개변수*에 대한 내용을 제대로 확인해야 한다.
- static 멤버함수에 대한 내용.
# 지금까지 다룬 방식은 QWidget 을 이용해 한 개의 윈도우 화면만 존재하는 방식으로 GUI를 구성.
- 복잡한 윈도우 GUI를 구현해야 한다면 QMainWindow와 더불어 QMdiArea 클래스를 함께 사용하는 것을 권장.
- ( ex ) Menu Bar, Toolbars, Status Bar, Dock Widget, Central Widget 등으로 위젯들을 특정 영역에 배치할 수 있다.
(우리 실습 수준에서는 MDI까지는 사용하지 않는다.)
- quint32 타입(4 Bytes)의 변수 데이터를 QByteArray 에 Write/Read 해야 하는 경우, Qt 에서 제공하는 QDataStream 또는 QTextStream 을 사용하면 쉽게 핸들링 가능.
- QDataStream 은 Binary 데이터를 Write/Read 하는데 사용.
- QTextStream 은 Text기반의 데이터를 Write/Read 하는데 사용.
- Qt는 GUI 위젯 영역에 QPainter 클래스를 이용해 텍스트, 선(Line), 도형을 표시할 수 있다.
- 기본적인 드로잉 기능 이외에 QImage, QPixmap, QPicture 클래스를 이용해 이미지파일을 위젯 영역에 표시할 수 있다.
- Gradients, Transformation, Composition 등과 같은 효과를 QPainter 영역에 적용할 수 있다.
# 참고 : MiterJoin, BevelJoin, RoundJoin은 목수의 건축용어이다.
- 01_QPen
- 02_QBrush + 03_Gradients
- 04_Transform
- 05_CustomButton
>> 이 때, connect 함수에 조금 더 집중해보자.
- 06_CustomBackgroundWidget
>> 생성되는 위젯은 다음과 같다. ( Hello world 버튼을 클릭했을 때, Application Output창에 출력되는 내용도 확인하기.)
- 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); }
- "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 변수
- QtConcurrent를 RUN하면 출력창에 메시지가 나온다.
💾 Qt 프로그래밍과 데이터베이스 (Database) 연동
Qt는 Qt SQL 모듈을 통해 데이터베이스 연동을 매우 강력하고 편리하게 지원한다. 이 모듈을 사용하면 SQL 문을 직접 실행할 수 있을 뿐만 아니라, 데이터베이스의 데이터를 GUI 위젯에 직접 연결하여 표시하고 수정하는 기능을 제공하여 개발 생산성을 크게 높일 수 있다.
- 설정해준 네모 박스를 마우스 클릭으로 이동하면, 박스끼리 충돌 과정에서 색깔이 변하게 된다.
- 코드 내용
- view에 표시되는 차트의 UI는 다음과 같다. (Line, Area, Bar, Pie)
-> 각 차트마다 코드가 어떤 부분에서 변했는지 점검하기.
- 먼저, "Qt Maintainence Tool"을 통해 업데이트를 해줘야 한다.
- Qt Data Visualization을 실행하려면 Maintenance Tool에서:
- MaintenanceTool 실행
- Add or remove components
- 현재 사용 중인 Qt 버전 선택
- Qt Data Visualization 체크
- 설치 실행
Bar 코드의 예시.
- (Bar, Scatter, Surface, Contour)
5-5-1. Audio
5-5-2. Video
5-5-3. Camera
# 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++ 클래스 공부를 추가로 해야겠다고 생각했다.
# 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)