어제 내용에서 추가하였다
어제까지는 송신 버튼을 눌러서만 가능했다면, enter 키로 입력할 수 있도록 변경한다
connect(ui->pLEsendData, SIGNAL(returnPressed()), this, SLOT(on_pPBsendButton_clicked()));
tab2에 추가한다
void Tab2TcpSocket::updateKeydataSlot(int KeyNo)
{
QString strSendData;
if(KeyNo == 1) {
strSendData = "[HM_CON]GASON";
} else if(KeyNo == 2) {
strSendData = "[HM_CON]GASOFF";
} else if(KeyNo == 3) {
strSendData = "[HM_CON]LAMPON";
} else if(KeyNo == 4) {
strSendData = "[HM_CON]LAMPOFF";
} else {
return;
}
pSocketClient->slotSocketSendData(strSendData);
}
tab2에서 다음과 같이 수정하여서 key 1,2,3,4로 LED, LAMP를 ON/OFF 할 수 있다
keyboard.h,cpp,ui 세개를 가져와서 add 한다
tab2에서 객체를 생성하려한다
#include "keyboard.h"
private:
Keyboard * pKeyboard;
tab2.h에 추가하고
tab2.cpp로 가서 객체를 생성해준다
Tab2TcpSocket::Tab2TcpSocket(QWidget *parent) :
QWidget(parent),
ui(new Ui::Tab2TcpSocket)
{
pKeyboard = new Keyboard();
connect(ui->pLErecvId, SIGNAL(selectionChanged()), this, SLOT(keyboardSlot()));
connect(ui->pLEsendData, SIGNAL(selectionChanged()), this, SLOT(keyboardSlot()));
}
SLOT을 생성했기 때문에 헤더에 slot 추가해주고 cpp 맨 아래에 함수 만들어준다
(늘 했던대로)
tab2.h에 lineedit가 필요하다
#include "QLineEdit"
그리고 cpp에 와서 함수 안에서 객체 생성한다
void Tab2TcpSocket::keyboardSlot()
{
QLineEdit * pQLineEdit = (QLineEdit *)sender();
pKeyboard->setLineEdit(pQLineEdit);
pKeyboard->show();
}
왼쪽 아래나 중앙을 더블클릭 하면 키보드가 실행되고, 입력 후 엔터를 누르면 쓴 글자로 입력이된다
sender : 시그널이 발생했을때 자기자신의 객체를 받아온다
이미지 등록
프로젝트 이름에서 add new - qt resource file
그리고 mainwindow.ui 에서 tab4를 만들고 이름을 수정한다
그 다음 ui를 하나 더 추가한다
메인위젯.h에
#include "tab3controlpannel.h"
Tab3ControlPannel *pTab3ControlPannel;
추가하고
.cpp에
pTab3ControlPannel = new Tab3ControlPannel(ui->pTab3);
ui->pTab3->setLayout(pTab3ControlPannel->layout());
두 줄을 추가해준다
ui에 scroll area, label을 각각 추가한다
label의 맨 아래쪽으로 내리면 pixmap이 있다
이미지를 추가하고
push버튼 2개를 넣는다
램프에 대해 아이콘 설정을 한다
이름을 바꾸고 on/off와 크기 설정을 한 뒤
살짝 남기고(마진) 조절해준다
플러그도 마찬가지로 설정해준다
이렇게 설정해주고
배경을 send to back 해주면
이렇게 스크롤 바가 생긴다!
그런데 우분투에서 checkable을 해도 이미지가 안바뀌어서 강제적으로 입히려 한다
(윈도우에서는 잘됨)
먼저 램프부터 해준다
tab3.h에 추가하고
signals:
void socketSendDataSig(QString);
tab3.cpp에 추가하고
void Tab3ControlPannel::on_pPBLamp_clicked(bool checked)
{
if(checked)
{
emit socketSendDataSig("[HM_CON]LAMPON");
ui->pPBLamp->setChecked(true);
}
else
{
emit socketSendDataSig("[HM_CON]LAMPON");
ui->pPBLamp->setChecked(false);
}
}
우선 tab2.h에 있는
SocketClient *pSocketClient;
를 public으로 임시 변경하고
main.cpp에 추가한다
connect(pTab3ControlPannel,SIGNAL(socketSendDataSig(QString)), pTab2TcpSocket->pSocketClient, SLOT(slotSocketSendData(QString)));
되면 gas도 해본다
메인cpp에 추가한다
connect(pTab2TcpSocket, SIGNAL(tab3RecvDataSig(QString)), Tab3ControlPannel, SLOT(tab3RecvDataSlot()));
그러면 tab2.h에서
void tab3RecvDataSig(QString);
추가하고
tab3.h에서
void tab3RecvDataSlot(QString);
추가하고
함수로 만든다
void Tab3ControlPannel::tab3RecvDataSlot(QString recvData)
{
QIcon buttonIcon;
QStringList qList = recvData.split("@");
if(qList[2] == "LAMPON") {
ui->pPBLamp->setChecked(true);
buttonIcon.addFile(":/Images/Images/light_on.png");
ui->pPBLamp->setIcon(buttonIcon);
}else if(qList[2] == "LAMPOFF") {
ui->pPBLamp->setChecked(false);
buttonIcon.addFile(":/Images/Images/light_off.png");
ui->pPBLamp->setIcon(buttonIcon);
}else if(qList[2] == "GASON") {
ui->pPBPlug->setChecked(true);
buttonIcon.addFile(":/Images/Images/plug_on.png");
ui->pPBPlug->setIcon(buttonIcon);
}else if(qList[2] == "GASOFF") {
ui->pPBPlug->setChecked(false);
buttonIcon.addFile(":/Images/Images/plug_off.png");
ui->pPBPlug->setIcon(buttonIcon);
}
}
메인에 다음 내용을 추가하여 제목을 넣을 수 있다
setWindowTitle("AiotClient");
tab3.h에
#include <QPalette>
private:
QPalette paletteColotOn;
QPalette paletteColotOff;
추가하고
Tab3ControlPannel::Tab3ControlPannel(QWidget *parent) :
QWidget(parent),
ui(new Ui::Tab3ControlPannel)
{
ui->setupUi(this);
paletteColotOn.setColor(ui->pPBLamp->backgroundRole(), QColor(255,0,0));
paletteColotOff.setColor(ui->pPBLamp->backgroundRole(), QColor(0,0,255));
ui->pPBLamp->setPalette(paletteColotOff);
ui->pPBPlug->setPalette(paletteColotOff);
}
void Tab3ControlPannel::tab3RecvDataSlot(QString recvData)
{
QIcon buttonIcon;
QStringList qList = recvData.split("@");
if(qList[2] == "LAMPON")
{
ui->pPBLamp->setChecked(true);
buttonIcon.addFile(":/Images/Images/light_on.png");
ui->pPBLamp->setIcon(buttonIcon);
ui->pPBLamp->setPalette(paletteColotOn);
}
else if(qList[2] == "LAMPOFF")
{
ui->pPBLamp->setChecked(false);
buttonIcon.addFile(":/Images/Images/light_off.png");
ui->pPBLamp->setIcon(buttonIcon);
ui->pPBLamp->setPalette(paletteColotOff);
}
else if(qList[2] == "GASON")
{
ui->pPBPlug->setChecked(true);
buttonIcon.addFile(":/Images/Images/plug_on.png");
ui->pPBPlug->setIcon(buttonIcon);
ui->pPBPlug->setPalette(paletteColotOn);
}
else if(qList[2] == "GASOFF")
{
ui->pPBPlug->setChecked(false);
buttonIcon.addFile(":/Images/Images/plug_off.png");
ui->pPBPlug->setIcon(buttonIcon);
ui->pPBPlug->setPalette(paletteColotOff);
}
}
tab3.cpp에 추가한다
그러면 on/off때 ui의 색이 변경된다
메인 백그라운드 색 입히기는 참고용으로 그냥 볼 것
아래 내용을 추가하면 수신 삭제 버튼을 활용할 수 있다
connect(ui->pPBrecvDataClear, SIGNAL(clicked()), ui->pTErecvData, SLOT(clear()));
[HM_CON]GETSENSOR 를 입력하면 조/온/습도를 확인할 수 있다
이 결과를 통해 차트를 그려보려 한다
welcome - example - line example 실행하면 확인할 수 있다
tab5를 하나 추가한 뒤
Tab4LineChart라는 이름으로 forms ui를 하나 추가한다
ui로 가서 vertical layout, horizontal layout을 추가한다
push버튼을 hbox에 넣고 그 왼쪽에 hspacer를 넣고 0:0으로 한다
전체 layout을 vertical로 한 뒤 1:9 비율로 만든다
main.h에
#include "tab4linechart.h"
private:
Tab4LineChart *pTab4LineChart;
main.cpp에
pTab4LineChart = new Tab4LineChart(ui->pTab4);
ui->pTab4->setLayout(pTab4LineChart->layout());
그리고 이름을 바꿔준다
다시 한번 말하지만, 만약 못읽으면 save all, rebuild all, 라즈베리에서 make 하면 된다
.pro 파일에 charts 추가한다
QT += core gui network charts
tab4.h에
#include <QLineSeries>
#include <QChartView>
#include <QDateTimeAxis>
#include <QDate>
#include <QTime>
QT_CHARTS_USE_NAMESPACE
public:
void updateLastDateTime();
private:
QLineSeries * illuLine;
QChart * chart;
QChartView * chartView;
QDateTimeAxis * axisX;
QDateTime firstDate;
QDateTime lastDate;
위의 모든 것을 추가해준다(시간과 날짜를 사용하기 위함이다)
그리고 tab4.cpp에 가서
Tab4LineChart::Tab4LineChart(QWidget *parent) :
QWidget(parent),
ui(new Ui::Tab4LineChart)
{
ui->setupUi(this);
illuLine = new QLineSeries(this);
illuLine->setName("조도");
QPen pen;
pen.setWidth(2);
pen.setBrush(Qt::red);
pen.setCapStyle(Qt::FlatCap);
pen.setJoinStyle(Qt::MiterJoin);
illuLine->setPen(pen);
chart = new QChart();
chart->addSeries(illuLine);
chart->createDefaultAxes();
chart->axes(Qt::Vertical).first()->setRange(0, 100); //세로축
chartView = new QChartView(chart);
chartView->setRenderHint(QPainter::Antialiasing);
ui->pVLlineChart->layout()->addWidget(chartView);
axisX = new QDateTimeAxis;
axisX->setFormat("hh:mm");
chartView->chart()->setAxisX(axisX, illuLine);
updateLastDateTime();
}
void Tab4LineChart::updateLastDateTime()
{
QDate date = QDate::currentDate();
QTime time = QTime::currentTime();
firstDate.setDate(date);
firstDate.setTime(time);
lastDate.setDate(date);
QTime tempTime = time.addSecs(60*10); // 60sec * 10min
lastDate.setTime(tempTime);
axisX->setRange(firstDate, lastDate);
}
이렇게 작성한다
그리고 tab2.cpp에 가서
else if(qlist[2] == "SENSOR")
{
emit tab4RecvDataSig(strRecvData);
}
추가 후 tab2.h에 해당 시그널을 등록하고
main.cpp가서
connect(pTab2TcpSocket,SIGNAL(tab4RecvDataSig(QString)),pTab4LineChart, SLOT(tab4RecvDataSlot(QString)));
추가하고
tab4.h에서 슬롯만든다
그러면 다시 tab4.cpp 오면 함수를 만들어야 한다
void Tab4LineChart::tab4RecvDataSlot(QString recvData)
{
QDate date = QDate::currentDate();
QTime time = QTime::currentTime();
QDateTime xValue;
xValue.setDate(date);
xValue.setTime(time);
QStringList qlist = recvData.split("@"); // @HM_CON@SENSOR@78@23@40 이런식으로 만든다
illuLine->append(xValue.toMSecsSinceEpoch(), qlist[3].toInt());
}
이렇게 하고 연결했을 때 잘 된다
clear 버튼을 눌렀을때 클리어하고, 현재 시간으로 다시 업데이트 하는 코드를 추가한다
void Tab4LineChart::on_pPBClear_clicked()
{
illuLine->clear();
updateLastDateTime();
}
평가
1번 소켓
2번 차트
3번 sql quary