Qt/C++ - Lesson 030. QCustomPlot – Introduction into working with charts

QCPCurve, QCPItemTracer, QCustomPlot, Qt5, график

Constantly I hear about QCustomPlot on working with graphs to Qt, but on the start of the made in one my application I worked without special libraries, and now in a same moment decided to get acquainted with this library. It seemed that after all it has more work to developers, but at the moment she has a very powerful functionality. I work with her with pleasure and sketched their code for pampering and studying.

Now, Let`s learn it. The program in the example must perform the following functions:

  1. Draw the one graph on several points;
  2. Have a vertically movable line;
  3. For a vertical line will follow the router, which will be up to the next point on the graph of the vertical line.

Project Structure

  • QCustomPlotExample.pro - the profile of the project;
  • mainwindow.h - header file of the main application window;
  • mainwindow.cpp - file source code of the main application window;
  • main.cpp - the main file of the application source code;
  • qcustomplot.h - header QCustomPlot library file;
  • qcustomplot.cpp - QCustomPlot source file.

Listings of the library file, they are very large and we did not climb in them, just add the files to the project and connect the header file in the MainWindow class.

mainwindow.h

The MainWindow class header files are included library QCustomPlot, as well as to declare the plot, vertical line as the object class and tracer QCPCurve QCPItemTracer.

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <qcustomplot.h>
#include <QDebug>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
    QCustomPlot *wGraphic;      
    QCPCurve *verticalLine;     
    QCPItemTracer *tracer;      

private slots:
    void slotMousePress(QMouseEvent * event);
    void slotMouseMove(QMouseEvent * event);
};

#endif // MAINWINDOW_H

mainwindow.cpp

QCustomPlot can give signals to mouse clicks and movement, and under normal circumstances he always causes the mouse movement signal over the other, so you need to check whether a mouse button is pressed to make a redraw the contents of the web. In that case, if the mouse button is pressed, then we will move the vertical line, and after it will skip tracer, posing in a field lineEdit your location. That is, in the graph which point it is currently installed. Note that the router does not pass along all points of the graph, but only for those that have been downloaded via QVector .

Installing QCustomPlot object in the application window is made not through the IDE QtCreator graphic designer, and in the original application code.

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QApplication>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
  //  this->setGeometry(300,100,640,480);

    wGraphic = new QCustomPlot();
    ui->gridLayout->addWidget(wGraphic,1,0,1,1);

    // Init vertical Line
    verticalLine = new QCPCurve(wGraphic->xAxis, wGraphic->yAxis);

    connect(wGraphic, &QCustomPlot::mousePress, this, &MainWindow::slotMousePress);
    connect(wGraphic, &QCustomPlot::mouseMove, this, &MainWindow::slotMouseMove);

    // creating a vector for the vertical line
    QVector<double> x(2) , y(2);
        x[0] = 0;
        y[0] = -50;
        x[1] = 0;
        y[1] = 50;

    wGraphic->addPlottable(verticalLine);   // Adding a line on the canvas
    verticalLine->setName("Vertical");      // Set its name
    verticalLine->setData(x, y);            // And sets the coordinates

    // creating of the graphics vector
    QVector<double> x1(5) , y1(5);
        x1[0] = -45;
        y1[0] = -43;
        x1[1] = 46;
        y1[1] = 42;
        x1[2] = -25;
        y1[2] = -24;
        x1[3] = -12;
        y1[3] = 10;
        x1[4] = 25;
        y1[4] = 26;

    wGraphic->addGraph(wGraphic->xAxis, wGraphic->yAxis);
    wGraphic->graph(0)->setData(x1,y1);     // Set the coordinates of the points chart

    // Initialize the router
    tracer = new QCPItemTracer(wGraphic);
    tracer->setGraph(wGraphic->graph(0));   

    wGraphic->xAxis->setLabel("x");
    wGraphic->yAxis->setLabel("y");

    wGraphic->xAxis->setRange(-50,50);
    wGraphic->yAxis->setRange(-50,50);

    wGraphic->replot();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::slotMousePress(QMouseEvent *event)
{
    // Find X coordinate on the graph where the mouse being clicked
    double coordX = wGraphic->xAxis->pixelToCoord(event->pos().x());

    // Prepare the X axis coordinates on the vertical transfer line
    QVector<double> x(2), y(2);
    x[0] = coordX;
    y[0] = -50;
    x[1] = coordX;
    y[1] = 50;

    // Sets the new coordinates
    verticalLine->setData(x, y);

    // According to the X coordinate mouse clicks define the next position for the tracer
    tracer->setGraphKey(coordX);

    // Output the coordinates of the point of the graph, where the router is setted in QLineEdit
    ui->lineEdit->setText("x: " + QString::number(tracer->position->key()) +
                          " y: " + QString::number(tracer->position->value()));
    wGraphic->replot(); // redraw
}

void MainWindow::slotMouseMove(QMouseEvent *event)
{
    if(QApplication::mouseButtons()) slotMousePress(event);
}

Result

As a result of the work done you will receive an application, which will appear as shown in the following figure.

Link to the project download in zip-archive: QCustomPlot Example

Video

We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.
Support the author Donate
z
  • #
  • Jan. 23, 2017, 5:30 a.m.

А почему именно QCustomPlot а не QCharts?

Потому, что на момент написания статьи QCharts был только в коммерческой платной версии.

M
  • #
  • Oct. 20, 2017, 8:30 a.m.

Здравствуйте. Скачал архив, работает. Создал проект и вставил код в 2 файла, ка вы указали - не работает.  В mainwindow.cpp выдает 3 ошибки:

C:\Qt\project\3\mainwindow.cpp:14: ошибка: 'class Ui::MainWindow' has no member named 'gridLayout'
ui->gridLayout->addWidget(wGraphic,1,0,1,1); // ... и устанавливаем
^
C:\Qt\project\3\mainwindow.cpp:30: ошибка: 'class QCustomPlot' has no member named 'addPlottable'
wGraphic->addPlottable(verticalLine);   // Добавляем линию РЅР° полотно
^
C:\Qt\project\3\mainwindow.cpp:91: ошибка: 'class Ui::MainWindow' has no member named 'lineEdit'
ui->lineEdit->setText("x: " + QString::number(tracer->position->key()) +
^
Скажите пожалуйста, как это исправить!

ui->lineEdit и ui->gridLayout - это объекты, которые должны были быть созданы в графическом дизайнере. ui - это объект графического интерфейса. Их у вас просто нет, поработайте с графическим дизайнером, чтобы создать его.


что касается addPlotable, так это отсутсвует инклюд библиотеки, заголовочного файла в mainwindow.h
M
  • #
  • Oct. 20, 2017, 8:43 a.m.

Но почему вы это не описали? Не могли бы вы описать.


Использование дизайнера в Qt Creator и использование ui файлов является распространённой практикой в Qt фреймворке.
Написать отдельную статью про то, что это такое? - может быть.
Описывать в каждой статье основы? - нет. Не о том статья.

A

такая же ошибка с методом addPlottable. Инклуд проблему не решил.

Куда инклюд писали?

A

Прописал в заголовочном файле mainwindow.h

Может версия другая? У меня в файле библиотеки вообще нет такого метода.

То есть вы использовали последнюю версию библиотеки с сайта разработчика QCustomPlot?
Да, вы правы.. я посмотрел документацию у разработчика библиотеки. Он выпустил новую версию. И там отсутсвует данный метод.
Там сейчас делатся через QCPGraph, через установку данных через его метод data()

customPlot->graph()->data()->set(timeData);
A

Спасибо за информацию, а как же теперь пользоваться QCPCurve и другими типами? Краб то заполнить могу информацией, а как добавить её на customPlot?

Краб то заполнить могу информацией
В смысле QCPGraph ?

QCustomPlot имеет метод addGraph
A

Меня интересует именно параметрические кривые, я могу их строить с помощью QCPTGraph, но их отображение имеет отклонения(разрывы в функции, неточности). Я полагал QCPCurve сможет решить эту проблему, но как видите из за отсутствия метода addPlottable не могу сообразить как кривую добавить на график.

A

Или может скачать старую версию библиотеки? Вы не могли бы скинуть файлы старой библиотеки мне на почту?

Ну параметрические кривые могу быть вполне отображены и новой библиотекой, на оф. сайте есть пара примеров параметрических кривых.

А что касается бибилотеки, то скачайте проект из этой статьи . Там в составе проетк есть старая библиотека. Ссылка перед видео.
A

Спасибо, разберёмся)

h

Here the tracer is moving by Mouse Press And Mouse Move.How to move the Tracer by using the QTimer.The tracer has to be move from origin to end point automatically/programically by using QTimer.

Полезная статья. Как всегда - то что надо.
Добавлю ещё маленькую полезность - после установки tracer (88 строка) и перед выводом значений в lineEdit (91 строка) стоит добавить updatePosition иначе будут отображаться значения из предыдущей позиции.

Comments

Only authorized users can post comments.
Please, Log in or Sign up
How to become an author?

Contribute to the evolution of the EVILEG community.

Learn how to become a site author.

Learn it
Donate

Good day, Dear Users!!!

I am Evgenii Legotckoi, developer of EVILEG. And it is my hobby project, which helps to learn programming another programmers and developers

If the site helped you, and you want also support the development of the site, than you can donate by following ways

PayPalYandex.Money
Timeweb

Let me recommend you the excellent hosting on which EVILEG is located.

For many years, Timeweb has been proving his stability.

For projects on Django I recommend VDS hosting

View Hosting Timeweb
AS
May 26, 2020, 11:29 a.m.
Artem Sun-Dun-Chan

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:50points,
  • Rating points-4
MN
May 25, 2020, 11:33 a.m.
Mitja Nagibin

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:50points,
  • Rating points-4
f
May 25, 2020, 5:05 a.m.
falcon

C++ - Test 001. The first program and data types

  • Result:66points,
  • Rating points-1
Last comments
May 28, 2020, 3:14 p.m.
Evgenij Legotskoj

Qt/C++ - Lesson 039. How to paint stroke in QSqlTableModel by value in the column?

Ну в моём примере, который в статье сработало так model->setData(model->index(1, 1), 7); Поскольку model->index(1, 0) - это индекс колонки id, которая скрыта, поэтому…
MA
May 28, 2020, 3:08 p.m.
Mihail A

Qt/C++ - Lesson 039. How to paint stroke in QSqlTableModel by value in the column?

Спасибо, завтра првоерю. А model->setData(model->index(1, 0), 7); Тоже заработало?
May 28, 2020, 3:06 p.m.
Evgenij Legotskoj

Qt/C++ - Lesson 039. How to paint stroke in QSqlTableModel by value in the column?

Да, метод data всё-таки влиял, я переписал его так и заработало удаление QVariant TableModel::data(const QModelIndex &idx, int role) const{ if (role == Qt::BackgroundColorRole) {…
May 28, 2020, 2:49 p.m.
Evgenij Legotskoj

Django - Tutorial 011. Adding comments to the site based on Django

Он более функциональный и его функционал объективно лучше поддерживается Django. Из первого, что приходит на ум: Это наличие полей типа Array Поддержка полей для JSON …
May 28, 2020, 2:42 p.m.
progammist

Django - Tutorial 011. Adding comments to the site based on Django

а в чем явное преимущество postgresql над mysql?)
Now discuss on the forum
IP
May 29, 2020, 1:55 a.m.
Igor' Poroshin

QTablwView + QSqlQueryModel скрыть пустой столбец

Да, понятно. В данном случае лучше использовать серверную процедуру (если такие поддерживаются), в которой будет проверяться наличие всех пустых строк у нужного столбца и вызываться соответ…
RG
May 28, 2020, 6:21 p.m.
Rovshan Gurbanov

Сборка под старые версии Android

У меня SDK почти все версии есть, NDK есть версии 10, 17, 21. Но собирается приложение только с NDK v21 под Android версии 7.0 и выше Версия Qt у меня 5.14.2
May 28, 2020, 7:58 a.m.
Evgenij Legotskoj

Освобождение памяти QMainWindow::setCentralWidget

Да, соглашусь. Просто удаление происходит позже, а не сразу.
May 28, 2020, 5:43 a.m.
Mihailll

При подключении к git как указать пароль?

Нужно сделать ssh-keygen и потом полученый из файла код скопировать в ssh ключ в бикбакете
F
May 28, 2020, 1:42 a.m.
Fidan

QML

Да, проблема ушла, спасибо.
About
Services
© EVILEG 2015-2020
Recommend hosting TIMEWEB