Evgenii Legotckoi
Evgenii LegotckoiҚар. 30, 2015, 8:49 Т.Ж.

Qt/C++ - Сабақ 030. QCustomPlot - диаграммалармен жұмыс істеудің жылдам бастауы

Мен Qt ішіндегі диаграммалармен жұмыс істеуге қатысты QCustomPlot туралы үнемі естимін, бірақ алғашында мен велосипедтерімді қолданбаларымның бірінде жасадым, енді бос уақытымда осы кітапханамен танысуды жөн көрдім. Өйткені, әзірлеушілер үшін әлі де жұмыс істейтін нәрсе бар сияқты көрінді, бірақ қазіргі уақытта оның өте қуатты функционалдығы бар. Мен онымен қуана жұмыс істедім және еркелетуге және оқуға арналған кодымды сызып алдым.

Ал енді нүктеге жақынырақ. Мысалдағы бағдарлама келесі функцияларды орындауы керек:

  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 мысалы

Бейне оқулық

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Ол саған ұнайды ма? Әлеуметтік желілерде бөлісіңіз!

z
  • Қаң. 23, 2017, 6:30 Т.Ж.

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

Evgenii Legotckoi
  • Қаң. 23, 2017, 10:29 Т.Ж.

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

М
  • Қаз. 20, 2017, 9:30 Т.Ж.

Здравствуйте. Скачал архив, работает. Создал проект и вставил код в 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()) +
^
Скажите пожалуйста, как это исправить!
Evgenii Legotckoi
  • Қаз. 20, 2017, 9:40 Т.Ж.

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


что касается addPlotable, так это отсутсвует инклюд библиотеки, заголовочного файла в mainwindow.h
М
  • Қаз. 20, 2017, 9:43 Т.Ж.

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


Evgenii Legotckoi
  • Қаз. 20, 2017, 10:03 Т.Ж.

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

A
  • Қаз. 23, 2017, 5:25 Т.Ж.

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

Evgenii Legotckoi
  • Қаз. 23, 2017, 5:55 Т.Ж.

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

A
  • Қаз. 23, 2017, 5:57 Т.Ж.

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

Может версия другая? У меня в файле библиотеки вообще нет такого метода.
Evgenii Legotckoi
  • Қаз. 23, 2017, 6:03 Т.Ж.

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

customPlot->graph()->data()->set(timeData);
A
  • Қаз. 23, 2017, 6:09 Т.Ж.

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

Evgenii Legotckoi
  • Қаз. 23, 2017, 6:11 Т.Ж.
Краб то заполнить могу информацией
В смысле QCPGraph ?

QCustomPlot имеет метод addGraph
A
  • Қаз. 23, 2017, 6:15 Т.Ж.

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

A
  • Қаз. 23, 2017, 6:16 Т.Ж.

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

Evgenii Legotckoi
  • Қаз. 23, 2017, 6:20 Т.Ж.

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

А что касается бибилотеки, то скачайте проект из этой статьи . Там в составе проетк есть старая библиотека. Ссылка перед видео.
A
  • Қаз. 23, 2017, 6:25 Т.Ж.

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

h
  • Мамыр 30, 2018, 9:14 Т.Қ.

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.

Docent
  • Қаң. 21, 2020, 2:12 Т.Қ.

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

Docent
  • Жел. 25, 2020, 2:36 Т.Ж.

Доброго времени, это снова я) Имеется ли возможность подключения одного QCPItemTracer ко многим QCPGraph ?
Например у нас на одном QCustomPlot создано множество QCPGraph, делать для каждого их них по одному QCPItemTracer совсем неудобно и громоздко (фильтр для проверки к какому QCPGraph ближе оказался tracer и отключение видимости всех остальных... ну так себе), создание +1 невидимого QCPGraph содержащего в себе данные всех предыдущих - накладно (сотни тысяч точек в каждом). Отсюда и возник вопрос - как используя один QCPItemTracer перемещаться по всем QCPGraph.


(на изображении небольшой пример, tracer остался где-то далеко на 1м graph())

Пікірлер

Тек рұқсаты бар пайдаланушылар ғана пікір қалдыра алады.
Кіріңіз немесе Тіркеліңіз
OI
  • Ora Iro
  • Жел. 24, 2024, 6:38 Т.Ж.

C++ - Тест 001. Первая программа и типы данных

  • Нәтиже:40ұпай,
  • Бағалау ұпайлары-8
AD

C++ - Тест 004. Указатели, Массивы и Циклы

  • Нәтиже:50ұпай,
  • Бағалау ұпайлары-4
m
  • molni99
  • Қаз. 26, 2024, 1:37 Т.Ж.

C++ - Тест 004. Указатели, Массивы и Циклы

  • Нәтиже:80ұпай,
  • Бағалау ұпайлары4
Соңғы пікірлер
ИМ
Игорь МаксимовҚар. 22, 2024, 11:51 Т.Ж.
Django - Оқулық 017. Теңшелген Django кіру беті Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
Evgenii Legotckoi
Evgenii LegotckoiҚаз. 31, 2024, 2:37 Т.Қ.
Django - Сабақ 064. Python Markdown кеңейтімін қалай жазуға болады Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
A
ALO1ZEҚаз. 19, 2024, 8:19 Т.Ж.
Qt Creator көмегімен fb3 файл оқу құралы Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
ИМ
Игорь МаксимовҚаз. 5, 2024, 7:51 Т.Ж.
Django - Сабақ 064. Python Markdown кеңейтімін қалай жазуға болады Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas5Шілде 5, 2024, 11:02 Т.Ж.
QML - Сабақ 016. SQLite деректер қоры және онымен QML Qt-та жұмыс істеу Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
Енді форумда талқылаңыз
Evgenii Legotckoi
Evgenii LegotckoiМаусым 24, 2024, 3:11 Т.Қ.
добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
t
tonypeachey1Қар. 15, 2024, 6:04 Т.Ж.
google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
NSProject
NSProjectМаусым 4, 2022, 3:49 Т.Ж.
Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…
9
9AnonimҚаз. 25, 2024, 9:10 Т.Ж.
Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

Бізді әлеуметтік желілерде бақылаңыз