QCustomPlot Discussion and Comments

Error with QVectorReturn to overview

Hi to all,
I have a Producer Apllication that send 1 point data every 1 millsecond. This Producer is linked, via broker messages, with a Consumer Application. In the Consumer Application i want to display this data in real time, and I change some code in the realtimeDemo example, but something wrong happens.
This is the code interested:

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);


    QPixmap activelogo("C:/Users/Marco/Desktop/CadCamation/Ifacom.JPG");
    ui->label_title->setPixmap(activelogo);
    
	setupDemo();
	connectionReceiver();
    
}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::connectionReceiver(){

	 activemq::library::ActiveMQCPP::initializeLibrary();

	 // Set the URI to point to the IP Address of your broker.
	 //std::string brokerURI = "tcp://92.104.242.137:61613?wireFormat=stomp";	// remote
	 std::string brokerURI = "tcp://localhost:61613?wireFormat=stomp";		// localhost

	// Queue name
	 std::string destName = "IFACOM-CMS";

	 // Queue or Topic 
	 bool useTopics = false;			// true=Topic, false=Queue

	 // SESSION_TRANSACTED or AUTO_ACKNOWLEDGE
	 bool sessionTransacted = false; 

     
	 
     long long startTime = System::currentTimeMillis();

     // ***** Initialisation  **************************************************************
     m_IfacomAmqListener = new IfacomAmqReceiver(brokerURI,useTopics,destName,sessionTransacted);
     m_IfacomAmqListener->initConnection();
	 
	 m_IfacomAmqListener->setMessageListener( this );
}

void MainWindow::onMessage(const Message* message) {

        try {
            const TextMessage* textMessage = dynamic_cast<const TextMessage*> (message);
            std::string text = "";
			
		if (textMessage != NULL) {
                text = textMessage->getText();
				
            } else {
                text = "NOT A TEXTMESSAGE!"; 
           

			
            }
           
            int fieldIndex=message->getIntProperty("field");
            QString qstr = QString::fromStdString(text);
            
			switch(fieldIndex)
            {
              
			case 0:ui->lineEdit->setText(qstr);break;
			case 1:ui->lineEdit_2->setText(qstr);break;
			case 2:ui->lineEdit_3->setText(qstr);break;
            case 3:ui->lineEdit_4->setText(qstr);break;
            case 4:ui->lineEdit_5->setText(qstr);break;
            case 5:ui->lineEdit_6->setText(qstr);break;
            case 6:ui->lineEdit_7->setText(qstr);break;
            case 7:ui->lineEdit_8->setText(qstr);break;
            case 8:ui->lineEdit_9->setText(qstr);break;
            }

            

            bool ok;
            double value0=qstr.toDouble(&ok);
            double key = QDateTime::currentDateTime().toMSecsSinceEpoch()/1000.0;

            static double lastPointKey = 0;
            if (key-lastPointKey > 0.0005) // at most add point every 10 ms
         {
           
            // add data to lines:
            ui->widget_diagram2->graph(0)->addData(key, value0);
            // set data of dots:
            ui->widget_diagram2->graph(2)->clearData();
            ui->widget_diagram2->graph(2)->addData(key, value0);

		   ui->widget_diagram2->graph(0)->rescaleValueAxis();
			//ui->widget_diagram2->graph(1)->rescaleValueAxis(true);
			lastPointKey = key;
         }

		  


            }catch (CMSException& e) {
            e.printStackTrace();
        }
}


void MainWindow::setupDemo()
{
     setupRealtimeDataDemo(ui->widget_diagram2); 
     statusBar()->clearMessage();
     ui->widget_diagram2->replot();
}

