Qt프로그램

Qt GUI Widgets

Barbarian developer 2024. 10. 7.

Qt 에서 Widget 은 버튼, 체크박스, 라디오 버튼 등을 Widgets 이라고 한다. 따라서
이번 장에서는 Qt에서 제공하는 Widget들에 대해서 다루어 보도록 하자.


QCheckBox 와 QButtonGroup


QCheckBox 와 QButtonGroup 를 이용한 예제를 작성해 보도록 하자. 이번 예제에서는QCheckBox 에서 이미지 리소스를 사용하는 방법도 함께 알아보도록 하자.

 

프로젝트생성→QWidget Application→qmake→Base class QWidget→Generage form항목 체크 해제

 

<widget.h>

#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QCheckBox>
#include <QButtonGroup>
class Widget : public QWidget
{
	Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
private:	//오브젝트 선언 부분
    QButtonGroup *m_chk_group[2];
    QCheckBox *m_exclusive[3];
    QCheckBox *m_non_exclusive[3];

private slots:	//시그널을 처리할 함수 선언.
	void slot_chkChanged();
};
#endif // WIDGET_H
  • 위에서 보는 것과 같이 QButtonGroup 과 QCheckBox 오브젝트를 선언한다. 
  • 그리고 시그널(이벤트)을 처리할 slot_chkChanged( ) 함수를 선언한다.
  • 이 Slot 함수는 QCheckBox에서 발생한 시그널을 처리하는 함수이다. Slot 함수를 선언하기 위해서는 접근 제한자(private 또는 public) 과 “slots” 라는 키워드를 선언해야 한다.

<widgets.cpp>

#include "widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    QString str1[3] = {"Game", "Office", "Develop"};
    QString str2[3] = {"P&rogramming", "Q&t", "O&S"};
    int xpos = 30;
    int ypos = 30;
    m_chk_group[0] = new QButtonGroup(this);
    m_chk_group[1] = new QButtonGroup(this);
    for(int i = 0 ; i < 3 ; i++)
    {
        m_exclusive[i] = new QCheckBox(str1[i], this);
        m_exclusive[i]->setGeometry(xpos, ypos, 120, 30);
        m_chk_group[0]->addButton(m_exclusive[i]);
        m_non_exclusive[i] = new QCheckBox(str2[i], this);
        m_non_exclusive[i]->setGeometry(xpos + 120, ypos, 120, 30);
        m_chk_group[1]->addButton(m_non_exclusive[i]);
        connect(m_exclusive[i], SIGNAL(clicked()),
                this,
                SLOT(slot_chkChanged ()));
        ypos += 40;
    }
    m_chk_group[0]->setExclusive(false);
    m_chk_group[1]->setExclusive(true);
}
void Widget::slot_chkChanged()
{
    for(int i = 0 ; i < 3 ; i++)
    {
        if(m_exclusive[i]->checkState())
        {
            qDebug("checkbox %d selected ", i+1);
        }
    }
}
Widget::~Widget()
{
}

<결과>

  • 왼쪽의 Game, Office, Develop 항목과 오른쪽의 Programming, Qt, OS 은 QButtonGroup으로 분리하였다. 
  • 왼쪽의 QCheckBox 항목은 다중 선택이 가능하지만 오른쪽 항목은 다중 선택이 불가능 하도록 구현 하였다. 
  • 다중 선택이 불 가능하게 하기 위해서는 QButtonGroup 클래스에서 제공하는 setExclusive( ) 멤버함수를 사용하면 된다.
m_chk_group[0]->setExclusive(false);
m_chk_group[1]->setExclusive(true);
  • 위에서 보는 것과 같이 setExclusive( ) 함수에서 첫 번째 인자를 넘겨주면 다중 선택의 가능하거나 불가능하게 처리 할 수 있다.
  • false를 사용하면 다중 선택이 가능하며 true 를 사용하면 체크박스임에도 불구하고 다중 선택이 불가능하다.

 

Qt이미지 리소스

File name 설정
Add prefix를 누르고 '/'를 입력

<widget.cpp>

