Реклама

Qt/C++ - Урок 030. QCustomPlot - быстрый старт в работе с графиками

TutorialQtQCPCurve, QCPItemTracer, QCustomPlot, Qt5, график313

Постоянно слышу про QCustomPlot относительно работы с графиками в Qt , но по началу сделал в одном своём приложении свои велосипеды, а сейчас в свободную минутку решил познакомиться с этой библиотекой. Показалось, что всё-таки в ней есть ещё над чем работать разработчикам, но на данный момент она обладает очень мощным функционалом. Поработал с ней с удовольствием и набросал свой код для баловства и изучения.

А теперь ближе к делу. Программа в примере должна выполнять следующий функционал:

  1. Отрисовать один график по нескольким точкам;
  2. Иметь вертикальную передвигаемую линию;
  3. За вертикальной линией будет следовать трассировщик, который будет вставать в ближайшие к точки графика от вертикальной линии.

Структура проекта для QCustomPlot

В структуру проекта входят следующие файлы:

  • QCustomPlotExample.pro - профайл проекта;
  • mainwindow.h - заголовочный файл основного окна приложения;
  • mainwindow.cpp - файл исходных кодов основного окна приложения;
  • main.cpp - основной файл исходных кодов приложения;
  • qcustomplot.h - заголовочный файл библиотеки QCustomPlot;
  • qcustomplot.cpp - файл исходных кодов QCustomPlot.

Листинги файлов библиотеки приводить не буду, они очень большие и Мы в них не лезем, просто добавляем файлы в проект и подключаем заголовочный файл в классе MainWindow.

mainwindow.h

В заголовочной файле класса MainWindow подключаем библиотеку QCustomPlot, а также объявляем само полотно, вертикальную линии в качестве объекта класса 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;      // Объявляем объект QCustomPlot
    QCPCurve *verticalLine;     // Объявляем объект для вертикальной линии
    QCPItemTracer *tracer;      // Трасировщик по точкам графика

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

#endif // MAINWINDOW_H

mainwindow.cpp

QCustomPlot может отдавать сигналы клика и передвижения мыши, и в обычных условиях он всегда вызывает сигнала передвижения мыши над собой, поэтому необходимо проверять, а нажата ли кнопка мыши, чтобы делать перерисовку содержимого полотна. В том случае, если кнопка мыши нажата, то Мы будем передвигать вертикальную линию, а за ней будет перескакивать трассировщик, выдавая в поле lineEdit координаты своего местоположения. То есть в какую точку графика он в данный момент установлен. Отмечу, что трассировщик проходит не по всем точкам графика, а только по тем, которые были загружены с помощью QVector .

Установка объекта QCustomPlot в окно приложения производится не через графический дизайнер IDE QtCreator , а в исходном коде приложения.

#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); // ... и устанавливаем

    // Инициализируем вертикальную линию
    verticalLine = new QCPCurve(wGraphic->xAxis, wGraphic->yAxis);

    // Подключаем сигналы событий мыши от полотна графика к слотам для их обработки
    connect(wGraphic, &QCustomPlot::mousePress, this, &MainWindow::slotMousePress);
    connect(wGraphic, &QCustomPlot::mouseMove, this, &MainWindow::slotMouseMove);

    // создаём вектора для вертикальной линии
    QVector<double> x(2) , y(2);
        x[0] = 0;
        y[0] = -50;
        x[1] = 0;
        y[1] = 50;

    wGraphic->addPlottable(verticalLine);   // Добавляем линию на полотно
    verticalLine->setName("Vertical");      // Устанавливаем ей наименование
    verticalLine->setData(x, y);            // И устанавливаем координаты

    // создаём вектора для графика
    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);     // Устанавливаем координаты точек графика

    // Инициализируем трассировщик
    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)
{
    // Определяем координату X на графике, где был произведён клик мышью
    double coordX = wGraphic->xAxis->pixelToCoord(event->pos().x());

    // Подготавливаем координаты по оси X для переноса вертикальной линии
    QVector<double> x(2), y(2);
    x[0] = coordX;
    y[0] = -50;
    x[1] = coordX;
    y[1] = 50;

    // Устанавливаем новые координаты
    verticalLine->setData(x, y);

    // По координате X клика мыши определим ближайшие координаты для трассировщика
    tracer->setGraphKey(coordX);

    // Выводим координаты точки графика, где установился трассировщик, в lineEdit
    ui->lineEdit->setText("x: " + QString::number(tracer->position->key()) +
                          " y: " + QString::number(tracer->position->value()));
    wGraphic->replot(); // Перерисовываем содержимое полотна графика
}

void MainWindow::slotMouseMove(QMouseEvent *event)
{
    /* Если при передвижении мыши, ей кнопки нажаты,
     * то вызываем отработку координат мыши
     * через слот клика
     * */
    if(QApplication::mouseButtons()) slotMousePress(event);
}

Итог

В результате проделанной работы Вы получите приложение, которое будет выглядеть так, как показано на ниже следующем рисунке. Также Вы можете увидеть демонстрацию работы приложения в видеоуроке.

Ссылка на скачивание проекта в zip-архиве: QCustomPlot Example

Видеоурок

@EVILEG 30 ноября 2015 г. 19:49

Реклама

Реклама

Комментарии

Комментарии

Только авторизованные пользователи могут оставлять комментарии.
Пожалуйста, Авторизуйтесь или Зарегистрируйтесь

Реклама

Реклама