简体   繁体   中英

QCustomPlot - Plots in various tabs

I am currently receiving information via serial communication, see below for example of data coming in:

"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.

Now what I am trying to do is take all the incoming data and plot it. So to do this I have created a Qt application with multiple tabs.

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

I added a widget to each tab and promoted it to a QCustomPlot.

I setup each QCustomPlot as follows:

// 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)));
}

Once this is done, I open the serial port and connect to the ReadyRead signal. Every time new data is available, I check where the new data is coming from and I want to plot it.

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
}

I have omitted the code that extracts the actual values from the incoming data.

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
}

Now I am hoping that removeDataBefore(key_x-10) removes all the data before that point, because I find my memory fill up quite quickly. key_x and frequency is defined somewhere else.

The code I currently have (similar to that above) does work, but after a while everything starts slowing down and everything is delayed. So I am not quite sure what is wrong or causing this to happen. I would also like to know how to use the plots for Section A, Section B, Section C and Section D on Tab 1, as I don't want to create another 4 widgets on the 1st tab to plot the data.

I hope I have given you enough background information.

Thank you for your help in advance.

With regard to your second question, its easy. Simply add the graphs to one widget ( and maybe change the color etc )

Just call addGraph() to one graph object.

This may also increase your speed as you won't be calling replot() for each graph object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM