Qt에서 QtCharts 사용하기

1. 기본 개념

축(QAbstractAxis)

차트에는 일반적으로 X축과 Y축이 있고, 더 복잡한 형태에는 Z축도 있다. Qt의 차트 역시 X축/Y축 객체를 제공한다. 다만 축 객체를 직접 만들지 않으면 Qt가 제공하는 기본 축을 그대로 사용할 수 있다. 축을 세부적으로 구성하는 방법은 여기서는 다루지 않는다.

계열(QAbstractSeries)

꺾은선 그래프, 원형 차트, 막대 차트 등 어떤 종류든 차트가 표현하는 내용은 결국 데이터다. 하나의 곡선은 하나의 데이터 집합이고, 하나의 원형 차트도 하나의 데이터 집합에 대응한다. Qt Charts에서는 이렇게 묶인 데이터 집합을 계열(Series)이라고 한다. 차트 종류에 따라 Qt는 서로 다른 계열 클래스를 제공한다. 계열은 데이터를 저장하고 조회하는 역할뿐만 아니라 데이터를 실제로 그리는 방법도 제공한다. 예를 들어 꺾은선 그래프는 QLineSeries, 곡선 그래프는 QSplineSeries로 표현한다. 목적에 맞는 계열을 선택하면 된다.

범례(Legend)

Excel처럼 Qt Charts에도 범례가 있다. 범례를 화면에 표시하거나 숨길 수 있다.

차트(QChart)

QChart는 앞서 설명한 축, 계열, 범례 등을 하나로 캡슐화하는 클래스다. QChart는 각 요소를 조직하고 관리하는 역할을 한다. QChart는 QGraphicsObject를 상속하므로 실제 그래픽 아이템이다. QChart 객체에서 축 객체, 데이터 계열, 범례 등을 가져올 수 있고, 차트 테마나 배경색과 같은 스타일도 설정할 수 있다.

뷰(QChartView)

QChart는 차트 내용의 구성과 관리만 담당한다. 실제 화면 표시는 뷰가 담당하며 이때 사용하는 클래스가 QChartView다. QChartView는 QGraphicsView를 상속하고, QChart를 위해 setChart(QChart*)와 같은 전용 인터페이스를 추가로 제공한다.

2. 사용 방법

QtCharts를 적용하려면 다음 단계를 따른다.

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

QT += charts

2-2. chart 관련 헤더를 UI 헤더보다 먼저 포함

chart 관련 헤더가 UI 관련 헤더보다 아래에 있으면 QChartView 관련 심볼을 찾지 못해 컴파일 오류가 발생할 수 있다. 따라서 chart 헤더를 먼저 include 해야 한다.

#include <QtCharts/QChartView>
#include <QtCharts/QLineSeries>

QT_CHARTS_USE_NAMESPACE

2-3. UI 위젯을 QChartView로 승격

Qt Designer에서 QWidget을 하나 배치한 뒤 해당 위젯을 마우스 오른쪽 버튼으로 클릭하고 [Promote to...]를 선택한다. 대화상자에서 다음 항목을 입력한다.

  • Base class name: QWidget
  • Promoted class name: QChartView
  • Header file: QChartView

2-4. setChart 호출 후 이전 차트 객체 삭제

QChartView에 새 QChart를 설정한 뒤에는 기존 QChart 객체를 삭제하지 않으면 메모리 누수가 발생할 수 있다.

QChart *previousChart = ui->plotWidget->chart();
QChart *newChart = new QChart();
ui->plotWidget->setChart(newChart);

if (previousChart != nullptr) {
    delete previousChart;
}

3. 차트 스크롤 및 좌표 표시

차트를 스크롤하면서 동적으로 표시해야 한다면 Qt에서 제공하는 기본 예제인 dynamicspline을 참고한다. 차트 위에 정확한 좌표값이나 설명을 표시해야 한다면 callout 예제를 참고한다.

4. chart.scroll() 사용 시 주의할 점

QChart의 scroll()을 사용할 때는 x축 이동량을 계산하는 방식에 주의해야 한다.

double x = chart->plotArea().width() / (X_RANGE_MAX - X_RANGE_MIN);
chart->scroll(x, 0);

여기서 x는 plotArea().width() / xAxis->tickCount()로 계산하지 않는다. X_RANGE_MAXX_RANGE_MINsetRange()로 지정한 값이다. 즉 x축 이동량은 setRange() 설정과 대응되며, setTickCount() 설정값과는 대응되지 않는다.

태그: QtCharts Qt QChart QChartView C++

9월 13일 21:20에 게시됨