Qt) Designer로 UI 구성하기(4) - Tab3ControlPannel

mommers·2026년 4월 3일

QT

목록 보기
8/15

이전 글 : Qt) Designer로 UI 구성하기(3) - Tab2SocketClient

이전 글에서 Tab2SocketClient 클래스를 구현하였습니다.

이번 글에서는 이미지 리소스를 활용한 Tab3ControlPannel 클래스를 구현하는 과정을 정리하겠습니다.
배경 이미지와 아이콘 이미지를 위젯에 적용하고, QPalette로 버튼 색상을 제어하며, 소켓 메시지를 통해 원격으로 lamp/plug 상태를 제어합니다.


1. Tab3ControlPannel 클래스 생성

AiotClient 프로젝트 우클릭 → Add New → Qt → Qt Widgets Designer Form Class → Widget 선택

Class name을 Tab3ControlPannel로 입력하면 아래 파일이 자동 생성됩니다.

  • tab3controlpannel.h
  • tab3controlpannel.cpp
  • tab3controlpannel.ui

2. 이미지 리소스 추가

UI에 사용할 이미지 파일을 프로젝트 리소스로 등록합니다.
사용하는 이미지는 아래와 같습니다.

이미지는 깃허브에 올려놓겠습니다.
github : kyoungmo / images source

이미지 파일용도
room1.png배경 이미지
light_off.png전등 버튼 기본 상태 아이콘
light_on.png전등 버튼 ON 상태 아이콘
plug_off.png플러그 버튼 기본 상태 아이콘
plug_on.png플러그 버튼 ON 상태 아이콘

3. Tab3ControlPannel UI 구성 (Designer)

tab3controlpannel.ui를 Qt Designer에서 열고 위젯을 배치합니다.

3-1. QLabel - 배경 이미지 설정

QLabel을 캔버스에 배치하고 Property Editor에서 pixmaproom1.png를 지정합니다.

위젯objectName역할
QLabellabel배경 이미지 표시

3-2. QPushButton - 전등 버튼 아이콘 설정

QPushButton을 배치하고 Property Editor에서 icon에 이미지를 지정합니다.

  • Normal Off : light_off.png
  • Normal On : light_on.png
  • iconSize : 70 x 70

checkable을 체크하면 Normal Off / Normal On 상태에 따라 아이콘이 자동으로 전환됩니다.

3-3. QPushButton - 플러그 버튼 아이콘 설정

전등 버튼과 동일한 방식으로 플러그 버튼을 설정합니다.

  • Normal Off : plug_off.png
  • Normal On : plug_on.png
  • iconSize : 70 x 70

주요 위젯 objectName

위젯objectName역할
QLabellabel배경 이미지
QPushButtonpPBlamp전등 ON/OFF (Checkable)
QPushButtonpPBplug플러그 ON/OFF (Checkable)

3-4. QScrollArea로 감싸기

위젯 전체를 QScrollArea로 감싸서 화면 크기에 따라 스크롤이 가능하도록 합니다.

Widget Box에서 Scroll Area를 검색하여 캔버스에 추가한 뒤, 기존 위젯들을 내부로 이동합니다.

Object Inspector에서 최종 구조를 확인합니다.

Tab3ControlPannel (QWidget)
└── scrollArea (QScrollArea)
    └── scrollAreaWidgetContents (QWidget)
        ├── label (QLabel)
        ├── pPBlamp (QPushButton)
        └── pPBplug (QPushButton)

4. Tab3ControlPannel 코드

tab3controlpannel.h

QPalette를 멤버 변수로 선언하여 버튼 색상 ON/OFF 상태를 관리합니다.
버튼 클릭 시 소켓으로 메시지를 보내기 위한 socketSendDataSig 시그널과,
수신 메시지를 처리할 tab3RecvDataSlot을 선언합니다.

signals:
    void socketSendDataSig(QString);

public slots:
    void tab3RecvDataSlot(QStringList&);

private:
    QPalette paletteOn;
    QPalette paletteOff;

생성자 - QPalette 초기화

생성자에서 ON/OFF 상태의 팔레트 색상을 미리 설정합니다.

paletteOn.setColor(ui->pPBlamp->backgroundRole(), QColor(255, 0, 0));  // 빨강
paletteOff.setColor(ui->pPBlamp->backgroundRole(), QColor(0, 0, 255)); // 파랑
ui->pPBlamp->setPalette(paletteOff);
ui->pPBplug->setPalette(paletteOff);

초기 상태에서 두 버튼 모두 paletteOff(파란색)으로 설정됩니다.

버튼 클릭 슬롯 - 소켓 메시지 송신

버튼 클릭 시 socketSendDataSig 시그널로 소켓 메시지를 emit합니다.
checked 상태에 따라 ON/OFF 메시지를 구분하여 전송합니다.

