본문 바로가기

IT/QT

[QT] 1. 다양한 위젯 사용하기 (QPushButton, QSlider, QLabel, QSpinBox)

반응형

☞  메인보드 : Jetson Nano Developer Kit

☞  운영 체제 : Ubuntu 18.04 - JetPack 4.4.1

☞  IDE : QtCreator

☞  언어 : C++

 

 

 

 

 

 

OPENCV를 연재하려는데 예전에 해봤던 것을 그냥 올리면 재미가 없기 때문에 추가로 뭘 해서 올릴까 하다가 마침 사용하는 IDE가 qtcreator 여서 QT를 처음 배워본다는 의미로,,, 겸사겸사 하기로 했다. 처음 UI를 만드는 코드를 접한 것은 Python 공부할 때 pyqt 였던 것으로 기억한다. qt이고,,, 언어가 Python이니 pyqt 겠지 싶다. 창을 몇 개 만들어봤는데 재미있었던 기억이 있다.

 

qtcreator를 다운로드하는 것은 어렵지 않다. 터미널 창에서 다운로드를 해도 괜찮고

 

 

Get Qt - Download now

With Qt, you can reach all your target platforms – desktop & embedded – with one technology and one codebase, minimizing your time-to-market and maintenance burden.

www.qt.io

여기에 가서 본인 아키텍처에 맞는 버전을 다운로드하면 된다.

 

 

 

QT를 처음에 시작하면 요래요래 나온다.(어둠 속성인 사람은 설정에 가서 다크 모드로 바꿀 수 있다.)

 

 

 

OPENCV에 써먹을 간단한 위젯을 만들 거니까 QT Widgets Application으로 선택한다.

 

 

UI 모드를 사용하면 편할 수도 있겠지만 사용하지 않겠다.

 

 

프로젝트를 만들면 왼쪽과 같은 디렉토리가 생겨나고 main 코드를 실행하면 오른쪽처럼 아무것도 없는 창 하나가 생성된다.

 

디렉터리에는 헤더 파일 하나와 소스코드 두 개가 있다.

 

헤더 파일에는 보통 사용하는 위젯의 라이브러리와 네임스페이스, 함수, 변수의 속성(public, private, protected) 등이 기록된다. 소스코드에는 메인과 클래스 코드가 있는데  메인코드는 메인답게  호출할 함수들이 있고 클래스 코드에는 헤더 파일에서 정의된 함수와 변수들이 구현되는 코드 파일이다. 처음 써보는 소프트웨어지만 안드로이드 스튜디오처럼 UI를 만든다는 점에서 흡사하기 때문에 간단한 것들은 어렵지 않게 구현할 수 있었다.

 

 


(전체 코드를 보려면 아래의 '더보기' 클릭)

더보기

1.  widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

#include <QPushButton>
#include <QRadioButton>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QStackedWidget>
#include <QGroupBox>
#include <QSlider>
#include <QLabel>
#include <QSpinBox>

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = 0);
    ~Widget();

signals:
    void valueChanged(int value);

private:
    void createRadioGroupBox(const QString &title);
    QPushButton *quitButton;
    QPushButton *inputButton;
    QGroupBox *radioGroupBox;

    QRadioButton *createRadioButton(const QString &title);
    QRadioButton *CANADIAN;
    QRadioButton *SCENESTEALAR;
    QRadioButton *YAHOSUNJONG;

    QStackedWidget stackedWidget;
    void createSliderGroupBox(int getNumber);
    QGroupBox *sliderGroupBox;
    void createControls(int setNumber, const QString &title);
    QSlider *slider;

    QGroupBox *controlsGroup;
    QLabel *minimumLabel;
    QLabel *maximumLabel;
    QLabel *valueLabel;

    QSpinBox *minimumSpinBox;
    QSpinBox *maximumSpinBox;
    QSpinBox *valueSpinBox;

};

#endif // WIDGET_H

 

2. main.cpp 

#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}

 

3. widget.cpp 