m_chk_group[0]->setExclusive(false);
m_chk_group[1]->setExclusive(true);
m_exclusive[0]->setIcon(QIcon(":resources/browser.png"));
m_exclusive[1]->setIcon(QIcon(":resources/calendar.png"));
m_exclusive[2]->setIcon(QIcon(":resources/chat.png"));
m_non_exclusive[0]->setIcon(QIcon(":resources/editor.png"));
m_non_exclusive[1]->setIcon(QIcon(":resources/mail.png"));
m_non_exclusive[2]->setIcon(QIcon(":resources/users.png"));

이런식으로 이 위치에 각 자리의 인덱스에 맞게 소스코드를 작성하고, setIcon의 QIcon인자에는 넣고자 하는 이미지의 위치를 알아야 한다.

 이미지의 위치는 이렇게 쉽게 알 수 있다.

 

<결과>

QComboBox

  • 사용자가 위젯을 클릭하면 팝업 메뉴가 나타나고 등록된 항목 중 하나를 선택할 수 있는 GUI를 제공한다.
  • QComboBox 위젯 상에 아이템을 등록하기 위해 텍스트 또는 아이템에 이미지를 사용해 텍스트를 함께 사용할 수 있다.

<Widget.h>

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>    // QWidget 클래스를 포함
#include <QComboBox>  // QComboBox 클래스를 포함

class Widget : public QWidget
{
    Q_OBJECT  // Qt의 시그널과 슬롯 메커니즘을 사용하기 위한 매크로
public:
    Widget(QWidget *parent = nullptr);  // 생성자: 부모 위젯을 인자로 받을 수 있음
    ~Widget();  // 소멸자

private:
    QComboBox *combo;  // QComboBox에 대한 포인터

private slots:
    void valueChanged();  // 콤보박스 값이 변경될 때 호출될 슬롯 함수
};

#endif // WIDGET_H

 

  • QWidget: 이 클래스는 애플리케이션의 기본 UI 구성 요소입니다. Widget 클래스는 QWidget을 상속받아 사용자 인터페이스를 구현.
  • QComboBox: 드롭다운 목록을 제공하는 위젯.
  • valueChanged: 콤보박스의 선택된 항목이 변경될 때 호출되는 슬롯 함수.

 

<widget.cpp>

#include "widget.h"  // Widget 클래스의 선언을 포함

Widget::Widget(QWidget *parent)
    : QWidget(parent)  // 부모 클래스의 생성자를 호출
{
    setWindowTitle("QComboBox");  // 윈도우의 제목을 설정

    combo = new QComboBox(this);  // QComboBox를 동적으로 생성하고 현재 위젯을 부모로 설정
    combo->setGeometry(50, 50, 200, 30);  // 콤보박스의 위치와 크기를 설정

    // 콤보박스에 아이템을 추가
    combo->addItem(QIcon(":resources/browser.png"), "Application");  // 아이콘과 함께 "Application" 아이템을 추가
    combo->addItem(QIcon(":resources/mail.png"), "Graphics");        // 아이콘과 함께 "Graphics" 아이템을 추가
    combo->addItem("Database");  // 아이콘 없이 "Database" 아이템을 추가
    combo->addItem("Network");   // 아이콘 없이 "Network" 아이템을 추가

    // 콤보박스의 선택된 항목이 변경될 때 valueChanged 슬롯 함수가 호출되도록 연결
    connect(combo, SIGNAL(currentIndexChanged(int)),
            this,  SLOT(valueChanged()));

    // 현재 선택된 콤보박스 항목의 텍스트를 가져옴
    QString str;
    str = combo->currentText();

    // 콤보박스의 총 항목 개수를 디버그 콘솔에 출력
    qDebug("Total Items : %d", combo->count());
}

void Widget::valueChanged()
{
    // 현재 콤보박스의 선택된 항목의 인덱스를 가져와서 디버그 콘솔에 출력
    int current_index = combo->currentIndex();
    qDebug("Current ComboBox index : %d", current_index);
}

