我目前通過串行通信接收的信息,請參閱下面的示例數據的未來: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和頻率在其他地方定義。
我目前擁有的代碼(類似於上面的代碼)確實有效,但過了一段時間,一切開始放緩,一切都被推遲。所以我不太確定什麼是錯的或導致這種情況發生。我還想知道如何使用標籤1中的部分A,部分B,部分C和部分D的圖,因爲我不想在第一個標籤上創建另外4個小部件來繪製數據。
我希望我給你足夠的背景資料。
非常感謝您的幫助。
我知道我可以將多個圖形添加到一個窗口小部件,但是我不太確定如何在一個窗口小部件上獲得散點圖和正常圖形,然後如何讓它們都實時顯示。無論如何,爲了加快速度,我使用了一個計時器並每隔一段時間調用一次。似乎加快了一點。 – skandebaba 2014-10-12 21:31:28
你想在同一個地塊或只是相同的小部件內散射和正常嗎?我有一個類似的問題,我用一個單獨的線程來讀取數據(在你的情況下串行COM端口),該線程然後發出一個信號到必要的窗口來更新。這樣我只在新數據進來時更新,而不是基於任意定時器。 – 2014-10-14 14:23:47
我想在同一個窗口小部件中有散點圖和正常情節(所以只有一個QWidget升級到QCustomPlot並且在這個小部件中都有繪圖)。這將是一個很好的解決方案,我之前從未使用線程,所以我不知道如何去使用單獨的線程來讀取數據,而使用另一個線程來更新必要的窗口。你知道有什麼好的鏈接來幫助我開始這個嗎? – skandebaba 2014-10-16 02:23:52