#include "widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    int maximumValue = 30;

    createControls(maximumValue, "CONTROL");
    createRadioGroupBox("PEACE MAKER MEMBER");
    createSliderGroupBox(maximumValue);

    quitButton = new QPushButton("QUIT");
    connect(quitButton, SIGNAL(clicked()), this, SLOT(close()));
    
    QGridLayout *layout = new QGridLayout;
    layout->addWidget(slider);
    layout->addWidget(quitButton);

    QHBoxLayout *controlLayout = new QHBoxLayout;
    controlLayout->addStretch();
    controlLayout->addWidget(controlsGroup);

    QHBoxLayout *radioLayout = new QHBoxLayout;
    radioLayout->addWidget(radioGroupBox);
    radioLayout->addLayout(controlLayout);
    radioLayout->addLayout(layout);
    setLayout(radioLayout);

    connect(slider, &QSlider::valueChanged, valueSpinBox, &QSpinBox::setValue);
    setWindowTitle("PEACE MAKER IDIOT BATTLE");
}

void Widget::createControls(int setNumber ,const QString &title){
    controlsGroup = new QGroupBox(title);

    minimumLabel = new QLabel("Minimum Value  ");
    maximumLabel = new QLabel("Maximum Value  ");
    valueLabel = new QLabel("Current Value  ");

    minimumSpinBox = new QSpinBox;
    minimumSpinBox->setValue(0);

    maximumSpinBox = new QSpinBox;
    maximumSpinBox->setRange(0,setNumber);
    maximumSpinBox->setSingleStep(1);

    valueSpinBox = new QSpinBox;
    valueSpinBox->setRange(0,setNumber);
    valueSpinBox->setSingleStep(1);

    QGridLayout *controlGridLayout = new QGridLayout;
    controlGridLayout->addWidget(minimumLabel,0,0);
    controlGridLayout->addWidget(minimumSpinBox,0,1);
    controlGridLayout->addWidget(maximumLabel,1,0);
    controlGridLayout->addWidget(maximumSpinBox,1,1);
    controlGridLayout->addWidget(valueLabel,2,0);
    controlGridLayout->addWidget(valueSpinBox,2,1);
    controlsGroup->setLayout(controlGridLayout);
}

void Widget::createRadioGroupBox(const QString &title){
    radioGroupBox = new QGroupBox(title);

    CANADIAN = createRadioButton("Canadian");
    SCENESTEALAR = createRadioButton("SceneStelar");
    YAHOSUNJONG = createRadioButton("YahoSunJong");

    CANADIAN->setChecked(true);

    QVBoxLayout *imgLayout = new QVBoxLayout;
    imgLayout->addWidget(CANADIAN);
    imgLayout->addWidget(SCENESTEALAR);
    imgLayout->addWidget(YAHOSUNJONG);
    radioGroupBox->setFixedSize(200,150);
    radioGroupBox->setLayout(imgLayout);
}

void Widget::createSliderGroupBox(int getNumber){
    sliderGroupBox = new QGroupBox("IDIOT INDEX");

    slider = new QSlider(Qt::Horizontal);
    slider->setTickPosition(QSlider::TicksBothSides);
    slider->setTickInterval(10);
    slider->setSingleStep(1);
    slider->setValue(0);
    slider->setMinimum(0);
    slider->setMaximum(getNumber);
}

QRadioButton *Widget::createRadioButton(const QString &title){
    QRadioButton *buttonName = new QRadioButton(title);
    return buttonName;
}

Widget::~Widget()
{
}

 

간단한 예제 느낌으로 아무 쓸모도 없는 것을 만들어 봤다... 실행하면 이런 느낌의 창이 생긴다.

 

 

빨간색 부분은 RadioButton을 초록색 부분은 SpinBox를 하늘색 부분에는 Slider와 PushButton을 사용했다. 구현에 대한 부분은 Slider를 움직였을 때 Current Value의 값이 올라가는 것 이외에 없다. 이처럼 ~를 움직였을 때(값이 바뀌면) ~도 같이 움직여하는 것은 connect로 구현할 수 있었다.

 

 

connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type=Qt::AutoConnection)

 

 