Widget::~Widget()
{
    // 위젯 소멸자, 특별히 할 일 없음 (콤보박스는 부모 위젯에 의해 자동으로 삭제됨)
}

 

  • setWindowTitle: 윈도우 창의 제목을 "QComboBox"로 설정합니다.
  • combo->setGeometry: 콤보박스의 위치(50, 50)와 크기(200x30)를 설정합니다.
  • addItem: 콤보박스에 항목을 추가합니다. 일부 항목은 아이콘과 함께 추가되고, 일부는 아이콘 없이 텍스트만 추가됩니다.
  • connect: 시그널과 슬롯을 연결합니다. currentIndexChanged 시그널이 발생하면 valueChanged 슬롯 함수가 호출됩니다.
  • currentText: 현재 선택된 항목의 텍스트를 가져옵니다.
  • count: 콤보박스에 추가된 총 항목 개수를 출력합니다.
  • valueChanged: 선택된 항목의 인덱스를 가져와서 콘솔에 출력합니다.
    // 콤보박스에 아이템을 추가
    combo->addItem(QIcon(":resources/browser.png"), "Application");  // 아이콘이 출력되고 "Application"이란 텍스트가 출력됨.
    combo->addItem(QIcon(":resources/mail.png"), "Graphics");        // 아이콘이 출력되고"Graphics"란 텍스트가 출력됨 
    combo->addItem("Database");  // 아이콘 없이 "Database" 텍스트 추가
    combo->addItem("Network");   // 아이콘 없이 "Network" 텍스트 추가

 

 

<main.cpp>

#include <QtWidgets/QApplication>  // QApplication 클래스를 포함
#include "widget.h"                // Widget 클래스의 선언을 포함

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);  // 애플리케이션 인스턴스를 생성
    Widget w;  // Widget 인스턴스를 생성
    w.show();  // Widget을 화면에 표시

    return a.exec();  // 이벤트 루프 실행
}

 

  • QApplication: Qt 애플리케이션의 기본 클래스입니다. 이벤트 루프와 GUI를 관리.
  • w.show(): 생성된 위젯을 화면에 표시.
  • a.exec(): 애플리케이션의 이벤트 루프를 시작하여 사용자 상호작용을 처리.

<결과>

 

QCommandLinkButton

  • 이 위젯은 QPushButton 위젯과 동일한 기능을 제공하는 위젯이다.
  • 특징으로 이 위젯은MS Windows 에서 제공하는 Link Button과 같은 스타일을 제공한다.

<wiget.h>

#ifndef WIDGET_H
#define WIDGET_H

#include <QCommandLinkButton>  // QCommandLinkButton 클래스를 포함

class Widget : public QWidget
{
    Q_OBJECT  // Qt의 시그널과 슬롯 메커니즘을 사용하기 위한 매크로

public:
    Widget(QWidget *parent = nullptr);  // 생성자 선언 (부모 위젯을 인자로 받을 수 있음)
    ~Widget();  // 소멸자 선언

private:
    QCommandLinkButton *cmmBtn;  // QCommandLinkButton에 대한 포인터

private slots:
    void clickFunc();  // 버튼 클릭 시 호출되는 슬롯 함수

};

#endif // WIDGET_H

 

<widget.cpp>

#include "widget.h"  // Widget 클래스의 정의를 포함

Widget::Widget(QWidget *parent)
    : QWidget(parent)  // 부모 클래스 생성자를 호출하여 초기화
{
    setFixedSize(QSize(300, 100));  // 위젯의 고정 크기를 300x100으로 설정

    // QCommandLinkButton 생성, 버튼의 텍스트와 설명 텍스트 설정
    cmmBtn = new QCommandLinkButton("Vision", "Vision Project", this);  
    cmmBtn->setFlat(true);  // 버튼을 평평한 스타일로 설정 (경계선 제거)

    // 버튼 클릭 시 clickFunc() 슬롯을 호출하도록 시그널 연결
    connect(cmmBtn, SIGNAL(clicked()), this, SLOT(clickFunc()));
}

void Widget::clickFunc()
{
    // 버튼이 클릭되었을 때 디버그 메시지를 출력
    qDebug("QCommandLinkButton Click.");
}