void MainWindow::setupRealtimeDataDemo(QCustomPlot *widget_diagram2)
{

  

  // include this section to fully disable antialiasing for higher performance:
  /*
  customPlot->setNotAntialiasedElements(QCP::aeAll);
  QFont font;
  font.setStyleStrategy(QFont::NoAntialias);
  customPlot->xAxis->setTickLabelFont(font);
  customPlot->yAxis->setTickLabelFont(font);
  customPlot->legend->setFont(font);
  */
  widget_diagram2->addGraph(); // blue line
  widget_diagram2->graph(0)->setPen(QPen(Qt::blue));
  widget_diagram2->graph(0)->setBrush(QBrush(QColor(240, 255, 200)));
  widget_diagram2->graph(0)->setAntialiasedFill(false);
  widget_diagram2->addGraph(); // red line
  widget_diagram2->graph(1)->setPen(QPen(Qt::red));
  widget_diagram2->graph(0)->setChannelFillGraph(widget_diagram2->graph(1));

  widget_diagram2->addGraph(); // blue dot
  widget_diagram2->graph(2)->setPen(QPen(Qt::blue));
  widget_diagram2->graph(2)->setLineStyle(QCPGraph::lsNone);
  widget_diagram2->graph(2)->setScatterStyle(QCPScatterStyle::ssDisc);
  widget_diagram2->addGraph(); // red dot
  widget_diagram2->graph(3)->setPen(QPen(Qt::red));
  widget_diagram2->graph(3)->setLineStyle(QCPGraph::lsNone);
  widget_diagram2->graph(3)->setScatterStyle(QCPScatterStyle::ssDisc);

  widget_diagram2->xAxis->setTickLabelType(QCPAxis::ltDateTime);
  widget_diagram2->xAxis->setDateTimeFormat("hh:mm:ss");
  widget_diagram2->xAxis->setAutoTickStep(false);
  widget_diagram2->xAxis->setTickStep(2);
  widget_diagram2->yAxis->setLabel("Average Wire vibrations[%]");
  widget_diagram2->axisRect()->setupFullAxesBox();

  // make left and bottom axes transfer their ranges to right and top axes:
  connect(widget_diagram2->xAxis, SIGNAL(rangeChanged(QCPRange)), widget_diagram2->xAxis2, SLOT(setRange(QCPRange)));
  connect(widget_diagram2->yAxis, SIGNAL(rangeChanged(QCPRange)), widget_diagram2->yAxis2, SLOT(setRange(QCPRange)));

  // setup a timer that repeatedly calls MainWindow::realtimeDataSlot:
  connect(&dataTimer, SIGNAL(timeout()), this, SLOT(realtimeDataSlot()));
  dataTimer.start(1); // Interval 0 means to refresh as fast as possible
}

void MainWindow::realtimeDataSlot()
{
  // calculate two new data points:

  double key = QDateTime::currentDateTime().toMSecsSinceEpoch()/1000.0;
  static double lastPointKey = 0;
  if (key-lastPointKey > 0.0005) // at most add point every 10 ms
  {
    // remove data of lines that's outside visible range:
    ui->widget_diagram2->graph(0)->removeDataBefore(key-8);
    //ui->widget_diagram2->graph(1)->removeDataBefore(key-8);
    // rescale value (vertical) axis to fit the current data:
    ui->widget_diagram2->graph(0)->rescaleValueAxis();
    //ui->widget_diagram2->graph(1)->rescaleValueAxis(true);
    lastPointKey = key;
  }
  // make key axis range scroll with the data (at a constant range size of 8):
  ui->widget_diagram2->xAxis->setRange(key+0.25, 8, Qt::AlignRight);
  ui->widget_diagram2->replot();
}

But after few seconds in which the Receiver Apllication is running, a window error of the RUNTIME LIBRARY is displayed:
Debug Error!
Pogram: folder\folder\folder\debud\Qt5Cored.dll
Module: 5.1.1
File:global\global.cpp
Line:2022
ASSERT failure in QVector<T>::operator[]:"index out of range", fileq:\qt5_workdir\w\s\qtbase\include\qtcore.../src/corelib/tools/qvector.h, line 358

I'm using qt5 5.1.1 and VisualStudio 2012 with plugin addin for qt5


You'll have to run this in debug mode and find out with the stack trace where the QVector asserts.

Other than that, I think it isn't wise sending data packets via inter-process-communication every 1 ms. You should buffer them and transfer them as chunks, e.g. every 50 ms or more. Further it seems like you've not adapted the realtimedatademo logic enough for your application. For example, what use is the line

if (key-lastPointKey > 0.0005)
in your code? It looks like it makes you drop data, is that intended?