Nachdem ich mich nun in die Plotterei mit qwt eingearbeitet habe und einen recht schönen Plot zustande bekommen habe, dachte ich mir, noch das Zooming vom Bespiel (realtime_plot) einzufügen.
Das klappt auch gut, in dem erstdefinierten Bereich (Achsenskalierung).
Nun habe ich in dem Plot eine auswahloption für die Skalierung der x-Achse definiert.
1. Entweder fortlaufend (x-Achse einfach bei jedem Event verändern, oder gibt es eine schönere Lösung?)
Code: Alles auswählen
if (! xVectorPtr->isEmpty())
{
std::cout <<"mitlaufen!! "<< refresh <<"\n";
scaleIndex = xVectorPtr->last();
if (scaleIndex > 8)
{
setAxisScale(QwtPlot::xBottom,scaleIndex-8,scaleIndex+1.9);
}
}
else
scaleIndex = xVectorPtr->last();
Code: Alles auswählen
if (! xVectorPtr->isEmpty())
{
std::cout <<"aktualisierend!! "<< refresh <<"\n";
scaleIndex = xVectorPtr->last();
if (scaleIndex > scaleValue)
{
setAxisScale(QwtPlot::xBottom,scaleIndex-5,scaleIndex+5);
scaleValue += 5;
}
}
else
scaleIndex = xVectorPtr->last();
Da der Zoomer die Startskalierung des Canvas übernimmt, habe ich meinen Skalierbereich zunächst auf 1000 sec gesetzt (absolute Notlösung
Code: Alles auswählen
setAxisScale(QwtPlot::xBottom, 0, 1000); //zoomer need to be initialized by high xvalue, to insert the scrollbar
// enable zooming
Zoomer *zoomer = new Zoomer(canvas());
zoomer->setRubberBandPen(QPen(Qt::red, 2, Qt::DotLine));
zoomer->setTrackerPen(QPen(Qt::red));
setAxisScale(QwtPlot::xBottom, 0, 10);
setAxisTitle(QwtPlot::yLeft, "y");
Hier nochmal mein ganzer Code für euch:
Code: Alles auswählen
#include <stdlib.h>
#include <qwt_painter.h>
#include <qwt_plot_canvas.h>
#include <qwt_plot_marker.h>
#include <qwt_plot_curve.h>
#include <qwt_scale_widget.h>
#include <qwt_legend.h>
#include <qwt_scale_draw.h>
#include <qtimer.h>
#include <qwt_plot_grid.h>
#include <qwt_plot_canvas.h>
#include <qwt_plot_layout.h>
#include <QAbstractScrollArea>
#include <iostream.h>
#include "data_plot.h"
#include "scrollzoomer.h"
const unsigned int c_rangeMax = 1000;
class Zoomer: public ScrollZoomer
{
public:
Zoomer(QwtPlotCanvas *canvas):
ScrollZoomer(canvas)
{
}
virtual void rescale()
{
QwtScaleWidget *scaleWidget = plot()->axisWidget(yAxis());
QwtScaleDraw *sd = scaleWidget->scaleDraw();
int minExtent = 0;
if ( zoomRectIndex() > 0 )
{
// When scrolling in vertical direction
// the plot is jumping in horizontal direction
// because of the different widths of the labels
// So we better use a fixed extent.
minExtent = sd->spacing() + sd->majTickLength() + 1;
minExtent += sd->labelSize(
scaleWidget->font(), c_rangeMax).width();
}
sd->setMinimumExtent(minExtent);
ScrollZoomer::rescale();
}
};
//
// Initialize main window
//
DataPlot::DataPlot(QVector<double> *xVec, QVector<double> *yVec,QWidget* = NULL):
// QwtPlot(parent),
d_interval(0),
d_timerId(-1)
{
//QVector übernahme
xVectorPtr = xVec;
yVectorPtr = yVec;
// Disable polygon clipping
QwtPainter::setDeviceClipping(false);
// We don't need the cache here
canvas()->setPaintAttribute(QwtPlotCanvas::PaintCached, false);
canvas()->setPaintAttribute(QwtPlotCanvas::PaintPacked, false);
#if QT_VERSION >= 0x040000
#ifdef Q_WS_X11
canvas()->setAttribute(Qt::WA_PaintOnScreen, true);
#endif
#endif
alignScales();
setTitle("Oskar");
insertLegend(new QwtLegend(), QwtPlot::BottomLegend);
// Insert new curve
plot = new QwtPlotCurve("Ausgang XY"); //Ausgang als QString übergeben
plot->attach(this);
//setData has to be set for (only) one time, then QwtPlotCurve knows his Database
plot->setData(*xVectorPtr,*yVectorPtr);
// Set curve styles
plot->setPen(QPen(Qt::red));
#if 0
// Insert zero line at y = 0
QwtPlotMarker *mY = new QwtPlotMarker();
mY->setLabelAlignment(Qt::AlignRight|Qt::AlignTop);
mY->setLineStyle(QwtPlotMarker::HLine);
mY->setYValue(0.0);
mY->attach(this);
#endif
// Axis
setAxisTitle(QwtPlot::xBottom, "Time/seconds");
setAxisScale(QwtPlot::xBottom, 0, 1000); //zoomer need to be initialized by high xvalue, to insert the scrollbar
// enable zooming
Zoomer *zoomer = new Zoomer(canvas());
zoomer->setRubberBandPen(QPen(Qt::red, 2, Qt::DotLine));
zoomer->setTrackerPen(QPen(Qt::red));
setAxisScale(QwtPlot::xBottom, 0, 10);
setAxisTitle(QwtPlot::yLeft, "y");
setAxisScale(QwtPlot::yLeft, 0, 400);
//setAutoScale()
setTimerInterval(500.0); // in ms
//set scaleValue
scaleValue = 5;
refresh = false;
}
//
// Set a plain canvas frame and align the scales to it
//
void DataPlot::alignScales()
{
// The code below shows how to align the scales to
// the canvas frame
canvas()->setFrameStyle(QFrame::Box | QFrame::Plain );
canvas()->setLineWidth(1);
for ( int i = 0; i < QwtPlot::axisCnt; i++ )
{
QwtScaleWidget *scaleWidget = (QwtScaleWidget *)axisWidget(i);
if ( scaleWidget )
scaleWidget->setMargin(0);
QwtScaleDraw *scaleDraw = (QwtScaleDraw *)axisScaleDraw(i);
if ( scaleDraw )
scaleDraw->enableComponent(QwtAbstractScaleDraw::Backbone, false);
}
}
void DataPlot::setRefreshActual()
{
refresh = false;
}
void DataPlot::setRefreshConstant()
{
refresh = true;
}
// TimerInterval in ms (= Refreshrate -> 0 is fast & 100 is slowly)
void DataPlot::setTimerInterval(double ms)
{
d_interval = qRound(ms);
if ( d_timerId >= 0 )
{
killTimer(d_timerId);
d_timerId = -1;
}
if (d_interval >= 0 )
d_timerId = startTimer(d_interval);
}
// Generate new values
void DataPlot::timerEvent(QTimerEvent *)
{
if (!refresh)
{
//erste Möglichkeit: Achse mitlaufend
if (! xVectorPtr->isEmpty())
{
std::cout <<"mitlaufen!! "<< refresh <<"\n";
scaleIndex = xVectorPtr->last();
if (scaleIndex > 8)
{
setAxisScale(QwtPlot::xBottom,scaleIndex-8,scaleIndex+1.9);
}
}
else
scaleIndex = xVectorPtr->last();
}
else
{
//zweite Möglichkeit: Achse alle 5s updaten
if (! xVectorPtr->isEmpty())
{
std::cout <<"aktualisierend!! "<< refresh <<"\n";
scaleIndex = xVectorPtr->last();
if (scaleIndex > scaleValue)
{
setAxisScale(QwtPlot::xBottom,scaleIndex-5,scaleIndex+5);
scaleValue += 5;
}
}
else
scaleIndex = xVectorPtr->last();
}
plot->setData(*xVectorPtr,*yVectorPtr);
replot();
}
TheMetalManiac