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

AiotClient 프로젝트 우클릭 → Add New → Qt → Qt Widgets Designer Form Class → Widget 선택
Class name을 Tab3ControlPannel로 입력하면 아래 파일이 자동 생성됩니다.
tab3controlpannel.htab3controlpannel.cpptab3controlpannel.uiUI에 사용할 이미지 파일을 프로젝트 리소스로 등록합니다.
사용하는 이미지는 아래와 같습니다.
이미지는 깃허브에 올려놓겠습니다.
github : kyoungmo / images source
| 이미지 파일 | 용도 |
|---|---|
| room1.png | 배경 이미지 |
| light_off.png | 전등 버튼 기본 상태 아이콘 |
| light_on.png | 전등 버튼 ON 상태 아이콘 |
| plug_off.png | 플러그 버튼 기본 상태 아이콘 |
| plug_on.png | 플러그 버튼 ON 상태 아이콘 |
tab3controlpannel.ui를 Qt Designer에서 열고 위젯을 배치합니다.
QLabel을 캔버스에 배치하고 Property Editor에서 pixmap에 room1.png를 지정합니다.

| 위젯 | objectName | 역할 |
|---|---|---|
| QLabel | label | 배경 이미지 표시 |
QPushButton을 배치하고 Property Editor에서 icon에 이미지를 지정합니다.
light_off.pnglight_on.pngiconSize : 70 x 70
checkable을 체크하면 Normal Off / Normal On 상태에 따라 아이콘이 자동으로 전환됩니다.
전등 버튼과 동일한 방식으로 플러그 버튼을 설정합니다.
plug_off.pngplug_on.pngiconSize : 70 x 70
| 위젯 | objectName | 역할 |
|---|---|---|
| QLabel | label | 배경 이미지 |
| QPushButton | pPBlamp | 전등 ON/OFF (Checkable) |
| QPushButton | pPBplug | 플러그 ON/OFF (Checkable) |
위젯 전체를 QScrollArea로 감싸서 화면 크기에 따라 스크롤이 가능하도록 합니다.
Widget Box에서 Scroll Area를 검색하여 캔버스에 추가한 뒤, 기존 위젯들을 내부로 이동합니다.

Object Inspector에서 최종 구조를 확인합니다.
Tab3ControlPannel (QWidget)
└── scrollArea (QScrollArea)
└── scrollAreaWidgetContents (QWidget)
├── label (QLabel)
├── pPBlamp (QPushButton)
└── pPBplug (QPushButton)
QPalette를 멤버 변수로 선언하여 버튼 색상 ON/OFF 상태를 관리합니다.
버튼 클릭 시 소켓으로 메시지를 보내기 위한 socketSendDataSig 시그널과,
수신 메시지를 처리할 tab3RecvDataSlot을 선언합니다.
signals:
void socketSendDataSig(QString);
public slots:
void tab3RecvDataSlot(QStringList&);
private:
QPalette paletteOn;
QPalette paletteOff;
생성자에서 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를 참조 타입으로 전달받아 버튼 상태와 팔레트를 업데이트합니다.
mainwidget.ui를 열고 Tab Widget에 Tab3 페이지를 추가합니다.
Tab Widget 우클릭 → Insert Page → After Current Page

추가된 Tab 페이지의 objectName을 pTab3으로 설정합니다.
tab3controlpannel.h를 include하고 Tab3ControlPannel 포인터를 선언합니다.
#include <tab3controlpannel.h>
Tab3ControlPannel *pTab3ControlPannel;
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 버튼 상태 업데이트로 연결됩니다.
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로 전달합니다.
빌드 후 실행하면 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 연결