# Qt) Designer로 UI 구성하기(7) - Tab4SensorChart

mommers·2026년 4월 11일

QT

목록 보기
13/15

ROS 수업을 새로 들어가고부터 수업 진도 따라가고 백준 코테문제 집중해서 푸느라 블로그 정리가 밀렸네요.. 기억나는 순서대로 천천히 정리해보겠습니다.


이전 글 : Qt) Designer로 UI 구성하기(6) - Tab6WebCamera

이전 글에서 mjpg-streamer와 QWebEngineView를 활용해 Tab6 웹캠 탭을 구현했습니다.

이번 글에서는 소켓으로 수신한 센서 데이터를 실시간 그래프로 표시하는 Tab4SensorChart를 구현하는 과정을 정리해보겠습니다. 수업에서는 조도 데이터만으로 그래프를 그려보았고, 이후 시험에서 온도와 습도 데이터를 추가하는 방향으로 진행됐습니다.


1. .pro 파일에 charts 모듈 추가

QLineSeries, QChart, QChartView 등 차트 관련 클래스를 사용하기 위해 .pro 파일에 charts 모듈을 추가합니다.

QT += widgets network charts

2. Tab4SensorChart 클래스 생성

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

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

  • tab4sensorchart.h
  • tab4sensorchart.cpp
  • tab4sensorchart.ui

3. Tab4SensorChart UI 구성

tab4sensorchart.ui를 Qt Designer에서 열고 아래와 같이 위젯을 배치합니다.

=====================================
|                         [Clear]   |
|                                   |
|       pChartViewLayout            |
|        (차트 표시 영역)             |
|                                   |
=====================================

주요 위젯 objectName

위젯objectName역할
QWidgetpChartViewLayout차트 뷰를 추가할 레이아웃 영역
QPushButtonpPBchartClear차트 데이터 초기화

pChartViewLayoutQWidget을 배치하고 레이아웃을 설정한 후, 생성자에서 QChartView를 동적으로 추가하는 방식을 사용합니다.


4. tab4sensorchart.h

차트 관련 멤버 변수로 QLineSeries, QChart, QChartView, QDateTimeAxis를 선언합니다.
X축을 시간 기반으로 표시하기 위해 QDateTimeAxis를 사용합니다.

#ifndef TAB4SENSORCHART_H
#define TAB4SENSORCHART_H

#include <QWidget>
#include <QChartView>
#include <QLineSeries>
#include <QDateTimeAxis>
#include <QDate>
#include <QTime>

namespace Ui {
class Tab4SensorChart;
}

class Tab4SensorChart : public QWidget
{
    Q_OBJECT

public:
    explicit Tab4SensorChart(QWidget *parent = nullptr);
    ~Tab4SensorChart();
    void updateLastDateTime(bool bFlag);

private slots:
    void tab4RecvDataSlot(QStringList&);
    void on_pPBchartClear_clicked();

private:
    Ui::Tab4SensorChart *ui;
    QLineSeries *illuLine;
    QLineSeries *humiLine;
    QLineSeries *tempLine;
    QChart *pQChart;
    QChartView *pQChartView;
    QDateTimeAxis *pQDateTimeAxis;
    QDateTime firstDateTime;
    QDateTime lastDateTime;
};

#endif // TAB4SENSORCHART_H

5. tab4sensorchart.cpp

5-1. 생성자 - 차트 초기화

조도, 온도, 습도 각각 QLineSeries를 생성하고 색상을 지정합니다.
QPen으로 선 굵기와 색상을 설정합니다.

Tab4SensorChart::Tab4SensorChart(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Tab4SensorChart)
{
    ui->setupUi(this);

    // 조도 - 빨간색
    illuLine = new QLineSeries(this);
    illuLine->setName("조도");
    QPen pen_r;
    pen_r.setWidth(2);
    pen_r.setBrush(Qt::red);
    pen_r.setCapStyle(Qt::FlatCap);
    pen_r.setJoinStyle(Qt::MiterJoin);
    illuLine->setPen(pen_r);

    // 습도 - 초록색
    humiLine = new QLineSeries(this);
    humiLine->setName("습도");
    QPen pen_g;
    pen_g.setWidth(2);
    pen_g.setBrush(Qt::green);
    humiLine->setPen(pen_g);

    // 온도 - 파란색
    tempLine = new QLineSeries(this);
    tempLine->setName("온도");
    QPen pen_b;
    pen_b.setWidth(2);
    pen_b.setBrush(Qt::blue);
    tempLine->setPen(pen_b);

    // QChart 생성 및 시리즈 추가
    pQChart = new QChart();
    pQChart->addSeries(illuLine);
    pQChart->addSeries(humiLine);
    pQChart->addSeries(tempLine);

    // Y축 범위 0~100 설정
    pQChart->createDefaultAxes();
    pQChart->axes(Qt::Vertical).constFirst()->setRange(0, 100);

    // QChartView 생성
    pQChartView = new QChartView(pQChart);

    // X축 시간 축 설정
    pQDateTimeAxis = new QDateTimeAxis;
    pQDateTimeAxis->setFormat("hh:mm");

    updateLastDateTime(false);

    // pChartViewLayout에 QChartView 추가
    ui->pChartViewLayout->layout()->addWidget(pQChartView);
    pQChartView->chart()->setAxisX(pQDateTimeAxis, illuLine);
    pQChartView->chart()->setAxisX(pQDateTimeAxis, humiLine);
    pQChartView->chart()->setAxisX(pQDateTimeAxis, tempLine);
}

