2015. 8. 26. 00:24

0032 - GUI 프로그래밍 소개 / 위젯 생성과 Event 연결하기

참고 영상 (5분 이후)

지난 시간인 0031 - GUI 프로그래밍 소개 / 프로젝트 내 파일 에 이이서 진행합니다.

GUI Application 을 구성하는 파일(File) 들을 알아 보았으니 이제 GUI 를 구성하는 컨트롤(Control) 인 위젯(Widget) 을 추가하고 이벤트를 연결하는 방법에 대해서 알아 봅니다.

작업 대상은 0031 에서 작업 했었던 내용에 이어서 진행하시면 됩니다. 없다면 아래 링크(Link) 에서 받아서 진행 하시면 됩니다.

작업 파일

003_GUI_start.zip

압축을 푸신 후 pro 확장자로 된 파일을 열면 됩니다.


1. Widget 추가

파일을 열었으면 디자인(Design) 을 선택하여 Qt Designer 라 불리는 Form 편집기를 엽니다.

Design 항목 에서 Widget Box 창에 button 을 입력한 뒤 Push Button 을 마우스 클릭 한 후 놓지 말고 오른쪽으로 끌어서 QMainWindow 인 오른쪽 창 위젯 위로 옮긴 후 누른 클릭을 놓습니다. (Drag & Drop)

제대로 했다면 아래 화면 처럼 창위에 PushButton 이라는 Push Button 위젯(Widget) 이 생성됩니다.

이 상태에서 Build 를 하면 PushButton 이 보이는 채로 실행이 됩니다.

본 Design 설계를 UIC (User Interface Compiler) 라는 도구에 의해 C++ 로 변경되어서 컴파일이 되는데 컴파일 중간에 사용자가 관여 하는 부분은 없습니다.

그대신 현재 사용자가 작업하는 mainwindow.cpp 의 C++ 코드에서 위젯들의 설정 변경이 가능합니다. 이는 UIC 에서 생성한 UI::MainWindow 의 인스턴스(Instance : 클래스를 객체화하여 공간을 차지하는 변수)를 가리키는 Pointer 인 ui 를 MainWindow Class 에서 직접 참조할 수 있기 때문입니다.

따라서, 위젯을 생성하는 순간 사용자가 관여하지 않아도 QT Designer 에서 ui_mainwindow.h 파일 내에 pushButton 맴버 변수를 생성하며 PushButton 위젯 이 제공하는 매소드(맴버 함수) 들을 사용할 수 있습니다.

마우스 오른쪽 버튼을 누르고 Follow Symbol Under Cursor 를 선택하면 해당 pushButton 이 선언된 위치를 바로 찾아 갈수 있습니다.

ui_mainwindow.h 파일은 QT Project 파일 범위 밖에 있으므로 Project 탐색기에서 열수 없으며, 수정할 필요도 없습니다. 

QPushButton 에서 제공하는 메소드를 사용할 수 있으므로 pushButton 에 표시되는 내용인 Text 속성을 을 변경해 봅니다. setText 를 사용하는데, 멤버들이 모두 Pointer 로 되어 있으므로, 역참조(Pointer 에 저장된 주소에 접근한 후 실제 변수에 접근하기) 및 멤버 호출을 담당하는 연산자인 -> 를 사용합니다.

mainwindow.cpp File 을 열어서 ui->setupUi 아래 줄에 입력합니다.

ui->pushButton->setText("Hello");

-> 대신 다른 연산자를 쓰고 싶다면 아래처럼 쓰셔도 됩니다. 괄호와 역참조 연산자 그리고 멤버 참조 연산자의 우선순위로 인해 복잡해 보여서 생기는 가독성 문제로 위의 방법을 선호 합니다.

(*(*ui).pushButton).setText("Hello");

그러면 아래 Code 처럼 입력이 될 것입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include "mainwindow.h"
#include "ui_mainwindow.h"
 
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->pushButton->setText("Hello");
}
 
MainWindow::~MainWindow()
{
    delete ui;
}
 
cs

pushButton 에 마우스를 가져가면 아래 처럼 간편한 설명이 나오므로 어떤 객체인지 또는 멤버(구성원) 변수/함수(메소드) 인지 확인하는데 도움이 됩니다.

