Representation of data on diagram

123 views Asked by At

I'm trying to solve an issue with data representation, I know perfectly (by debug) where the error occurs, but the context is not very simple to define, due to the extension of the code. Starting to explain the work:

  • The program receives datas from a message broker (activeMq)
  • Store these value in a string variable
  • Try to show the values received on a diagram

The relevant code (in my opinion) to understand is this:

#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);
    setupDiagram();
    connectionReceiver();

}

In the previous code be attention to the function setupDiagram implemented here below:

void MainWindow::setupDiagram(){
 ui->widget_diagram2->addGraph();
 ui->widget_diagram2->graph(0)->setPen(QPen(Qt::blue));
 ui->widget_diagram2->graph(0)->setAntialiasedFill(false);
 ui->widget_diagram2->xAxis->setTickLabelType(QCPAxis::ltDateTime);
 ui->widget_diagram2->xAxis->setDateTimeFormat("hh:mm:ss");
 ui->widget_diagram2->xAxis->setAutoTickStep(false);
 ui->widget_diagram2->xAxis->setTickStep(2);
 ui->widget_diagram2->yAxis->setLabel("Average Wire vibrations[%]");
 ui->widget_diagram2->axisRect()->setupFullAxesBox();
 connect(ui->widget_diagram2->xAxis, SIGNAL(rangeChanged(QCPRange)), ui->widget_diagram2->xAxis2, SLOT(setRange(QCPRange)));
 connect(ui->widget_diagram2->yAxis, SIGNAL(rangeChanged(QCPRange)), ui->widget_diagram2->yAxis2, SLOT(setRange(QCPRange)));
 ui->widget_diagram2->replot();
}

After this the diagram is set in the widget object, and is all ok, so at this point the application wait for a data, and once it is received it is passed to the following function like a double type:

void MainWindow::upDateData(double value0){


 double key = QDateTime::currentDateTime().toMSecsSinceEpoch()/1000.0;
  static double lastPointKey = 0;
   if (key-lastPointKey > 0.01) // at most add point every 10 ms
   {

     ui->widget_diagram2->graph(0)->addData(key, value0);
     ui->widget_diagram2->graph(0)->removeDataBefore(key-8);
     ui->widget_diagram2->graph(0)->rescaleValueAxis();
     lastPointKey = key;
   }
  ui->widget_diagram2->xAxis->setRange(key+0.25, 8, Qt::AlignRight);
  ui->widget_diagram2->replot(); <---error here
}

the issue is in the last line, when I try to execute ui->widget_diagram2->replot(), some bad happen and this is the error:

enter image description here

How requested this is the connectionReceiver() function:

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

There are 1 answers

0
Peer S. On

As I understand it your MainWindow is the message listener and therefore recieves data and forwards it directly to upDateData, right? I also assume that the data comes in from a worker thread, not the main UI thread.

Most of the Qt classes are not thread safe and therefore it is usually not safe to call any member function on them from within worker threads.

(Consider what would happen if you change the text of a label from a worker thread while at the same time the UI thread is trying to render that same text.)

In your case now you have to decouple the incoming data from calling members on the widget and this is easiest done by using the signal/slot mechanism.

MainWindow::slot_upDateData(double value) {
  // process value
}

void MainWindow::upDateData(double value0) {
  emit sig_onUpDateData(value0);
}

// If upDateData is called from within the UI thread the slot gets called
// directly. If it is called from within a worker thread then a queued 
// connection will be used. In both cases the slot gets entered from within the
// the UI thread.
connect(this, SIGNAL(sig_onUpDateData(double)), SLOT(slot_upDateData(double)));