QCustomPlot — графики на разных вкладках

В настоящее время я получаю информацию через последовательную связь, см. ниже пример поступающих данных:

"A Ch1:45.23 Ch2:23.58 Ch3:12.45 Ch4:1.56"
"B Ch1:12.63 Ch2:15.45 Ch3:6.23 Ch4:45.32"
"C Ch1:22.20 Ch2:3.85 Ch3:2.45 Ch4:51.58"
"D Ch1:21.25 Ch2:2.58 Ch3:12.13 Ch4:61.52"
"A Ch1:4.27 Ch2:25.52 Ch3:22.15 Ch4:31.56" etc.

Теперь то, что я пытаюсь сделать, это взять все входящие данные и построить их. Поэтому для этого я создал приложение Qt с несколькими вкладками.

Tab 1 - All Sections
Tab 2 - Section A
Tab 3 - Section B
Tab 4 - Section C
Tab 5 - Section D

Я добавил виджет на каждую вкладку и повысил его до QCustomPlot.

Я настраиваю каждый QCustomPlot следующим образом:

// Would be nice to improve this
setupGraph(ui->sectionA);   // Setup Section A QCustomPlot
setupGraph(ui->sectionB);   // Setup Section B QCustomPlot
setupGraph(ui->sectionC);   // Setup Section C QCustomPlot
setupGraph(ui->sectionD);   // Setup Section D QCustomPlot

void MainWindow::setupGraph(QCustomPlot *graphPlot)
{
    QStringList legend;

    legend << "Load Cell 1" << "Load Cell 2" << "Load Cell 3" << "Load Cell 4" << "Total Weight";

    graphPlot->legend->setVisible(true);
    graphPlot->legend->setFont(QFont("Helvetica",9));

    for (int i = 0; i < legend.size(); i++)
    {
        graphPlot->addGraph();
        graphPlot->graph(i)->setName(legend[i]);
        graphPlot->graph(i)->setLineStyle(QCPGraph::lsLine);
    }

    graphPlot->graph(0)->setPen(QPen(Qt::blue));
    graphPlot->graph(1)->setPen(QPen(Qt::red));
    graphPlot->graph(2)->setPen(QPen(Qt::green));
    graphPlot->graph(3)->setPen(QPen(Qt::darkCyan));
    graphPlot->axisRect()->setupFullAxesBox();
    graphPlot->xAxis->setRange(-10,0);
    graphPlot->yAxis->setRange(0,5);
    connect(graphPlot->xAxis, SIGNAL(rangeChanged(QCPRange)), graphPlot->xAxis2, SLOT(setRange(QCPRange)));
    connect(graphPlot->yAxis, SIGNAL(rangeChanged(QCPRange)), graphPlot->yAxis2, SLOT(setRange(QCPRange)));
}

Как только это будет сделано, я открываю последовательный порт и подключаюсь к сигналу ReadyRead. Каждый раз, когда появляются новые данные, я проверяю, откуда берутся новые данные, и хочу отобразить их.

void MainWindow::readData()
{
    QByteArray serialData;

    if (serial->canReadLine())
        serialData = serial->readLine();

    if (serialData.startsWith('A'))
        realtimePlot(ui->sectionA) // Plot the data for Section A
    if (serialData.startsWith('B'))
        realtimePlot(ui->sectionB) // Plot the data for Section B
    if (serialData.startsWith('C'))
        realtimePlot(ui->sectionC) // Plot the data for Section C
    if (serialData.startsWith('D'))
        realtimePlot(ui->sectionD) // Plot the data for Section D
}

Я опустил код, который извлекает фактические значения из входящих данных.

void MainWindow::realtimePlot(QCustomPlot *graphPlot)
{
    range_y_min = 0;
    range_y_max = 100;
    // Add data to the lines
    graphPlot->graph(0)->addData(key_x, ch1);
    graphPlot->graph(1)->addData(key_x, ch2);
    graphPlot->graph(2)->addData(key_x, ch3);
    graphPlot->graph(3)->addData(key_x, ch4);
    // Remove data outside the visible range
    graphPlot->graph(0)->removeDataBefore(key_x-10);
    graphPlot->graph(1)->removeDataBefore(key_x-10);
    graphPlot->graph(2)->removeDataBefore(key_x-10);
    graphPlot->graph(3)->removeDataBefore(key_x-10);
    // Make the x-axis range scroll with the data (at a constant range size of 10):
    graphPlot->xAxis->setRange(key_x+1/frequency,10,Qt::AlignRight);
    // Set the range of the y-axis
    graphPlot->yAxis->setRange(range_y_min,range_y_max+5);
    // Replot the graph
    graphPlot->replot();
    key_x += 1/frequency; // defines horizontal gap between two data points on graph
}

Теперь я надеюсь, что removeDataBefore(key_x-10) удалит все данные до этого момента, потому что моя память довольно быстро заполняется. key_x и частота определены где-то еще.

Код, который у меня сейчас есть (похожий на приведенный выше), действительно работает, но через некоторое время все начинает тормозить и все задерживается. Поэтому я не совсем уверен, что не так или причина этого. Я также хотел бы знать, как использовать графики для раздела A, раздела B, раздела C и раздела D на вкладке 1, так как я не хочу создавать еще 4 виджета на 1-й вкладке для построения данных.

Надеюсь, я дал вам достаточно исходной информации.

Спасибо за вашу помощь заранее.


person skandebaba    schedule 25.09.2014    source источник


Ответы (1)


Что касается вашего второго вопроса, это легко. Просто добавьте графики в один виджет (и, возможно, измените цвет и т. д.)

Просто вызовите addGraph() для одного объекта графика.

Это также может увеличить вашу скорость, поскольку вы не будете вызывать replot() для каждого объекта графика.

person don_q    schedule 01.10.2014
comment
Я знаю, что могу добавить несколько графиков в один виджет, но я не совсем уверен, как получить точечный график и нормальный график для одного виджета, а затем как заставить их оба работать в режиме реального времени. Во всяком случае, чтобы немного ускорить процесс, я использовал таймер и вызывал его время от времени. Вроде немного ускорил. - person skandebaba; 13.10.2014
comment
Вы хотите, чтобы разброс и нормаль были в пределах одного графика или одного и того же виджета? У меня была аналогичная проблема, я использовал отдельный поток для чтения данных (в вашем случае серийный номер из com-порта), и этот поток затем посылает сигнал необходимым окнам для обновления. Таким образом, я обновляю только при поступлении новых данных, а не на основе произвольного таймера. - person don_q; 14.10.2014
comment
Я хотел бы иметь точечный график и нормальный график в одном и том же виджете (поэтому только один QWidget повышен до QCustomPlot и иметь оба графика в этом виджете). Это было бы хорошим решением, я никогда раньше не использовал потоки, поэтому я не знаю, как использовать отдельный поток для чтения данных и другой поток для обновления необходимых окон. Знаете ли вы какие-нибудь хорошие ссылки, которые помогут мне начать работу с этим? - person skandebaba; 16.10.2014