QChartView를 Designer에서 직접 배치하지 않고 생성자에서 동적으로 생성하여 pChartViewLayout에 추가하는 방식을 사용했습니다.


5-2. updateLastDateTime - X축 시간 범위 업데이트

bFlagfalse이면 현재 시각을 시작 시각으로 설정하고, true이면 현재 시각으로 끝 시각만 연장합니다.

void Tab4SensorChart::updateLastDateTime(bool bFlag)
{
    QDate date = QDate::currentDate();
    QTime time = QTime::currentTime();
    if(!bFlag)
    {
        firstDateTime.setDate(date);
        firstDateTime.setTime(time);
    }
    lastDateTime.setDate(date);
    lastDateTime.setTime(time.addSecs(60 * 1));
    pQDateTimeAxis->setRange(firstDateTime, lastDateTime);
}

처음 실행 시(false) 현재 시각을 기준으로 X축을 1분 범위로 초기화합니다.
데이터가 들어오면서 시간이 범위를 초과하면(true) X축 끝 시각을 현재 시각으로 연장합니다.


5-3. tab4RecvDataSlot - 수신 데이터 차트에 추가

Tab2에서 파싱된 QStringList를 받아 각 센서 값을 차트에 추가합니다.
X축 값은 현재 시각을 밀리초 단위로 변환하여 사용합니다.

void Tab4SensorChart::tab4RecvDataSlot(QStringList& strList)
{
    QDateTime dateTime = QDateTime::currentDateTime();

    QString strIllu = strList[3];
    QString strTemp = strList[4];
    QString strHumi = strList[5];

    if(lastDateTime.toSecsSinceEpoch() < dateTime.toSecsSinceEpoch())
    {
        updateLastDateTime(true);
    }

    illuLine->append(dateTime.toMSecsSinceEpoch(), strIllu.toInt());
    humiLine->append(dateTime.toMSecsSinceEpoch(), strTemp.toDouble());
    tempLine->append(dateTime.toMSecsSinceEpoch(), strHumi.toDouble());
}

5-4. Clear 버튼 - 차트 초기화

void Tab4SensorChart::on_pPBchartClear_clicked()
{
    illuLine->clear();
    humiLine->clear();
    tempLine->clear();
    updateLastDateTime(false);
}

6. mainwidget에 Tab4 추가 및 소켓 연동

mainwidget.h

#include <tab4sensorchart.h>

Tab4SensorChart *pTab4SensorChart;

mainwidget.cpp

pTab4SensorChart = new Tab4SensorChart(ui->pTab4);
ui->pTab4->setLayout(pTab4SensorChart->layout());

connect(pTab2SocketClient, SIGNAL(tab4RecvDataSig(QStringList&)),
        pTab4SensorChart, SLOT(tab4RecvDataSlot(QStringList&)));

Tab2의 updateRecvDataSlot에서 센서 데이터(HUM 등)를 파싱하여 tab4RecvDataSig로 emit하면 Tab4에서 수신하여 차트에 추가합니다.


전체 흐름 요약

.pro에 charts 모듈 추가 (QT += charts)
    ↓
Tab4SensorChart 클래스 생성 (Qt Widgets Designer Form Class)
    ↓
UI 구성 (pChartViewLayout + Clear 버튼)
    ↓
생성자 : QLineSeries 3개 생성 및 색상 설정 (조도-빨강, 습도-초록, 온도-파랑)
    ↓
QChart에 시리즈 추가 → QChartView 생성 → pChartViewLayout에 추가
    ↓
QDateTimeAxis로 X축 시간 범위 설정
    ↓
tab4RecvDataSlot : 수신 데이터 파싱 → 각 시리즈에 append
    ↓
mainwidget에 Tab4 추가 및 Tab2 수신 시그널 연결
profile
임베디드 개발자가 되기 위해 공부중입니다!

0개의 댓글