Нарисуйте 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(); тогда линии не удаляются из текущего графика, а перекрываются.

0 ответов

Другие вопросы по тегам