Widget::~Widget()
{
    // 소멸자: 특별한 작업 필요 없음. Qt에서 부모 위젯이 자식 위젯을 자동으로 관리
}

 

<main.cpp>

#include <QtWidgets/QApplication>  // QApplication 클래스를 포함
#include "widget.h"  // Widget 클래스의 선언을 포함

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);  // 애플리케이션 인스턴스를 생성
    Widget w;  // Widget 인스턴스를 생성
    w.show();  // 위젯을 화면에 표시

    return a.exec();  // 이벤트 루프를 실행하여 사용자 상호작용을 처리
}
  • QCommandLinkButton: 이 위젯은 더 많은 정보와 설명 텍스트를 제공하는 큰 버튼입니다. 기본적으로 윈도우 비스타 이후에서 볼 수 있는 "커맨드 링크" 스타일의 버튼을 구현합니다.
  • clickFunc(): QCommandLinkButton이 클릭되었을 때 호출되는 슬롯 함수입니다. 이 함수는 qDebug를 사용하여 디버그 메시지를 출력합니다.

 

<결과>

QDate 클래스와 QDateEdit 위젯 클래스

  • QDateEdit는 날짜를 표시하거나 변경할 수 있는 GUI를 제공한다. 
  • QDateEdit는 QDate클래스에 설정된 날짜를 표시할 수 있다. 
  • QDate 클래스는 년, 월, 일을 지정하거나 현재 날짜를 시스템으로부터 얻어와 QDateEdit 위젯에 연결해 표시할 수 있다.

<widget.h>

#ifndef WIDGET_H
#define WIDGET_H

#include <QDate>      // 날짜를 다루기 위한 QDate 클래스
#include <QDateEdit>  // 날짜 편집 위젯을 위한 QDateEdit 클래스
#include <QLabel>     // 텍스트 표시를 위한 QLabel 클래스

class Widget : public QWidget
{
    Q_OBJECT  // Qt의 시그널 및 슬롯 메커니즘을 사용하기 위한 매크로

public:
    Widget(QWidget *parent = nullptr);  // 생성자
    ~Widget();  // 소멸자

private:
    QDateEdit *dateEdit[4];  // 네 개의 날짜 편집 위젯 배열
    QLabel *lbl[2];          // 두 개의 라벨 배열
};

#endif // WIDGET_H

 

  • QDateEdit: 날짜 입력 및 편집을 위한 위젯으로, 날짜를 쉽게 수정하고 표시할 수 있습니다.
  • QLabel: 단순히 텍스트를 표시하는 위젯으로, 날짜 정보를 텍스트 형식으로 출력하는 데 사용됩니다.
  • dateEdit[4]: 4개의 날짜 편집 위젯을 배열로 관리합니다.
  • lbl[2]: 두 개의 라벨을 배열로 관리하여, 특정 날짜 정보를 텍스트로 출력합니다.

 

<widget.cpp>

#include "widget.h"  // 위젯 클래스 정의 포함
#include <QDate>     // 날짜를 다루기 위한 QDate 클래스

