Представление данных на диаграмме

Я пытаюсь решить проблему с представлением данных, я прекрасно знаю (путем отладки), где происходит ошибка, но контекст не очень прост для определения из-за расширения кода. Начинаю объяснять работу:

  • Программа получает данные от брокера сообщений (activeMq)
  • Сохраните эти значения в строковой переменной
  • Попробуйте показать значения, полученные на диаграмме

Соответствующий код (на мой взгляд), чтобы понять это:

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

}

В предыдущем коде обратите внимание на функцию setupDiagram, реализованную здесь ниже:

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

После этого диаграмма устанавливается в объекте виджета, и все в порядке, поэтому в этот момент приложение ожидает данные, и как только они получены, они передаются следующей функции типа двойного типа:

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
}

проблема в последней строке, когда я пытаюсь выполнить ui->widget_diagram2->replot()случается что-то плохое, и это ошибка:

введите описание изображения здесь

Как запрошено это функция connectionReceiver ():

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

2

Решение

Насколько я понимаю, ваше MainWindow является прослушивателем сообщений и, следовательно, получает данные и перенаправляет их непосредственно в upDateData, верно? Я также предполагаю, что данные поступают из рабочего потока, а не из основного потока пользовательского интерфейса.

Большинство классов Qt не безопасно и, следовательно, это обычно небезопасно вызывать на них какие-либо функции-члены из рабочих потоков.

(Подумайте, что произойдет, если вы измените текст метки из рабочего потока, в то время как поток пользовательского интерфейса пытается отобразить этот же текст.)

В вашем случае теперь вы должны отделить входящие данные от вызывающих участников на виджете, и это проще всего сделать с помощью механизма сигнал / слот.

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)));
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]