Problem with qwtPlot / not matching function for call to...
-
Hi all,
I wrote a application that plot data with the qwtPlot library.
It will not work fine.
First I try to plot xData and yData in a while loop 5 times with function populate() in plot.cpp.
When I call the function populate() at the end from the constructor Plot::Plot..., the plot are correctly.
But when I call the function populate() from the module modbusadapter.cpp, I became an error message:no matching function for call to 'Plot::Plot(ModbusAdapter* const)'
candidates are: Plot::Plot(QWidget*)
note: Plot::Plot(const Plot&)I receive the error only when I allocate memory for plot object in this form:
@plotNewDensity=new Plot(this);@
without the attribute 'this', I can compile, but when I call function populate() in modbusadapter.cpp (after modbus response),
I can see in debug mode that the code jumps in populate(), but without plots...Here any code segments:
plot.h
@#ifndef PLOT_H
#define PLOT_H#include <qapplication.h>
#include <qlayout.h>
#include <qwt_plot.h>
#include <qwt_plot_grid.h>
#include <qwt_plot_marker.h>
#include <qwt_plot_curve.h>
#include <qwt_legend.h>
#include <qwt_series_data.h>
#include <qwt_plot_canvas.h>
#include <qwt_plot_panner.h>
#include <qwt_plot_magnifier.h>
#include <qwt_text.h>
#include <qwt_math.h>
#include <math.h>#define SIZE 15
class Plot : public QwtPlot
{
Q_OBJECTpublic:
Plot( QWidget *parent = NULL);
~Plot();
void setPlotValue(double value);
void populate();protected:
virtual void resizeEvent( QResizeEvent * );private:
//void populate();
void updateGradient();
double cntX;
QwtPlotCurve *density;
double xData[SIZE];
double yData[SIZE];public slots:
void addNewValue(double value);
//void populate();signals:
};
#endif // PLOT_H@plot.cpp
@#include "plot.h"Plot::Plot(QWidget *parent):
QwtPlot( parent )
{
xData[0] = 0;
yData[0] = 0;// Insert new density curve density = new QwtPlotCurve("y = density"); //density->setRenderHint(QwtPlotItem::RenderAntialiased); density->setStyle(QwtPlotCurve::Lines); density->setLegendAttribute(QwtPlotCurve::LegendShowLine, true); density->setPen(QPen(Qt::red)); density->attach(this); // Draw grid QwtPlotGrid *grid = new QwtPlotGrid(); grid->setPen(QPen(Qt::gray, 0.0, Qt::DotLine)); grid->enableX(true); grid->enableXMin(true); grid->enableY(true); grid->enableYMin(false); grid->attach(this); // Insert markers // ...a horizontal line at y = 0... QwtPlotMarker *mY = new QwtPlotMarker(); mY->setLabel(QString::fromLatin1("y = 0")); mY->setLabelAlignment(Qt::AlignRight|Qt::AlignTop); mY->setLineStyle(QwtPlotMarker::HLine); mY->setYValue(0.0); mY->attach(this); // ...a vertical line at x = 0... QwtPlotMarker *mX = new QwtPlotMarker(); mX->setLabel(QString::fromLatin1("x = 0")); mX->setLabelAlignment(Qt::AlignLeft | Qt::AlignBottom); mX->setLabelOrientation(Qt::Vertical); mX->setLineStyle(QwtPlotMarker::VLine); mX->setLinePen(QPen(Qt::black, 0, Qt::DashDotLine)); mX->setXValue(0.0); mX->attach(this); // init private member //cntX= 0.0; // init function setPlotValue //setPlotValue(0.0); //plotGPS=new QwtPlotCurve(); // panning with the left mouse button (void) new QwtPlotPanner( canvas() ); // zoom in/out with the wheel (void) new QwtPlotMagnifier( canvas() ); setAutoFillBackground( true ); setPalette( QPalette( QColor( 165, 193, 228 ) ) ); updateGradient(); setTitle("A Simple QwtPlot Demonstration"); insertLegend(new QwtLegend(), QwtPlot::RightLegend); // axes setAxisTitle(xBottom, "x -->" ); setAxisScale(xBottom, 0.0, 10.0); setAxisTitle(yLeft, "y -->"); setAxisScale(yLeft, -1.0, 1.0); // canvas canvas()->setLineWidth( 1 ); canvas()->setFrameStyle( QFrame::Box | QFrame::Plain ); canvas()->setBorderRadius( 15 ); QPalette canvasPalette( Qt::white ); canvasPalette.setColor( QPalette::Foreground, QColor( 133, 190, 232 ) ); canvas()->setPalette( canvasPalette ); //populate(); // when I call here, the plots are correctly...
}
Plot::~Plot()
{}
void Plot::populate()
{
qWarning()<< "Plot : populate()";double maxD = 0; double minD = 1; double maxS = 0; double minS = 1; double dens = 2.0; unsigned int sample = 0; unsigned int x = 0; unsigned int y = 0; while(sample < 5) { xData[x++]= sample; yData[y++]= dens; setAxisScale(xBottom, (int)xData[dataCount-1]-iHistorySize, (int)xData[dataCount-1]+1); setAxisScale(yLeft, (int)min-1, (int)max+1); maxS = sample; minS = sample++; maxD = dens; minD = dens++; setAxisScale(xBottom, (int)minS-1, (int)maxS+1); setAxisScale(yLeft, (int)minD-1, (int)maxD+1); density->setSamples(xData, yData, sample); // Call "replot()" to refresh plot displaying replot(); }
}
...
...
...@ -
and here the rest:
modbusadapter.h
@#ifndef MODBUSADAPTER_H
#define MODBUSADAPTER_H#include <QObject>
#include "modbus.h"
#include "registersmodel.h"
#include "rawdatamodel.h"
#include <QTimer>
#include "eutils.h"#include "plot.h"
class ModbusAdapter : public QObject
{
Q_OBJECTpublic:
explicit ModbusAdapter(QObject *parent = 0);void busMonitorRequestData(uint8_t * data,uint8_t dataLen); void busMonitorResponseData(uint8_t * data,uint8_t dataLen); void modbusConnectRTU(QString port, int baud, QChar parity, int dataBits, int stopBits); void modbusConnectTCP(QString ip, int port); void modbusDisConnect(); void modbusRequestData(int slave, int functionCode, int startAddress, int noOfItems); RegistersModel *regModel; RawDataModel *rawModel; Plot *plotNewDensity; bool isConnected();
...
...
...@modbusadapter.cpp
@#include "modbusadapter.h"
#include <QMessageBox>
#include <QtDebug>
#include <errno.h>ModbusAdapter *m_instance;
static const int DBG = false; //Debug messages from libmodbusModbusAdapter::ModbusAdapter(QObject *parent) :
QObject(parent),
m_modbus(NULL)
{
m_instance=this;
regModel=new RegistersModel(this);
rawModel=new RawDataModel(this);plotNewDensity=new Plot(this); m_connected = false;
}
...
...
...
// after modbus response
plotNewDensity->populate();
...
...
...@can help anywhere plaese?
thanks and sorry for my english ;)
best regards
Anthony -
You need to look at the base class of ModbusAdapter which is QObject.
Plot::Plot(QWidget *parent) is expecting a QWidget pointer. QWidget has also QObject as a base class, but the compiler cannot match. That is the error message.
You can use QWidget as base class for ModBusAdapter. That should solve the matching problem. However, you need to check for side effects possibly arising.
-
hello koahnig, thanks for the advice...
Now I use QWidget as base class for ModBusAdapter in this way:
@class ModbusAdapter : public QWidget
{
Q_OBJECTpublic:
explicit ModbusAdapter(QWidget *parent = 0);
...
...
...@and
@ModbusAdapter::ModbusAdapter(QWidget *parent) :
QWidget(parent),
m_modbus(NULL)
{
m_instance=this;
regModel=new RegistersModel(this);
rawModel=new RawDataModel(this);plotNewDensity=new Plot(this); m_connected = false;
}@
I can compile, but when I jump in populate() from modbusadaapter.cpp after modbus response, still I don't have nothing plots...
When I debug I see again that the jump in populate is ok and the steps and values also but without plots...What could be the problem?
!https://www.dropbox.com/s/r09yyx8vgf9em5t/plotOk.gif (plot ok, when i call populate() in constructor Plot::Plot...)!
!https://www.dropbox.com/s/4mz55fx8qp58if8/plotNok.gif (without plots, when i call populate() in modbusadapter.cpp after modbus response)!
-
@
void Plot::populate()
{
qWarning()<< "Plot : populate()";double maxD = 0; double minD = 1; double maxS = 0; double minS = 1; double dens = 2.0; unsigned int sample = 0; unsigned int x = 0; unsigned int y = 0; while(sample < 5) { xData[x++]= sample; yData[y++]= dens; setAxisScale(xBottom, (int)xData[dataCount-1]-iHistorySize, (int)xData[dataCount-1]+1); setAxisScale(yLeft, (int)min-1, (int)max+1); maxS = sample; minS = sample++; maxD = dens; minD = dens++; setAxisScale(xBottom, (int)minS-1, (int)maxS+1); setAxisScale(yLeft, (int)minD-1, (int)maxD+1); density->setSamples(xData, yData, sample); // Call "replot()" to refresh plot displaying } setAutoReplot(true); replot();
}
@See, if this helps.
-
with
@setAutoReplot(true);@
it still doesn't plot nothing...
-
the main looks like
@#include <QtGui/QApplication>
#include "mainwindow.h"
#include "plot.h"int main(int argc, char *argv[])
{
QApplication a(argc, argv);Plot *plot = new Plot(); // We put a dummy widget around to have // so that Qt paints a widget background // when resizing QWidget window; QHBoxLayout *layout = new QHBoxLayout( &window ); layout->setContentsMargins( 0, 0, 0, 0 ); layout->addWidget( plot ); window.resize(600,400); window.show(); MainWindow w; w.show(); return a.exec();
}@
maybe is that anything wrong?
-
do I declare also anything in mainwindow?
here the code:
mainwindow.h
@#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QSettings>
#include <QLabel>
#include <QTimer>
#include "modbus.h"
#include "forms/about.h"
#include "forms/settingsmodbusrtu.h"
#include "forms/settingsmodbustcp.h"
#include "forms/settings.h"
#include "forms/busmonitor.h"
#include "modbusadapter.h"namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{
Q_OBJECTpublic:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();private:
Ui::MainWindow *ui;
//UI - Dialogs
About *m_dlgAbout;
SettingsModbusRTU *m_dlgModbusRTU;
SettingsModbusTCP *m_dlgModbusTCP;
Settings *m_dlgSettings;
BusMonitor *m_busMonitor;QSettings *m_modbusCommSettings; void updateStatusBar(); QLabel *m_statusText; QWidget *m_statusInd; ModbusAdapter *m_modbus; void modbusConnect(bool connect); QTimer *m_pollTimer;
private slots:
void showSettingsModbusRTU();
void showSettingsModbusTCP();
void showSettings();
void showBusMonitor();
void changedModbusMode(int currIndex);
void changedFunctionCode(int currIndex);
void changedBase(int currIndex);
void changedReqCycle(bool value);
void changedConnect(bool value);
void changedSlaveIP();
void addItems();
void clearItems();
void request();
void pollRequestForData();};
#endif // MAINWINDOW_H
@now I have nothing in mainwindow regarding plot...
-
Did you use one of the examples?
If so, maybe you should go back and change step by step. Unfortunately, I do not have enough experience with qwt to help you further. -
yes I have a example. The difference is that the plot layout are implemented directly in mainwindow looks like: !https://www.dropbox.com/s/a9qih7t7ubzq04d/EP24control.gif ()!
in my version I have two window one for plot and the other for modbus communication
here the code of example:
plot.h
@#ifndef PLOT_H
#define PLOT_H#include <QVector>
#include <qwt_plot.h>
#include <qwt_system_clock.h>
#include <qwt_plot_curve.h>#define BUFFERSIZE 36000 // Data buffer size (voluntarly laaarge! => 36000 at 10data/s = 1h)
class plot : public QwtPlot
{
Q_OBJECTpublic:
plot(QWidget * = NULL);
virtual ~plot();
void start();
void rescaleXaxis(int scale);private:
QwtPlot *d_plot;QwtPlotCurve *d_curve; double xData[BUFFERSIZE]; // x-data table double yData[BUFFERSIZE]; // y-data table int dataCount; // data counter double timeData[BUFFERSIZE]; int iHistorySize; // history size QwtSystemClock d_clock;
public slots:
void slot_addPoint(double value);
};#endif // PLOT_H
@plot.cpp
@#include "plot.h"
#include <qwt_plot_grid.h>
#include <qwt_plot_layout.h>
#include <qwt_plot_canvas.h>
#include <qwt_plot_marker.h>
#include <qwt_plot_curve.h>
#include <qwt_plot_directpainter.h>
#include <qwt_curve_fitter.h>
#include <qwt_painter.h>
#include <QtDebug>plot::plot(QWidget *parent):
QwtPlot(parent)
{
// Initialize variables
dataCount = 0;
iHistorySize = 60;
xData[dataCount] = 0;// Set x-axis scale rescaleXaxis(iHistorySize); // Set x-axis label setAxisTitle(xBottom, "Time [s]"); // Draw grid QwtPlotGrid *grid = new QwtPlotGrid(); grid->setPen(QPen(Qt::gray, 0.0, Qt::DotLine)); grid->enableX(true); grid->enableXMin(true); grid->enableY(true); grid->enableYMin(false); grid->attach(this); // Draw curve d_curve = new QwtPlotCurve(); d_curve->setStyle(QwtPlotCurve::Lines); d_curve->setPen(QPen(Qt::blue)); d_curve->attach(this);
}
plot::~plot()
{}
void plot::start()
{
if(d_clock.isNull())
{
// Start clock
d_clock.start();
}
else
{
dataCount = 0;
xData[dataCount] = 0;// Reset x-axis rescaleXaxis(iHistorySize); // Restart clock d_clock.restart(); }
}
// SLOTS
void plot::slot_addPoint(double value)
{
double max = 0;
double min = 1;// Get elapsed time in seconds xData[dataCount] = (double)(d_clock.elapsed() / 1000); // Add y-data yData[dataCount] = value; if(xData[dataCount] < BUFFERSIZE) { // Increment data counter dataCount++; } else { // Shift once for(int i=1;i<=dataCount;i++) { xData[i-1] = xData[i]; yData[i-1] = yData[i]; } } // Rescale x-axis rescaleXaxis(iHistorySize); // Rescale y-axis for(int i=0; i<dataCount; i++) { if(yData[i] > max)max = yData[i]; if((yData[i] < 0) && (yData[i] < min))min = yData[i]; } setAxisScale(yLeft, (int)min-1, (int)max+1); // Set samples on the curve d_curve->setSamples(xData, yData, dataCount); // Call "replot()" to refresh plot displaying replot();
}
void plot::rescaleXaxis(int scale)
{
// set scale value to iHistorySize
iHistorySize = scale;// if timer not existing of if current time is less than history size if(d_clock.isNull() || (xData[dataCount-1] < iHistorySize)) { // Set x-axis scale setAxisScale(xBottom, 0., iHistorySize); } else { // Set x-axis scale setAxisScale(xBottom, (int)xData[dataCount-1]-iHistorySize, (int)xData[dataCount-1]+1); } // Call "replot()" to refresh plot displaying replot();
}
@main
@#include <QtGui/QApplication>
#include "mainwindow.h"int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;// Window icon QPixmap p(":/icones/progicon"); w.setWindowIcon(p); w.setWindowTitle("EP24control v1.0.0"); // Window background color QPalette pal = w.palette(); pal.setColor(w.backgroundRole(), QColor(210,220,230)); w.setPalette(pal); w.resize(800,600); w.show(); return a.exec();
}
@ -
and here the
mainwindow.h
@#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QComboBox>
#include <QPushButton>
#include <QLabel>
#include <QSpinBox>
#include <QLayout>
#include <QGroupBox>
#include <QFile>
#include <QTextStream>
#include <QLineEdit>
#include <QDateTime>
#include "comthread.h"
#include "plot.h"
#include "led.h"class MainWindow : public QWidget
{
Q_OBJECTpublic:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();private:
void refreshComPortList(QComboBox *myComboBox);
ComThread *comThread;
...
...
...
plot *ui_voltagePlot;
plot *ui_currentPlot;
plot *ui_temperaturePlot;
...
...
...
@and mainwindow.cpp
@#include <QDateTime>
#include <QFileDialog>
#include "mainwindow.h"
#include <QDebug>MainWindow::MainWindow(QWidget *parent) :
QWidget(parent)
{
...
...
...
// Voltage plot
ui_voltagePlot = new plot(this);
ui_voltagePlot->setAxisScale(QwtPlot::yLeft, 0., 16.);
ui_voltagePlot->setAxisTitle(QwtPlot::yLeft, "Voltage [V]");
// Current plot
ui_currentPlot = new plot(this);
ui_currentPlot->setAxisScale(QwtPlot::yLeft, 0., 10.);
ui_currentPlot->setAxisTitle(QwtPlot::yLeft, "Current [A]");
// Temperature plot
ui_temperaturePlot = new plot(this);
ui_temperaturePlot->setAxisScale(QwtPlot::yLeft, -20., 50.);
ui_temperaturePlot->setAxisTitle(QwtPlot::yLeft, "Temp. [°C]");
...
...
...
// === END OF USER INTERFACE ELEMENTS ===// === LAYOUT ===
...
...
...QVBoxLayout *plotLayout = new QVBoxLayout(); plotLayout->addWidget(ui_voltagePlot); plotLayout->addWidget(ui_currentPlot); plotLayout->addWidget(ui_temperaturePlot); QGridLayout *layout = new QGridLayout(); layout->addLayout(plotLayout, 0, 0, 6, 1);
...
...
...connect(comThread, SIGNAL(vComSignalVbat(double)), ui_voltagePlot, SLOT(slot_addPoint(double))); connect(comThread, SIGNAL(vComSignalCbat(double)), ui_currentPlot, SLOT(slot_addPoint(double))); connect(comThread, SIGNAL(vComSignalTonb(double)), ui_temperaturePlot, SLOT(slot_addPoint(double)));
...
....
....// Start plot curves creation ui_voltagePlot->start(); ui_currentPlot->start(); ui_temperaturePlot->start();
...
....
...
// Set new scale
ui_voltagePlot->rescaleXaxis(iHorizontalScale);
ui_currentPlot->rescaleXaxis(iHorizontalScale);
ui_temperaturePlot->rescaleXaxis(iHorizontalScale);...
...
...
// Set new scale
ui_voltagePlot->rescaleXaxis(iHorizontalScale);
ui_currentPlot->rescaleXaxis(iHorizontalScale);
ui_temperaturePlot->rescaleXaxis(iHorizontalScale);...
...
@ -
maybe is that the problem, bacause I use two different window with two separate "instance" in my version main...
!https://www.dropbox.com/s/5bp1p4sqfa3qm77/window_qwtPlot&modbus.gif ()!