PDA

View Full Version : Plotter class



awpitt13
9th February 2012, 00:23
Hello all,

I'm running a data logger and I'm trying to implement a plotter that pops up when a button is pressed on my gui. I am aware of Qwt, but I don't need anything fancy and from what I've read it seems installing it is sort of a pain. Instead, I've been using a plotter class I found in a book I just bought, C++ GUI Programming with Qt 4. Right now the code is setup for plotting two horizontal lines, I'm just trying to get the code functional, I'll worry about getting it functional with my data logger later.

I am getting no errors, nothing seems to happen when I click the button

Here is some of the code;

plotter.h


#ifndef PLOTTER_H
#define PLOTTER_H

#include <QMap>
#include <QPixmap>
#include <QVector>
#include <QWidget>

class QToolButton;
class PlotSettings;

class Plotter : public QWidget
{
Q_OBJECT

public:
Plotter (QWidget *parent = 0);

void setPlotSettings(const PlotSettings &settings);
void setCurveData(int id, const QVector<QPointF> &data);
void clearCurve(int id);
QSize minimumSizeHint() const;
QSize sizeHint() const;

public slots:
void zoomIn();
void zoomOut();

protected:
void paintEvent(QPaintEvent *event);
void resizeEvent(QResizeEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void keyPressEvent(QKeyEvent *event);
void wheelEvent(QWheelEvent *event);

private:
void updateRubberBandRegion();
void refreshPixmap();
void drawGrid(QPainter *painter);
void drawCurves(QPainter *painter);

enum { Margin = 50 };

QToolButton *zoomInButton;
QToolButton *zoomOutButton;
QMap<int, QVector<QPointF> > curveMap;
QVector<PlotSettings> zoomStack;
int curZoom;
bool rubberBandIsShown;
QRect rubberBandRect;
QPixmap pixmap;
};

class PlotSettings
{
public:
PlotSettings();

void scroll(int dx, int dy);
void adjust();
double spanX() const { return maxX - minX; }
double spanY() const { return maxY - minY; }

double minX;
double maxX;
int numXTicks;
double minY;
double maxY;
int numYTicks;

private:
static void adjustAxis(double &min, double &max, int &numTicks);
};

#endif

#include "plotter.h"

plotSettings.cpp


PlotSettings::PlotSettings()
{
minX = 0.0;
maxX = 10.0;
numTicks = 5;

minY = 0.0;
maxY = 10.0;
numYTicks = 5;
}

//more code...


here is the implementation file, Plotter.cpp



#include "plotter.h"
#include <QtGui>

Plotter::Plotter(QWidget *parent)
: QWidget(parent)
{
setBackgroundRole(QPalette::Dark);
setAutoFillBackground(true);
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
setFocusPolicy(Qt::StrongFocus);
rubberBandIsShown = false;

zoomInButton = new QToolButton(this);
zoomInButton->setIcon(QIcon(":/images/zoomin.png"));
zoomInButton->adjustSize();
connect(zoomInButton, SIGNAL(clicked()), this, SLOT(zoomIn()));

zoomOutButton = new QToolButton(this);
zoomOutButton->setIcon(QIcon(":/images/zoomout.png"));
zoomOutButton->adjustSize();
connect(zoomOutButton, SIGNAL(clicked()), this, SLOT(zoomOut()));

setPlotSettings(PlotSettings());
}

//all the functions follow...




Now in my main window I call it



//rest of program code

void mainWindow::on_pushButton_clicked()
{
PlotSettings settings;
settings.minX(0.0);
settings.maxX(100.0);
settings.minY(0.0);
settings.maxY(100.0);

int numPoints = 100;
ArrayList<QPointF> points0 = new ArrayList<QPointF>();
ArrayList<QPointF> points1 = new ArrayList<QPointF>();
for (int x = 0; x < numPoints; ++x) {
points0.add(new QPointF(x, Math.random() * 100));
points1.add(new QPointF(x, Math.random() * 100));
}

Plotter plotter;
plotter.setWindowTitle(plotter.tr("Jambi Plotter"));
plotter.setPlotSettings(settings);
plotter.setCurveData(0, points0);
plotter.setCurveData(1, points1);
plotter.show();

//rest of program code
}


Thank you in advance for any help you can offer

norobro
9th February 2012, 02:46
See comments in the code:

void mainWindow::on_pushButton_clicked()
{
PlotSettings settings;
settings.minX(0.0); // not allowed; use assignment statement
settings.maxX(100.0);
settings.minY(0.0);
settings.maxY(100.0);

int numPoints = 100;
QVector<QPointF> points0; // use QVector - no need to create this on the heap
ArrayList<QPointF> points1 = new ArrayList<QPointF>(); //same as above
for (int x = 0; x < numPoints; ++x) {
points0.append(QPointF(x, qrand() % 100)); // use QVector::append(), again no need to create the points on the heap
// see qsrand & qrand()
points1.add(new QPointF(x, Math.random() * 100)); //same as above
}

Plotter plotter; // This does need to be created on the heap
plotter.setWindowTitle(plotter.tr("Jambi Plotter"));
plotter.setPlotSettings(settings);
plotter.setCurveData(0, points0);
plotter.setCurveData(1, points1);
plotter.show();
}
HTH

awpitt13
9th February 2012, 18:46
From your suggestions I have edited my code which can be seen below. When I click this button, nothing seems to happen. I feel like I need a .exec() command somewhere to pop up a new Ui but I'm not sure how to implement this...



void mainWindow::on_pushButton_clicked()
{
PlotSettings settings;
settings.minX = 0.0;
settings.maxX = 100.0;
settings.minY = 0.0;
settings.maxY = 100.0;

int numPoints = 100;
QVector<QPointF> points0;
QVector<QPointF> points1;
for (int x = 0; x < numPoints; ++x) {
points0.append(QPointF(x, qrand() % 100));

points1.append(QPointF(x, qrand() % 100));
}

Plotter plotter;
plotter.setWindowTitle(plotter.tr("Plotter"));
plotter.setPlotSettings(settings);
plotter.setCurveData(0, points0);
plotter.setCurveData(1, points1);
plotter.show();
}

norobro
9th February 2012, 19:20
The one thing that you didn't do is create "plotter" on the heap at line 18:
Plotter *plotter = new Plotter;

awpitt13
9th February 2012, 23:05
changing line 18 to


Plotter *plotter = new Plotter;


results in the following errors:

request for member 'setWindowTitle' in 'plotter' which is of non-class type 'Plotter*'
request for member 'tr' in 'plotter' which is of non-class type 'Plotter*'
request for member 'setPlotSettings' in 'plotter' which is of non-class type 'Plotter*'
request for member 'setCurveData' in 'plotter' which is of non-class type 'Plotter*'
request for member 'setCurveData' in 'plotter' which is of non-class type 'Plotter*'
request for member 'show' in 'plotter' which is of non-class type 'Plotter*'

norobro
10th February 2012, 00:21
You need to use the pointer member selection operator (http://www.learncpp.com/cpp-tutorial/612-references-vs-pointers-and-member-selection/)"->" to call each of those methods.

e.g.:
plotter->setWindowTitle(plotter->tr("Plotter"));

awpitt13
10th February 2012, 00:30
Thank you sir, it's working