[QWT] Scrollzoomer von den Examples beim Plotten
Verfasst: 7. Juli 2007 16:58
Hallo!
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?)
2.alle 5sec ein update der achsen
Da der Zoomer die Startskalierung des Canvas übernimmt, habe ich meinen Skalierbereich zunächst auf 1000 sec gesetzt (absolute Notlösung
) und danach wieder auf meine ursprüngliche Skalierung geswitched (=10 sec). Wie gesagt, eine absolute Notlösung.
Meine Kenntnisse in C++ und QWT sind jetzt leider erst 2 Monate alt und daher verstehe ich den Zoomer leider noch nicht so ganz. Daher wäre es super, wenn ich einen Tipp bekäme, sodass man im Zoomer den Bereich selbst anpassen kann. Zur Zeit wird ja einfach nur ein QwtPlotCanvas übergeben, bei der instanziierung.
Hier nochmal mein ganzer Code für euch:
Herzlichen Dank schonmal für die super Hilfe hier im Forum
TheMetalManiac
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