Введение
В отличие от QCustomPlot, Qt Charts — официальный модуль Qt (доступный как коммерческое расширение в более старых версиях, и часть открытой экосистемы Qt в более новых), интегрированный с системой сборки Qt и поддерживающий как Qt Widgets, так и QML из одной базы кода. Это делает его естественным выбором, когда не хотят добавлять внешнюю зависимость и важна нативная интеграция с обеими UI-технологиями Qt. В статье построим график на основе Qt Charts в обоих вариантах — Widgets и QML.
Концепция
В Qt Widgets центральный класс — QChart, который содержит один или несколько объектов-серий (QLineSeries, QBarSeries, QPieSeries и другие), отображаемый через QChartView (наследник QGraphicsView). В QML аналогичная функциональность доступна через элемент ChartView с дочерними элементами-сериями (LineSeries, BarSeries и так далее), что даёт декларативный, привычный для QML стиль описания графика прямо в дереве компонентов интерфейса.
Пример кода
// --- Вариант на Qt Widgets ---
#include <QApplication>
#include <QtCharts/QChartView>
#include <QtCharts/QLineSeries>
#include <QtCharts/QValueAxis>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
auto *series = new QLineSeries();
series->setName("Температура");
for (int hour = 0; hour < 24; ++hour) {
const double temperature = 10 + 8 * std::sin((hour - 6) * M_PI / 12.0);
series->append(hour, temperature);
}
auto *chart = new QChart();
chart->addSeries(series);
chart->setTitle("Температура за сутки");
chart->createDefaultAxes();
chart->axes(Qt::Horizontal).first()->setTitleText("Час");
chart->axes(Qt::Vertical).first()->setTitleText("°C");
QChartView chartView(chart);
chartView.setRenderHint(QPainter::Antialiasing);
chartView.resize(640, 400);
chartView.show();
return app.exec();
}
// --- Вариант на QML ---
import QtQuick
import QtCharts
ApplicationWindow {
visible: true
width: 640
height: 400
ChartView {
anchors.fill: parent
title: "Температура за сутки"
antialiasing: true
LineSeries {
name: "Температура"
XYPoint { x: 0; y: 8 }
XYPoint { x: 6; y: 2 }
XYPoint { x: 12; y: 18 }
XYPoint { x: 18; y: 14 }
XYPoint { x: 23; y: 9 }
}
}
}
Пояснения к коду
В варианте на Qt Widgets QLineSeries заполняется парами значений через append(x, y), затем добавляется в QChart через addSeries(). Вызов createDefaultAxes() автоматически создаёт оси X и Y с диапазонами, подобранными по данным серии — без него график был бы построен без видимых осей и подписей. QChartView оборачивает QChart для отображения в обычной иерархии виджетов, аналогично любому другому виджету.
В QML-варианте та же концептуальная структура выражена декларативно: ChartView — корневой контейнер графика, а LineSeries с дочерними XYPoint описывают данные прямо в дереве QML-компонентов, без необходимости в отдельном императивном коде для заполнения серии — это особенно удобно, когда данные графика статичны или меняются через привязки к моделям, а не императивно в цикле.
Подводные камни
- Производительность Qt Charts на очень больших объёмах данных (десятки тысяч точек, особенно при частом обновлении в реальном времени) заметно ниже, чем у специализированных библиотек типа QCustomPlot — для задач с высокочастотным обновлением больших датасетов (осциллографы, потоковая телеметрия) Qt Charts может не справляться с нужной частотой кадров.
- Различия API между вариантами для Widgets и QML не являются полностью симметричными — некоторые возможности доступны только в одном из двух вариантов API, что может вызывать путаницу при попытке найти аналогичную функциональность в документации, написанной для другого варианта использования.
- Модуль Qt Charts требует отдельного подключения компонента в CMake (
find_package(Qt6 COMPONENTS Charts)и соответствующий импорт в QML) — в более старых версиях Qt этот модуль был частью коммерческой подписки, и стоит проверить актуальный статус лицензирования для конкретной используемой версии Qt в проекте. - Ограниченная гибкость кастомизации внешнего вида по сравнению с полностью самостоятельной отрисовкой через
QPainter. Если требуется визуально нестандартный график, сильно отличающийся от предустановленных стилей Qt Charts, может оказаться проще и предсказуемее реализовать кастомную отрисовку напрямую (как в статье про кастомные графики наQPainter), чем пытаться «подогнать» внешний вид Qt Charts под нетипичные требования дизайна.