Widget::Widget(QWidget *parent)
    : QWidget(parent)  // 부모 클래스의 생성자 호출
{
    QDate dt1 = QDate(2023, 1, 1);  // 2023년 1월 1일을 나타내는 QDate 객체 생성
    QDate dt2 = QDate::currentDate();  // 현재 날짜를 가져오는 QDate 객체 생성

    // 첫 번째 날짜에 2년을 더한 날짜를 QDateEdit 위젯에 설정
    dateEdit[0] = new QDateEdit(dt1.addYears(2), this);
    dateEdit[0]->setGeometry(10, 10, 140, 40);  // 위치 및 크기 설정

    // 첫 번째 날짜에 3개월을 더한 날짜를 QDateEdit 위젯에 설정
    dateEdit[1] = new QDateEdit(dt1.addMonths(3), this);
    dateEdit[1]->setGeometry(160, 10, 140, 40);  // 위치 및 크기 설정

    // 첫 번째 날짜에 10일을 더한 날짜를 QDateEdit 위젯에 설정
    dateEdit[2] = new QDateEdit(dt1.addDays(10), this);
    dateEdit[2]->setGeometry(310, 10, 140, 40);  // 위치 및 크기 설정

    // 현재 날짜를 QDateEdit 위젯에 설정
    dateEdit[3] = new QDateEdit(dt2, this);
    dateEdit[3]->setGeometry(10, 60, 140, 40);  // 위치 및 크기 설정

    // 날짜 관련 정보 출력 (dt1: 2023년 1월 1일 기준)
    qDebug("Day of year : %d", dt1.dayOfYear());  // 해당 날짜가 1년 중 몇 번째 날인지 출력
    qDebug("End Day : %d", dt1.daysInMonth());    // 해당 달의 총 일수 출력
    qDebug("End Day : %d", dt1.daysInYear());     // 해당 연도의 총 일수 출력

    // 문자열로부터 날짜 객체 생성
    QDate dt3 = QDate::fromString("2002.06.26", "yyyy.MM.dd");  // 2002년 6월 26일을 나타내는 QDate 생성
    QDate dt4 = QDate::fromString("06.26", "MM.dd");            // 6월 26일을 나타내는 QDate 생성

    // 라벨에 날짜 정보를 설정하고 화면에 출력
    lbl[0] = new QLabel(dt3.toString(), this);  // 첫 번째 라벨에 dt3을 텍스트로 변환하여 출력
    lbl[0]->setGeometry(10,110, 150, 30);       // 위치 및 크기 설정
    lbl[1] = new QLabel(dt4.toString(), this);  // 두 번째 라벨에 dt4을 텍스트로 변환하여 출력
    lbl[1]->setGeometry(10,150, 150, 30);       // 위치 및 크기 설정

    // 2011년 6월 27일이 유효한 날짜인지 확인
    if(QDate::isValid(2011, 6, 27))
    {
        qDebug("2011.6.27 true");  // 유효하면 "true" 출력
    }
    else
    {
        qDebug("2011.6.27 false");  // 유효하지 않으면 "false" 출력
    }
}

Widget::~Widget()
{
    // 소멸자: Qt가 자동으로 자식 위젯을 정리하므로 특별한 작업 필요 없음
}
  • 날짜 초기화 및 계산:
    • QDate dt1 = QDate(2023, 1, 1);는 2023년 1월 1일을 나타냅니다.
    • QDate dt2 = QDate::currentDate();는 현재 날짜를 나타냅니다.
    • addYears(), addMonths(), addDays() 메서드는 날짜를 조정하는 함수로, dt1에 각각 2년, 3개월, 10일을 더한 날짜를 계산합니다.
  • QDateEdit 위젯 설정:
    • dateEdit[] 배열에 각각 조정된 날짜를 적용하고, 이를 화면에 배치합니다 (setGeometry()).
  • QDate의 날짜 정보 출력:
    • dayOfYear()는 1년 중 몇 번째 날인지 반환합니다.
    • daysInMonth()는 해당 월의 총 일수를 반환합니다.
    • daysInYear()는 해당 연도의 총 일수를 반환합니다.
  • QDate 문자열 변환:
    • QDate::fromString()을 사용해 특정 형식의 문자열을 QDate 객체로 변환합니다. 예를 들어, "2002.06.26"을 "yyyy.MM.dd" 형식으로 파싱하여 QDate로 변환합니다.
  • 날짜 유효성 검사:
    • QDate::isValid()를 사용해 주어진 연도, 월, 일이 유효한 날짜인지 검사하고 결과를 출력합니다.

메인은 이전 예제와 동일합니다.

 

<결과>

QDate 클래스는 원하는 포맷으로 날짜를 표시하기 위한 방법으로 QString 데이터 타입을 리턴 하는 멤버 함수를 이용하면 날짜를 다양하게 표현할 수 있다.

 

'Qt프로그램' 카테고리의 다른 글

Qt Designer 를 이용한 GUI 설계  (3) 2024.10.08
Signal and Slot  (1) 2024.10.08
Layout  (0) 2024.10.08
Qt GUI widgets(2)  (1) 2024.10.08
qmake / CMake / console / GUI  (0) 2024.10.07

댓글