매개변수들을 간단히 보자면 connect(사건 1 발생, 사건 1 , 사건 1에 의해 발생한 사건 2, 사건 2) 이런 느낌인데,,,, 사건 1은 SIGNAL로 표현하고 사건 2는 SLOT으로 표현한다. SIGNAL과 SLOT 모두 헤더 파일에 signals와 slots로 속성 부여를 하여 직접 만들 수 있는데 SLOT은 따로 만들어서 사용하는 경우가 많을 것 같다. 

 

만들고 싶은 기능이 기본으로 QT에 내장되어 있어서 따로 만들어줄 필요는 없었다.

 

 

QPushButton quitButton = new QPushButton;
connect(quitButton, SIGNAL(clicked()), this, SLOT(close()));

QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(quitButton);
setLayout(layout);

 

 

레이아웃에는 QHBoxLayout과 QVBoxLayout이 있었다. 박스 형태의 레이아웃을 생성하는데 Horziontal(수평)인지 Vertical(수직)인지 결정해서 사용하면 된다. 각 레이아웃 안에 추가할 위젯이 있다면 화살표와 함께 addWidget으로 추가해주면 된다.

 

 

    QHBoxLayout *sliderLayout = new QHBoxLayout;
    QHBoxLayout *buttonLayout = new QHBoxLayout;
    QGridLayout *layout = new QGridLayout;
    layout->addWidget(slider);
    layout->addWidget(quitButton);

    QHBoxLayout *horizonLayout = new QHBoxLayout;
    horizonLayout->addLayout(sliderLayout);
    horizonLayout->addLayout(buttonLayout);

    QHBoxLayout *controlLayout = new QHBoxLayout;
    controlLayout->addStretch();
    controlLayout->addWidget(controlsGroup);

    QHBoxLayout *radioLayout = new QHBoxLayout;
    radioLayout->addWidget(radioGroupBox);
    radioLayout->addLayout(controlLayout);
    radioLayout->addLayout(horizonLayout);
    radioLayout->addLayout(layout);
    setLayout(radioLayout);

 

 

레이아웃에 레이아웃을 추가하고 싶다면 addLayout으로 추가할 수 있다. 

 

 

 

 

GridLayout은 행과 열의 수를 정해서 레이아웃을 형성할 수 있다.

CONTROL 레이아웃은 Label 3개와 SpinBox 3개로 이루어져 있다.

 

 

 

 

 

위젯과 달리 레이아웃은 헤더 파일에 정의할 필요 없이 소스코드에 바로 사용할 수 있다.

 

 

    QGridLayout *gridLayout = new QGridLayout;
    gridLayout->addWidget(CANADIAN,0,0);
    gridLayout->addWidget(SCENESTEALAR,1,0);
    gridLayout->addWidget(YAHOSUNJONG,2,0);
    radioGroupBox->setLayout(gridLayout);

 

미리 만들어준 GroupBox에 GridLayout을 만들어서 넣어주고 addWidget(위젯 이름, 열(세로줄), 행(가로줄)) 세 개의 매개변수에 위젯 이름과 행, 열 수를 넣어주면 레이아웃이 간단히 생성된다.

 

 

어쩌다 보니 사용한 IDE가 qtcreator라서 QT를 사용하게 됐는데 꽤 재밌기도 하고 대회나 프로젝트할 때 다른 패키지나 라이브러리와 섞어서 사용할 텐데 다른 팀원도 보기 좋게 만들 수 있는 방법을 익혀 놓으면 좋을 것 같다는 생각이 들었다.

 

 

Qt Documentation

Welcome to Qt Docs! Here you'll find documentation for Qt, a cross-platform software development framework Programming Languages Programming languages and bindings supported by Qt ---> C++ QML Python Getting Started Key Topics Solutions Qt provides tailore

doc.qt.io

 

모르거나 써보지 못한 위젯, 함수는 위 사이트에서 검색하면서 공부했다.

반응형

'IT > QT' 카테고리의 다른 글

[QT] 3. 상단 탭 추가하기 (QTapWidget)  (0) 2022.03.16
[QT] 2. QT + OPENCV  (0) 2020.12.12