void Tab3ControlPannel::on_pPBlamp_clicked(bool checked)
{
    if(checked)
    {
        ui->pPBlamp->setChecked(true);
        emit socketSendDataSig("[KYM_LIN]LAMPON");
        ui->pPBlamp->setPalette(paletteOn);
    }
    else
    {
        ui->pPBlamp->setChecked(false);
        emit socketSendDataSig("[KYM_LIN]LAMPOFF");
        ui->pPBlamp->setPalette(paletteOff);
    }
}

void Tab3ControlPannel::on_pPBplug_clicked(bool checked)
{
    if(checked)
    {
        ui->pPBplug->setChecked(true);
        emit socketSendDataSig("[KYM_LIN]PLUGON");

        ui->pPBplug->setPalette(paletteOn);
    }
    else
    {
        ui->pPBplug->setChecked(false);
        emit socketSendDataSig("[KYM_LIN]PLUGOFF");
        ui->pPBplug->setPalette(paletteOff);
    }
}

Tab2에서 파싱된 QStringList를 참조 타입으로 전달받아 버튼 상태와 팔레트를 업데이트합니다.


5. mainwidget에 Tab3 추가

Tab 페이지 추가

mainwidget.ui를 열고 Tab Widget에 Tab3 페이지를 추가합니다.

Tab Widget 우클릭 → Insert Page → After Current Page

추가된 Tab 페이지의 objectName을 pTab3으로 설정합니다.

mainwidget.h

tab3controlpannel.h를 include하고 Tab3ControlPannel 포인터를 선언합니다.

#include <tab3controlpannel.h>

Tab3ControlPannel *pTab3ControlPannel;

mainwidget.cpp

Tab3ControlPannel 객체를 생성하여 pTab3에 배치하고, Tab2와 Signal/Slot을 연결합니다.

pTab3ControlPannel = new Tab3ControlPannel(ui->pTab3);
ui->pTab3->setLayout(pTab3ControlPannel->layout());

connect(pTab3ControlPannel, SIGNAL(socketSendDataSig(QString)),
        pTab2SocketClient, SLOT(socketWriteDataSlot(QString)));
connect(pTab2SocketClient, SIGNAL(tab3RecvDataSig(QStringList&)),
        pTab3ControlPannel, SLOT(tab3RecvDataSlot(QStringList&)));

Tab3의 버튼 클릭 → Tab2를 통해 소켓 송신, Tab2에서 수신한 메시지 → Tab3 버튼 상태 업데이트로 연결됩니다.

tab2socketclient.cpp - 수신 메시지 파싱 및 라우팅

Tab2의 updateRecvDataSlot에서 수신된 문자열을 파싱하여 Tab3로 전달합니다.

void Tab2SocketClient::updateRecvDataSlot(QString strRecvData)
{
    strRecvData.chop(1);    // '\n' 제거
    QTime time = QTime::currentTime();
    QString strTime = time.toString() + " " + strRecvData;
    ui->pTErecvData->append(strTime);

    // [KYM_LIN]LAMPON → "@KYM_LIN@LAMPON@"으로 변환 후 split
    strRecvData.replace("[", "@");
    strRecvData.replace("]", "@");
    QStringList strList = strRecvData.split("@");
    // strList[0] = ""
    // strList[1] = "KYM_LIN"
    // strList[2] = "LAMPON"

    if((strList[2].indexOf("LAMP") == 0) || (strList[2].indexOf("PLUG") == 0))
        emit tab3RecvDataSig(strList);
}

LAMP 또는 PLUG로 시작하는 메시지는 tab3RecvDataSig로 emit하여 Tab3로 전달합니다.


6. 실행 결과

빌드 후 실행하면 Tab3에 배경 이미지와 아이콘 버튼이 정상적으로 표시됩니다.

버튼 클릭 시 소켓 메시지가 전송되고, 서버로부터 응답이 돌아오면 아이콘과 배경색이 전환됩니다.


전체 흐름 요약

Tab3ControlPannel 클래스 생성 (Qt Widgets Designer Form Class)
    ↓
이미지 리소스 추가 (배경, 아이콘)
    ↓
QLabel에 room1.png 배경 이미지 설정
    ↓
QPushButton에 아이콘 이미지 설정 (Normal Off / Normal On)
    ↓
QScrollArea로 전체 위젯 감싸기
    ↓
생성자에서 QPalette 초기화
    ↓
버튼 클릭 슬롯에서 socketSendDataSig emit
    ↓
tab3RecvDataSlot에서 수신 메시지 파싱 및 버튼 상태 변경
    ↓
mainwidget.ui에서 Tab3 페이지 추가
    ↓
mainwidget에서 Tab3ControlPannel 객체 생성 및 Tab2와 Signal/Slot 연결
profile
임베디드 개발자가 되기 위해 공부중입니다!

0개의 댓글