이전 글까지 Tab1 ~ Tab3까지 구현해봤습니다.
이번 글에서는 Tab1과 Tab2 사이에서 교수님이 내주신 과제 2개를 정리하겠습니다. 과제를 구현하면서 Signal / Slot에 대해 확실히 이해하게 되어 함께 정리해보려 합니다.

Tab1에서 다이얼 값이 변화할 때마다 Tab2 소켓을 통해 KYM_LIN 클라이언트에게 아래 형식으로 메시지를 전송합니다.
[KYM_LIN]DIAL@{0~255}

서버에 접속한 상태에서 KYM_QT가 아래 형식의 메시지를 수신하면, Tab1의 해당 번호 체크박스를 ON 또는 OFF로 설정합니다.
[KYM_QT]KEY@{1~8}@ON
[KYM_QT]KEY@{1~8}@OFF
Signal / Slot은 어떠한 원하는 동작이 발생했을 때, Slot 함수를 실행시킨다 라고 생각하면 됩니다.
예를 들어 과제 1번에서, Tab1의 다이얼 값에 변화가 생겼다는 Signal이 발생했을 때 Tab2의 어떤 Slot 함수를 실행시킨다고 이해하면 됩니다.
Signal / Slot의 흐름은 아래와 같습니다.
Tab1에서 emit 뒤에 Signal 내용 작성
↓
mainwidget에서 connect 함수 작성
↓
connect 함수에 맞는 Slot 함수를 Tab2에서 구현
즉 Signal을 발생시키는 쪽(emit)과 이를 받아 처리하는 쪽(Slot)을 mainwidget의 connect로 연결하는 구조입니다.

다이얼 값 변화 슬롯과 소켓 송신 시그널을 선언합니다.
private slots:
void on_pDialLed_valueChanged(int value);
signals:
void socketSendDataSig(QString);
다이얼 값이 변경될 때마다 [KYM_LIN]DIAL@값 형식으로 시그널을 emit합니다.
void Tab1DeviceControl::on_pDialLed_valueChanged(int value)
{
QString strData = "[KYM_LIN]DIAL@" + QString::number(value);
emit socketSendDataSig(strData);
}
on_pDialLed_valueChanged는 Qt Designer에서 자동 연결되는 슬롯으로, 다이얼 값이 변할 때마다 호출됩니다.
Tab1의 시그널을 Tab2의 소켓 송신 슬롯에 연결합니다.
connect(pTab1DeviceControl, SIGNAL(socketSendDataSig(QString)),
pTab2SocketClient, SLOT(socketWriteDataSlot(QString)));

Tab2의 updateRecvDataSlot에서 수신된 문자열을 파싱하여 Tab1으로 전달합니다.
strRecvData.replace("[", "@");
strRecvData.replace("]", "@");
QStringList strList = strRecvData.split("@");
// strList[0] = ""
// strList[1] = "KYM_QT"
// strList[2] = "KEY"
// strList[3] = "1" ← 체크박스 번호
// strList[4] = "ON" ← ON / OFF
if(strList[2] == "KEY")
emit tab1RecvDataSig(strList);
signals:
void tab1RecvDataSig(QStringList&);
public slots:
void tab1RecvDataSlot(QStringList&);
파싱된 QStringList에서 체크박스 번호와 ON/OFF 상태를 추출하여 해당 체크박스를 설정합니다.
void Tab1DeviceControl::tab1RecvDataSlot(QStringList& strList)
{
bool keyFlag;
int keyNumber = strList[3].toInt();
if(keyNumber < 1 || 8 < keyNumber)
return;
else
keyNumber--;
if(strList[4] == "ON")
keyFlag = true;
else
keyFlag = false;
pQCheckBox[keyNumber]->setChecked(keyFlag);
updateCheckBoxSlot(++keyNumber);
}
Tab2의 시그널을 Tab1의 슬롯에 연결합니다.
connect(pTab2SocketClient, SIGNAL(tab1RecvDataSig(QStringList&)),
pTab1DeviceControl, SLOT(tab1RecvDataSlot(QStringList&)));
[Tab1] 다이얼 값 변화
↓ on_pDialLed_valueChanged(int value)
↓ emit socketSendDataSig("[KYM_LIN]DIAL@값")
↓ mainwidget connect
[Tab2] socketWriteDataSlot(QString)
↓ 소켓 송신
소켓 수신
↓ [Tab2] updateRecvDataSlot(QString)
↓ 문자열 파싱 → QStringList
↓ emit tab1RecvDataSig(strList)
↓ mainwidget connect
[Tab1] tab1RecvDataSlot(QStringList&)
↓ 체크박스 번호 추출 및 ON/OFF 설정