자세한 설명은 오른쪽에 나와 있는 F1 버튼을 누르면 따로 창이 나오면서 보충 설명을 해줍니다.

이제 실행 (왼쪽 아래 녹색 삼각형 버튼) 을 하면 아래와 같은 창이 나타날 것입니다.

여기 까지 오셨으면 위젯을 연결하고 해당 멤버들을 접근하는 것을 배우셨습니다.

2. Event 연결하기

Button 을 눌렀을 때 Event 가 발생하는데, 이를 처리하는 방법에 대해 알아 봅니다. QT 는 편리하게 Event 처리를 시그널과 슬롯(Signal & Slot)이라는 메커니즘을 지원합니다. 복잡해 보이지만, 실제로는 Event 처리 방식을 아주 단순화 시킨 것입니다.

위 그림에서 Hello 를 눌렀을 때 나오는 Event 는 clicked() 라는 시그널(Signal) 에 대응됩니다. 이를 받을 수 있는 슬롯(Slot) 이 있다면, 관계를 설정 후 해당 시그널이 왔을 때 처리가 가능해 질 것입니다.

자세한 설명은 Signals & Slots 소개 에서 정리되어 있습니다.


Hello 버튼은 QPushButton 에서 제공하는 시그널을 활용하고, 이를 받아서 처리하는 슬롯은 Window 인 QMainWindow 에서 제공하는 close() 슬롯을 사용할 합니다.

각각의 시그널과 슬롯은 위젯마다 다르며 이를 활용하면 특별한 코딩 없이도 시각적인 처리가 가능합니다.

QT Design 창에서 상위 Edit Signals/Slots 을 선택하여 시그널/슬롯을 연결할 수 있게 합니다.

PushButton 을 마우스를 클릭한 후 드래그 해서 MainWindow 쪽에서 마우스 클릭을 놓으면 Signal 과 Slot 관계를 정해주는 Configure Connection 창이 나타납니다.

QPushButton / QMainWindow 은 공통적으로 QWidget 에서 상속을 받았으므로, 상위 Widget 들이 제공하는 시그널과 슬롯들을 지원합니다.

아래 Show signals and slots inherited from QWidget 을 선택하여 선택지를 확장 시킵니다.

왼쪽 pushButton 이 클릭 했을 때 발생되는 시그널인 clicked() 를 선택한 후 이를 받아 들이는 MainWindow 에서는 창을 닫는 closed() 을 선택 하고 OK 를 누릅니다.

이렇게 되면 pushButton 에서 clicked() 시그널이 발생하면 Connection (연결) 관계에 있는 MainWindow 에서 close() 슬롯에게 시그널이 전달되어 그에 맞는 이벤트가 처리 됩니다.

Configure Connection 창에서 해당 연결 작업이 끝나므로 별다른 Coding 은 필요하지 않습니다. 연결이 완료 되면 아래의 창처럼 연결관계가 화면에 나타납니다.


이 상태에서는 Widget 이동 같은 편집 기능이 되지 않습니다. 대신 상단에 눌렀던 Edit Signals/Slots (F4) 왼쪽에 있는 Edit Widgets (F3) 을 선택하면 원래대로 편집이 가능해집니다.


그리고 해당 PushButton 의 Text 를 설정하는 setText 에서 "Hello" 대신에 "Close" 로 바꿔서 실제 동작에 맞는 이름으로 지정해 봅니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include "mainwindow.h"
#include "ui_mainwindow.h"
 
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //ui->pushButton->setText("Hello");
    //(*(*ui).pushButton).setText("Hello");
 
    ui->pushButton->setText("Close");
}
 
MainWindow::~MainWindow()
{
    delete ui;
}
 
cs

실행하면 나오는 Close 버튼을 누르면 Signals & Slots 의 연결 관계대로 Event 가 처리되어 응용프로그램이 정상 종료 됨을 확인할 수 있습니다.

이외에도 Progress Bar 와 같은 다양한 위젯들을 QT Designer 에서 추가로 넣을 수 있습니다.

우선 제가 동영상 내용과 동일한 선상에서 학습한 뒤 설명드리겠습니다.

완료 파일

003_GUI_end.zip