Нарисуйте QwtPlotCurve с увеличением / добавлением данных
Я пытаюсь построить (в реальном времени) некоторые линии для некоторых данных датчика, не удаляя более старые линии из объекта QwtPlot из прошлого.
Мой QwtPlot инициализирован:
m_Gui.guiQwtPlot->setTitle(title);
m_Gui.guiQwtPlot->setCanvasBackground(* new QBrush(Qt::black));
m_Gui.guiQwtPlot->setAxisScale(QwtPlot::yLeft, -30.0, 30.0);
m_Gui.guiQwtPlot->insertLegend(new QwtLegend());
m_Gui.guiQwtPlot->legend()->setFont(fontNormal);
m_Gui.guiQwtPlot->setFont(fontNormal);
m_Gui.guiQwtPlot->setAxisFont(QwtPlot::yLeft, fontNormal);
m_Gui.guiQwtPlot->setAxisFont(QwtPlot::xBottom, fontNormal);
m_Gui.guiQwtPlot->setAxisScaleDraw(QwtPlot::xBottom, new TimeScaleDraw(QTime::currentTime()));
m_Gui.guiQwtPlot->setAxisLabelRotation(QwtPlot::xBottom, 0.0);
m_Gui.guiQwtPlot->setAxisLabelAlignment(QwtPlot::xBottom,Qt::AlignLeft|Qt::AlignBottom);
m_Gui.guiQwtPlot->setAxisTitle(QwtPlot::xBottom, axisTitleBottom);
m_Gui.guiQwtPlot->setAxisTitle(QwtPlot::yLeft, axisTitleLeft);
QwtPlotMagnifier *plotM= new QwtPlotMagnifier(m_Gui.guiQwtPlot->canvas());
plotM->setMouseButton(Qt::NoButton);
QwtPlotPanner *plotP= new QwtPlotPanner(m_Gui.guiQwtPlot->canvas());
Каждые 5 секунд я получаю новые данные от датчиков и для каждого датчика я создаю QwtPlotCurve, а затем обновляю свои данные датчика с помощью setSamples (points)
void pcaPlotting::updateDataSlot(QString sensorId, QPolygonF points)
{
QMap<QString, QwtPlotCurve*> m_PlotC;
QStringList m_SensorNameList
for(unsigned int i= 0; i< m_SensorNameList.count(); ++i)
{
m_PlotC[m_SensorNameList.at(i)]= new QwtPlotCurve();
m_PlotC[m_SensorNameList.at(i)]->setRenderHint(QwtPlotItem::RenderAntialiased, true);
m_PlotC[m_SensorNameList.at(i)]->setCurveAttribute(QwtPlotCurve::Fitted);
}
m_PlotC[sensorId]->setSamples(points);
emit updatePlotSignal(m_PlotC);
}
Наконец, я обновляю свой график по сигналу / слоту
void mainGui::updatePlotSlot(QMap<QString, QwtPlotCurve*> plotC)
{
for(QMap<QString, QwtPlotCurve*>::iterator it= plotC.begin(); it!= plotC.end(); ++it)
{
plotC[it.key()]->attach(m_Gui.guiQwtPlot);
m_Gui.guiQwtPlot->replot();
}
}
К сожалению, он отображает только те данные, которые я получил за 5 секунд, а затем строки заменяются новыми данными через 5 секунд. Что мне делать, чтобы линии не заменялись и не увеличивались до тех пор, пока я не перестану рисовать?
Спасибо за любую помощь.
Отредактированный вопрос
Я адаптировал мой код выше для примера реального времени QwtPlotDirectPainter.
При инициализации QwtPlot я добавил дополнительные функции canvas()->setAttribute() и setAutoReplot():
void guiMain::createPlot(QStringList m_SensorNameList)
{
m_Gui.guiQwtPlot->setTitle(title);
m_Gui.guiQwtPlot->setCanvasBackground(* new QBrush(Qt::black));
m_Gui.guiQwtPlot->setAxisScale(QwtPlot::yLeft, -30.0, 30.0);
m_Gui.guiQwtPlot->insertLegend(new QwtLegend());
m_Gui.guiQwtPlot->legend()->setFont(fontNormal);
m_Gui.guiQwtPlot->setFont(fontNormal);
m_Gui.guiQwtPlot->setAxisFont(QwtPlot::yLeft, fontNormal);
m_Gui.guiQwtPlot->setAxisFont(QwtPlot::xBottom, fontNormal);
m_Gui.guiQwtPlot->setAxisScaleDraw(QwtPlot::xBottom, new TimeScaleDraw(QTime::currentTime()));
m_Gui.guiQwtPlot->setAxisLabelRotation(QwtPlot::xBottom, 0.0);
m_Gui.guiQwtPlot->setAxisLabelAlignment(QwtPlot::xBottom,Qt::AlignLeft|Qt::AlignBottom);
m_Gui.guiQwtPlot->setAxisTitle(QwtPlot::xBottom, axisTitleBottom);
m_Gui.guiQwtPlot->setAxisTitle(QwtPlot::yLeft, axisTitleLeft);
m_Gui.guiQwtPlot->canvas()->setAttribute(Qt::WA_PaintOutsidePaintEvent, true);
m_Gui.guiQwtPlot->setAutoReplot(false);
QwtPlotMagnifier *plotM= new QwtPlotMagnifier(m_Gui.guiQwtPlot->canvas());
plotM->setMouseButton(Qt::NoButton);
QwtPlotPanner *plotP= new QwtPlotPanner(m_Gui.guiQwtPlot->canvas());
}
Инициализация QwtPlotCurve: для каждого моего датчика я создаю QwtPlotCurve, QwtPlotDirectPainter и добавляю curveData в QwtPlotCurve
void plotting::createPlotCurve(QStringList m_SensorNameList)
{
QMap<QString, QwtPlotCurve*> m_PlotC;
QMap<QString, QwtPlotDirectPainter*> m_DirectPainter;
if(!m_SensorNameList.isEmpty())
{
for(unsigned int i= 0; i< m_SensorNameList.count(); ++i)
{
m_PlotC[m_SensorNameList.at(i)]= new QwtPlotCurve();
m_PlotC[m_SensorNameList.at(i)]->setPen(QPen(QColor(m_ColorList[i]), 1, Qt::SolidLine));
m_PlotC[m_SensorNameList.at(i)]->setRenderHint(QwtPlotItem::RenderAntialiased, true);
m_PlotC[m_SensorNameList.at(i)]->setCurveAttribute(QwtPlotCurve::Fitted);
m_DirectPainter[m_SensorNameList.at(i)]= new QwtPlotDirectPainter();
m_PlotC[m_SensorNameList.at(i)]->setData(new curveData());
}
}
}
Через каждые 5 секунд я получаю новые данные от датчиков, и для каждого датчика я добавляю точки QPolygonF:
void plotting::updateDataSlot(QString sensorId, QPolygonF points)
{
if(m_SensorNameList.contains(sensorId))
{
//m_PlotC[sensorId]->setSamples(points);
curveData *data= static_cast<curveData *>(m_PlotC[sensorId]->data());
data->append(points);
m_DirectPainter[sensorId]->drawSeries(m_PlotC[sensorId], data->size()-100, data->size()-1);
emit updatePlotSignal(m_PlotC);
}
}
обновить сюжет:
void guiMain::updatePlotSlot(QMap<QString, QwtPlotCurve*> plotC)
{
m_Gui.guiQwtPlot->repaint();
for(QMap<QString, QwtPlotCurve*>::iterator it= plotC.begin(); it!= plotC.end(); ++it)
{
plotC[it.key()]->attach(m_Gui.guiQwtPlot);
m_Gui.guiQwtPlot->replot();
}
}
В классе curveData я использую QPolygonF вместо QPointF в функции добавления:
class curveData: public QwtArraySeriesData<QPointF>
{
public:
...
inline void append(const QPolygonF &point)
{
d_samples+= point;
}
...
};
Но как-то нет разницы с предыдущим сюжетом. Строки не добавляются и не удаляются со сцены через 5 сек. каждый раз. Если я закомментирую m_Gui.guiQwtPlot->repaint(); тогда линии не удаляются из текущего графика, а перекрываются.