Released version 6.1.3
This commit is contained in:
commit
a94503cb82
1885 changed files with 276310 additions and 0 deletions
25
examples/realtime/README
Normal file
25
examples/realtime/README
Normal file
|
@ -0,0 +1,25 @@
|
|||
1) Incremental plots
|
||||
|
||||
IncrementalPlot shows an example how to implement a plot that
|
||||
displays growing data.
|
||||
|
||||
The example produces random data when you push the start button.
|
||||
With 'Timer' you can adjust the intervall between the
|
||||
the generation of the points, with 'Points' you can set the number
|
||||
of points to be generated.
|
||||
|
||||
Unfortunately in Qt4 incremental painting is not possible with QPaintEngines
|
||||
that doesn't support the QPaintEngine::PaintOutsidePaintEvent feature.
|
||||
( These are all common paint engines beside the OpenGL engine, but this one
|
||||
is not supported by Qwt yet. )
|
||||
That is the reason why you can see much faster repaints with Qt3.
|
||||
|
||||
2) Stacked Zooming with scrollbars
|
||||
|
||||
ScrollZoomer adds scrollbars for zooming. There are a couple of
|
||||
reasons why the implementation is a hack and therefore the class
|
||||
is not part of the Qwt lib, but it should be working with all
|
||||
types of QwtPlots. Copy the code of scrollbar.[h|cpp] and
|
||||
scrollzoomer.[h|cpp] to the application code.
|
||||
|
||||
Uwe
|
51
examples/realtime/clear.xpm
Normal file
51
examples/realtime/clear.xpm
Normal file
|
@ -0,0 +1,51 @@
|
|||
/* XPM */
|
||||
static const char *clear_xpm[] = {
|
||||
/* width height num_colors chars_per_pixel */
|
||||
" 32 32 12 1",
|
||||
/* colors */
|
||||
". c #000000",
|
||||
"# c #004040",
|
||||
"a c #303030",
|
||||
"b c #400000",
|
||||
"c c #404000",
|
||||
"d c #585858",
|
||||
"e c #808080",
|
||||
"f c #a0a0a4",
|
||||
"g c #bdbdbd",
|
||||
"h c #c0c0c0",
|
||||
"i c #dcdcdc",
|
||||
"j c #ffffff",
|
||||
/* pixels */
|
||||
"gggggggggggggggggggggggggggggggg",
|
||||
"gggggggggggggg..gggggggggggggggg",
|
||||
"gggggggggg....ficggggggggggggggg",
|
||||
"ggggggg...fdad#ai......ggggggggg",
|
||||
"gggg...fhjjidfbc#f.fffe...gggggg",
|
||||
"ggg.fhjjjjihc#dhef.fhhhffe.ggggg",
|
||||
"ggg.#jjjjjihhhhhe..ehhhfff.ggggg",
|
||||
"ggg.#dffjjjjiihhcadehhfddd.ggggg",
|
||||
"ggg.iiiffhfjjjjjhhhfdddddd.ggggg",
|
||||
"ggg.#fjjiiffeeeeddddeeeddd.ggggg",
|
||||
"gggg.#eeiiiiifffffffeee...gggggg",
|
||||
"gggg.ffffffiifffffffddddd.gggggg",
|
||||
"gggg.fffjfffeeeeddddeed.d.gggggg",
|
||||
"gggg.fefiiiifhffeeeeded.d.gggggg",
|
||||
"gggg.fefijhfhifefff.ded.d.gggggg",
|
||||
"gggg.fefijeffifeefe.ded.d.gggggg",
|
||||
"gggg.fefijeffifeefe.ded.d.gggggg",
|
||||
"gggg.fefijeffifeefe.ded.d.gggggg",
|
||||
"gggg.fefijeffifeefe.ded.d.gggggg",
|
||||
"gggg.fefijeffifeefe.ded.d.gggggg",
|
||||
"gggg.fefijeffifeefe.ded.d.gggggg",
|
||||
"gggg.fefijeffifeefe.ded.d.gggggg",
|
||||
"gggg.fefijeffifeefe.ded.d.gggggg",
|
||||
"gggg.fefijeffifeefe.ded.d.gggggg",
|
||||
"gggg.fefijeffifeefe.ded.d.gggggg",
|
||||
"gggg.fefijeffifeefe.ded.d.gggggg",
|
||||
"gggg.fffijeffifeefe.deddd.gggggg",
|
||||
"gggg.ffiijeffifeefeddedd#.gggggg",
|
||||
"gggg.eiijjjeiifdffedded#..gggggg",
|
||||
"ggggg..fjjiiiiffffedddd..ggggggg",
|
||||
"ggggggg...fhhfffffdd...ggggggggg",
|
||||
"gggggggggg..........gggggggggggg"
|
||||
};
|
124
examples/realtime/incrementalplot.cpp
Normal file
124
examples/realtime/incrementalplot.cpp
Normal file
|
@ -0,0 +1,124 @@
|
|||
#include <qwt_plot.h>
|
||||
#include <qwt_plot_canvas.h>
|
||||
#include <qwt_plot_curve.h>
|
||||
#include <qwt_symbol.h>
|
||||
#include <qwt_plot_directpainter.h>
|
||||
#include <qwt_painter.h>
|
||||
#include "incrementalplot.h"
|
||||
#include <qpaintengine.h>
|
||||
|
||||
class CurveData: public QwtArraySeriesData<QPointF>
|
||||
{
|
||||
public:
|
||||
CurveData()
|
||||
{
|
||||
}
|
||||
|
||||
virtual QRectF boundingRect() const
|
||||
{
|
||||
if ( d_boundingRect.width() < 0.0 )
|
||||
d_boundingRect = qwtBoundingRect( *this );
|
||||
|
||||
return d_boundingRect;
|
||||
}
|
||||
|
||||
inline void append( const QPointF &point )
|
||||
{
|
||||
d_samples += point;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
d_samples.clear();
|
||||
d_samples.squeeze();
|
||||
d_boundingRect = QRectF( 0.0, 0.0, -1.0, -1.0 );
|
||||
}
|
||||
};
|
||||
|
||||
IncrementalPlot::IncrementalPlot( QWidget *parent ):
|
||||
QwtPlot( parent ),
|
||||
d_curve( NULL )
|
||||
{
|
||||
d_directPainter = new QwtPlotDirectPainter( this );
|
||||
|
||||
if ( QwtPainter::isX11GraphicsSystem() )
|
||||
{
|
||||
#if QT_VERSION < 0x050000
|
||||
canvas()->setAttribute( Qt::WA_PaintOutsidePaintEvent, true );
|
||||
#endif
|
||||
canvas()->setAttribute( Qt::WA_PaintOnScreen, true );
|
||||
}
|
||||
|
||||
d_curve = new QwtPlotCurve( "Test Curve" );
|
||||
d_curve->setData( new CurveData() );
|
||||
showSymbols( true );
|
||||
|
||||
d_curve->attach( this );
|
||||
|
||||
setAutoReplot( false );
|
||||
}
|
||||
|
||||
IncrementalPlot::~IncrementalPlot()
|
||||
{
|
||||
delete d_curve;
|
||||
}
|
||||
|
||||
void IncrementalPlot::appendPoint( const QPointF &point )
|
||||
{
|
||||
CurveData *data = static_cast<CurveData *>( d_curve->data() );
|
||||
data->append( point );
|
||||
|
||||
const bool doClip = !canvas()->testAttribute( Qt::WA_PaintOnScreen );
|
||||
if ( doClip )
|
||||
{
|
||||
/*
|
||||
Depending on the platform setting a clip might be an important
|
||||
performance issue. F.e. for Qt Embedded this reduces the
|
||||
part of the backing store that has to be copied out - maybe
|
||||
to an unaccelerated frame buffer device.
|
||||
*/
|
||||
const QwtScaleMap xMap = canvasMap( d_curve->xAxis() );
|
||||
const QwtScaleMap yMap = canvasMap( d_curve->yAxis() );
|
||||
|
||||
QRegion clipRegion;
|
||||
|
||||
const QSize symbolSize = d_curve->symbol()->size();
|
||||
QRect r( 0, 0, symbolSize.width() + 2, symbolSize.height() + 2 );
|
||||
|
||||
const QPointF center =
|
||||
QwtScaleMap::transform( xMap, yMap, point );
|
||||
r.moveCenter( center.toPoint() );
|
||||
clipRegion += r;
|
||||
|
||||
d_directPainter->setClipRegion( clipRegion );
|
||||
}
|
||||
|
||||
d_directPainter->drawSeries( d_curve,
|
||||
data->size() - 1, data->size() - 1 );
|
||||
}
|
||||
|
||||
void IncrementalPlot::clearPoints()
|
||||
{
|
||||
CurveData *data = static_cast<CurveData *>( d_curve->data() );
|
||||
data->clear();
|
||||
|
||||
replot();
|
||||
}
|
||||
|
||||
void IncrementalPlot::showSymbols( bool on )
|
||||
{
|
||||
if ( on )
|
||||
{
|
||||
d_curve->setStyle( QwtPlotCurve::NoCurve );
|
||||
d_curve->setSymbol( new QwtSymbol( QwtSymbol::XCross,
|
||||
Qt::NoBrush, QPen( Qt::white ), QSize( 4, 4 ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
d_curve->setPen( Qt::white );
|
||||
d_curve->setStyle( QwtPlotCurve::Dots );
|
||||
d_curve->setSymbol( NULL );
|
||||
}
|
||||
|
||||
replot();
|
||||
}
|
28
examples/realtime/incrementalplot.h
Normal file
28
examples/realtime/incrementalplot.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef _INCREMENTALPLOT_H_
|
||||
#define _INCREMENTALPLOT_H_ 1
|
||||
|
||||
#include <qwt_plot.h>
|
||||
|
||||
class QwtPlotCurve;
|
||||
class QwtPlotDirectPainter;
|
||||
|
||||
class IncrementalPlot : public QwtPlot
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
IncrementalPlot( QWidget *parent = NULL );
|
||||
virtual ~IncrementalPlot();
|
||||
|
||||
void appendPoint( const QPointF & );
|
||||
void clearPoints();
|
||||
|
||||
public Q_SLOTS:
|
||||
void showSymbols( bool );
|
||||
|
||||
private:
|
||||
QwtPlotCurve *d_curve;
|
||||
QwtPlotDirectPainter *d_directPainter;
|
||||
};
|
||||
|
||||
#endif // _INCREMENTALPLOT_H_
|
12
examples/realtime/main.cpp
Normal file
12
examples/realtime/main.cpp
Normal file
|
@ -0,0 +1,12 @@
|
|||
#include <qapplication.h>
|
||||
#include "mainwindow.h"
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
QApplication a( argc, argv );
|
||||
|
||||
MainWindow w;
|
||||
w.show();
|
||||
|
||||
return a.exec();
|
||||
}
|
193
examples/realtime/mainwindow.cpp
Normal file
193
examples/realtime/mainwindow.cpp
Normal file
|
@ -0,0 +1,193 @@
|
|||
#include <qlabel.h>
|
||||
#include <qlayout.h>
|
||||
#include <qstatusbar.h>
|
||||
#include <qtoolbar.h>
|
||||
#include <qtoolbutton.h>
|
||||
#include <qspinbox.h>
|
||||
#include <qcheckbox.h>
|
||||
#include <qwhatsthis.h>
|
||||
#include <qpixmap.h>
|
||||
#include "randomplot.h"
|
||||
#include "mainwindow.h"
|
||||
#include "start.xpm"
|
||||
#include "clear.xpm"
|
||||
|
||||
class MyToolBar: public QToolBar
|
||||
{
|
||||
public:
|
||||
MyToolBar( MainWindow *parent ):
|
||||
QToolBar( parent )
|
||||
{
|
||||
}
|
||||
void addSpacing( int spacing )
|
||||
{
|
||||
QLabel *label = new QLabel( this );
|
||||
addWidget( label );
|
||||
label->setFixedWidth( spacing );
|
||||
}
|
||||
};
|
||||
|
||||
class Counter: public QWidget
|
||||
{
|
||||
public:
|
||||
Counter( QWidget *parent,
|
||||
const QString &prefix, const QString &suffix,
|
||||
int min, int max, int step ):
|
||||
QWidget( parent )
|
||||
{
|
||||
QHBoxLayout *layout = new QHBoxLayout( this );
|
||||
|
||||
if ( !prefix.isEmpty() )
|
||||
layout->addWidget( new QLabel( prefix + " ", this ) );
|
||||
|
||||
d_counter = new QSpinBox( this );
|
||||
d_counter->setRange( min, max );
|
||||
d_counter->setSingleStep( step );
|
||||
layout->addWidget( d_counter );
|
||||
|
||||
if ( !suffix.isEmpty() )
|
||||
layout->addWidget( new QLabel( QString( " " ) + suffix, this ) );
|
||||
}
|
||||
|
||||
void setValue( int value ) { d_counter->setValue( value ); }
|
||||
int value() const { return d_counter->value(); }
|
||||
|
||||
private:
|
||||
QSpinBox *d_counter;
|
||||
};
|
||||
|
||||
MainWindow::MainWindow()
|
||||
{
|
||||
addToolBar( toolBar() );
|
||||
#ifndef QT_NO_STATUSBAR
|
||||
( void )statusBar();
|
||||
#endif
|
||||
|
||||
d_plot = new RandomPlot( this );
|
||||
const int margin = 4;
|
||||
d_plot->setContentsMargins( margin, margin, margin, margin );
|
||||
|
||||
setCentralWidget( d_plot );
|
||||
|
||||
connect( d_startAction, SIGNAL( toggled( bool ) ), this, SLOT( appendPoints( bool ) ) );
|
||||
connect( d_clearAction, SIGNAL( triggered() ), d_plot, SLOT( clear() ) );
|
||||
connect( d_symbolType, SIGNAL( toggled( bool ) ), d_plot, SLOT( showSymbols( bool ) ) );
|
||||
connect( d_plot, SIGNAL( running( bool ) ), this, SLOT( showRunning( bool ) ) );
|
||||
connect( d_plot, SIGNAL( elapsed( int ) ), this, SLOT( showElapsed( int ) ) );
|
||||
|
||||
initWhatsThis();
|
||||
|
||||
setContextMenuPolicy( Qt::NoContextMenu );
|
||||
}
|
||||
|
||||
QToolBar *MainWindow::toolBar()
|
||||
{
|
||||
MyToolBar *toolBar = new MyToolBar( this );
|
||||
|
||||
toolBar->setAllowedAreas( Qt::TopToolBarArea | Qt::BottomToolBarArea );
|
||||
setToolButtonStyle( Qt::ToolButtonTextUnderIcon );
|
||||
|
||||
d_startAction = new QAction( QPixmap( start_xpm ), "Start", toolBar );
|
||||
d_startAction->setCheckable( true );
|
||||
d_clearAction = new QAction( QPixmap( clear_xpm ), "Clear", toolBar );
|
||||
QAction *whatsThisAction = QWhatsThis::createAction( toolBar );
|
||||
whatsThisAction->setText( "Help" );
|
||||
|
||||
toolBar->addAction( d_startAction );
|
||||
toolBar->addAction( d_clearAction );
|
||||
toolBar->addAction( whatsThisAction );
|
||||
|
||||
setIconSize( QSize( 22, 22 ) );
|
||||
|
||||
QWidget *hBox = new QWidget( toolBar );
|
||||
|
||||
d_symbolType = new QCheckBox( "Symbols", hBox );
|
||||
d_symbolType->setChecked( true );
|
||||
|
||||
d_randomCount =
|
||||
new Counter( hBox, "Points", QString::null, 1, 100000, 100 );
|
||||
d_randomCount->setValue( 1000 );
|
||||
|
||||
d_timerCount = new Counter( hBox, "Delay", "ms", 0, 100000, 100 );
|
||||
d_timerCount->setValue( 0 );
|
||||
|
||||
QHBoxLayout *layout = new QHBoxLayout( hBox );
|
||||
layout->setMargin( 0 );
|
||||
layout->setSpacing( 0 );
|
||||
layout->addSpacing( 10 );
|
||||
layout->addWidget( new QWidget( hBox ), 10 ); // spacer
|
||||
layout->addWidget( d_symbolType );
|
||||
layout->addSpacing( 5 );
|
||||
layout->addWidget( d_randomCount );
|
||||
layout->addSpacing( 5 );
|
||||
layout->addWidget( d_timerCount );
|
||||
|
||||
showRunning( false );
|
||||
|
||||
toolBar->addWidget( hBox );
|
||||
|
||||
return toolBar;
|
||||
}
|
||||
|
||||
void MainWindow::appendPoints( bool on )
|
||||
{
|
||||
if ( on )
|
||||
d_plot->append( d_timerCount->value(),
|
||||
d_randomCount->value() );
|
||||
else
|
||||
d_plot->stop();
|
||||
}
|
||||
|
||||
void MainWindow::showRunning( bool running )
|
||||
{
|
||||
d_randomCount->setEnabled( !running );
|
||||
d_timerCount->setEnabled( !running );
|
||||
d_startAction->setChecked( running );
|
||||
d_startAction->setText( running ? "Stop" : "Start" );
|
||||
}
|
||||
|
||||
void MainWindow::showElapsed( int ms )
|
||||
{
|
||||
QString text;
|
||||
text.setNum( ms );
|
||||
text += " ms";
|
||||
|
||||
statusBar()->showMessage( text );
|
||||
}
|
||||
|
||||
void MainWindow::initWhatsThis()
|
||||
{
|
||||
const char *text1 =
|
||||
"Zooming is enabled until the selected area gets "
|
||||
"too small for the significance on the axes.\n\n"
|
||||
"You can zoom in using the left mouse button.\n"
|
||||
"The middle mouse button is used to go back to the "
|
||||
"previous zoomed area.\n"
|
||||
"The right mouse button is used to unzoom completely.";
|
||||
|
||||
const char *text2 =
|
||||
"Number of random points that will be generated.";
|
||||
|
||||
const char *text3 =
|
||||
"Delay between the generation of two random points.";
|
||||
|
||||
const char *text4 =
|
||||
"Start generation of random points.\n\n"
|
||||
"The intention of this example is to show how to implement "
|
||||
"growing curves. The points will be generated and displayed "
|
||||
"one after the other.\n"
|
||||
"To check the performance, a small delay and a large number "
|
||||
"of points are useful. To watch the curve growing, a delay "
|
||||
" > 300 ms and less points are better.\n"
|
||||
"To inspect the curve, stacked zooming is implemented using the "
|
||||
"mouse buttons on the plot.";
|
||||
|
||||
const char *text5 = "Remove all points.";
|
||||
|
||||
d_plot->setWhatsThis( text1 );
|
||||
d_randomCount->setWhatsThis( text2 );
|
||||
d_timerCount->setWhatsThis( text3 );
|
||||
d_startAction->setWhatsThis( text4 );
|
||||
d_clearAction->setWhatsThis( text5 );
|
||||
}
|
||||
|
37
examples/realtime/mainwindow.h
Normal file
37
examples/realtime/mainwindow.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
#ifndef _MAINWINDOW_H_
|
||||
#define _MAINWINDOW_H_ 1
|
||||
|
||||
#include <qmainwindow.h>
|
||||
#include <qaction.h>
|
||||
|
||||
class QSpinBox;
|
||||
class QPushButton;
|
||||
class RandomPlot;
|
||||
class Counter;
|
||||
class QCheckBox;
|
||||
|
||||
class MainWindow: public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MainWindow();
|
||||
|
||||
private Q_SLOTS:
|
||||
void showRunning( bool );
|
||||
void appendPoints( bool );
|
||||
void showElapsed( int );
|
||||
|
||||
private:
|
||||
QToolBar *toolBar();
|
||||
void initWhatsThis();
|
||||
|
||||
private:
|
||||
Counter *d_randomCount;
|
||||
Counter *d_timerCount;
|
||||
QCheckBox *d_symbolType;
|
||||
QAction *d_startAction;
|
||||
QAction *d_clearAction;
|
||||
RandomPlot *d_plot;
|
||||
};
|
||||
|
||||
#endif
|
141
examples/realtime/randomplot.cpp
Normal file
141
examples/realtime/randomplot.cpp
Normal file
|
@ -0,0 +1,141 @@
|
|||
#include <qglobal.h>
|
||||
#include <qtimer.h>
|
||||
#include <qwt_plot_grid.h>
|
||||
#include <qwt_plot_canvas.h>
|
||||
#include <qwt_plot_layout.h>
|
||||
#include <qwt_scale_widget.h>
|
||||
#include <qwt_scale_draw.h>
|
||||
#include "scrollzoomer.h"
|
||||
#include "randomplot.h"
|
||||
|
||||
const unsigned int c_rangeMax = 1000;
|
||||
|
||||
class Zoomer: public ScrollZoomer
|
||||
{
|
||||
public:
|
||||
Zoomer( QWidget *canvas ):
|
||||
ScrollZoomer( canvas )
|
||||
{
|
||||
#if 0
|
||||
setRubberBandPen( QPen( Qt::red, 2, Qt::DotLine ) );
|
||||
#else
|
||||
setRubberBandPen( QPen( Qt::red ) );
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual QwtText trackerTextF( const QPointF &pos ) const
|
||||
{
|
||||
QColor bg( Qt::white );
|
||||
|
||||
QwtText text = QwtPlotZoomer::trackerTextF( pos );
|
||||
text.setBackgroundBrush( QBrush( bg ) );
|
||||
return text;
|
||||
}
|
||||
|
||||
virtual void rescale()
|
||||
{
|
||||
QwtScaleWidget *scaleWidget = plot()->axisWidget( yAxis() );
|
||||
QwtScaleDraw *sd = scaleWidget->scaleDraw();
|
||||
|
||||
double minExtent = 0.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->maxTickLength() + 1;
|
||||
minExtent += sd->labelSize(
|
||||
scaleWidget->font(), c_rangeMax ).width();
|
||||
}
|
||||
|
||||
sd->setMinimumExtent( minExtent );
|
||||
|
||||
ScrollZoomer::rescale();
|
||||
}
|
||||
};
|
||||
|
||||
RandomPlot::RandomPlot( QWidget *parent ):
|
||||
IncrementalPlot( parent ),
|
||||
d_timer( 0 ),
|
||||
d_timerCount( 0 )
|
||||
{
|
||||
setFrameStyle( QFrame::NoFrame );
|
||||
setLineWidth( 0 );
|
||||
|
||||
plotLayout()->setAlignCanvasToScales( true );
|
||||
|
||||
QwtPlotGrid *grid = new QwtPlotGrid;
|
||||
grid->setMajorPen( Qt::gray, 0, Qt::DotLine );
|
||||
grid->attach( this );
|
||||
|
||||
setCanvasBackground( QColor( 29, 100, 141 ) ); // nice blue
|
||||
|
||||
setAxisScale( xBottom, 0, c_rangeMax );
|
||||
setAxisScale( yLeft, 0, c_rangeMax );
|
||||
|
||||
replot();
|
||||
|
||||
// enable zooming
|
||||
|
||||
( void ) new Zoomer( canvas() );
|
||||
}
|
||||
|
||||
QSize RandomPlot::sizeHint() const
|
||||
{
|
||||
return QSize( 540, 400 );
|
||||
}
|
||||
|
||||
void RandomPlot::appendPoint()
|
||||
{
|
||||
double x = qrand() % c_rangeMax;
|
||||
x += ( qrand() % 100 ) / 100;
|
||||
|
||||
double y = qrand() % c_rangeMax;
|
||||
y += ( qrand() % 100 ) / 100;
|
||||
|
||||
IncrementalPlot::appendPoint( QPointF( x, y ) );
|
||||
|
||||
if ( --d_timerCount <= 0 )
|
||||
stop();
|
||||
}
|
||||
|
||||
void RandomPlot::append( int timeout, int count )
|
||||
{
|
||||
if ( !d_timer )
|
||||
{
|
||||
d_timer = new QTimer( this );
|
||||
connect( d_timer, SIGNAL( timeout() ), SLOT( appendPoint() ) );
|
||||
}
|
||||
|
||||
d_timerCount = count;
|
||||
|
||||
Q_EMIT running( true );
|
||||
d_timeStamp.start();
|
||||
|
||||
QwtPlotCanvas *plotCanvas = qobject_cast<QwtPlotCanvas *>( canvas() );
|
||||
plotCanvas->setPaintAttribute( QwtPlotCanvas::BackingStore, false );
|
||||
|
||||
d_timer->start( timeout );
|
||||
}
|
||||
|
||||
void RandomPlot::stop()
|
||||
{
|
||||
Q_EMIT elapsed( d_timeStamp.elapsed() );
|
||||
|
||||
if ( d_timer )
|
||||
{
|
||||
d_timer->stop();
|
||||
Q_EMIT running( false );
|
||||
}
|
||||
|
||||
QwtPlotCanvas *plotCanvas = qobject_cast<QwtPlotCanvas *>( canvas() );
|
||||
plotCanvas->setPaintAttribute( QwtPlotCanvas::BackingStore, true );
|
||||
}
|
||||
|
||||
void RandomPlot::clear()
|
||||
{
|
||||
clearPoints();
|
||||
replot();
|
||||
}
|
39
examples/realtime/randomplot.h
Normal file
39
examples/realtime/randomplot.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
#ifndef _RANDOMPLOT_H_
|
||||
#define _RANDOMPLOT_H_ 1
|
||||
|
||||
#include "incrementalplot.h"
|
||||
#include <qdatetime.h>
|
||||
|
||||
class QTimer;
|
||||
|
||||
class RandomPlot: public IncrementalPlot
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
RandomPlot( QWidget *parent );
|
||||
|
||||
virtual QSize sizeHint() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void running( bool );
|
||||
void elapsed( int ms );
|
||||
|
||||
public Q_SLOTS:
|
||||
void clear();
|
||||
void stop();
|
||||
void append( int timeout, int count );
|
||||
|
||||
private Q_SLOTS:
|
||||
void appendPoint();
|
||||
|
||||
private:
|
||||
void initCurve();
|
||||
|
||||
QTimer *d_timer;
|
||||
int d_timerCount;
|
||||
|
||||
QTime d_timeStamp;
|
||||
};
|
||||
|
||||
#endif // _RANDOMPLOT_H_
|
28
examples/realtime/realtime.pro
Normal file
28
examples/realtime/realtime.pro
Normal file
|
@ -0,0 +1,28 @@
|
|||
################################################################
|
||||
# Qwt Widget Library
|
||||
# Copyright (C) 1997 Josef Wilgen
|
||||
# Copyright (C) 2002 Uwe Rathmann
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the Qwt License, Version 1.0
|
||||
################################################################
|
||||
|
||||
include( $${PWD}/../examples.pri )
|
||||
|
||||
TARGET = realtime
|
||||
|
||||
HEADERS = \
|
||||
mainwindow.h \
|
||||
scrollzoomer.h \
|
||||
scrollbar.h \
|
||||
incrementalplot.h \
|
||||
randomplot.h
|
||||
|
||||
SOURCES = \
|
||||
main.cpp \
|
||||
mainwindow.cpp \
|
||||
scrollzoomer.cpp \
|
||||
scrollbar.cpp \
|
||||
incrementalplot.cpp \
|
||||
randomplot.cpp
|
||||
|
170
examples/realtime/scrollbar.cpp
Normal file
170
examples/realtime/scrollbar.cpp
Normal file
|
@ -0,0 +1,170 @@
|
|||
#include <qstyle.h>
|
||||
#include <qstyleoption.h>
|
||||
#include "scrollbar.h"
|
||||
|
||||
ScrollBar::ScrollBar( QWidget * parent ):
|
||||
QScrollBar( parent )
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
ScrollBar::ScrollBar( Qt::Orientation o,
|
||||
QWidget *parent ):
|
||||
QScrollBar( o, parent )
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
ScrollBar::ScrollBar( double minBase, double maxBase,
|
||||
Qt::Orientation o, QWidget *parent ):
|
||||
QScrollBar( o, parent )
|
||||
{
|
||||
init();
|
||||
setBase( minBase, maxBase );
|
||||
moveSlider( minBase, maxBase );
|
||||
}
|
||||
|
||||
void ScrollBar::init()
|
||||
{
|
||||
d_inverted = orientation() == Qt::Vertical;
|
||||
d_baseTicks = 1000000;
|
||||
d_minBase = 0.0;
|
||||
d_maxBase = 1.0;
|
||||
moveSlider( d_minBase, d_maxBase );
|
||||
|
||||
connect( this, SIGNAL( sliderMoved( int ) ), SLOT( catchSliderMoved( int ) ) );
|
||||
connect( this, SIGNAL( valueChanged( int ) ), SLOT( catchValueChanged( int ) ) );
|
||||
}
|
||||
|
||||
void ScrollBar::setInverted( bool inverted )
|
||||
{
|
||||
if ( d_inverted != inverted )
|
||||
{
|
||||
d_inverted = inverted;
|
||||
moveSlider( minSliderValue(), maxSliderValue() );
|
||||
}
|
||||
}
|
||||
|
||||
bool ScrollBar::isInverted() const
|
||||
{
|
||||
return d_inverted;
|
||||
}
|
||||
|
||||
void ScrollBar::setBase( double min, double max )
|
||||
{
|
||||
if ( min != d_minBase || max != d_maxBase )
|
||||
{
|
||||
d_minBase = min;
|
||||
d_maxBase = max;
|
||||
|
||||
moveSlider( minSliderValue(), maxSliderValue() );
|
||||
}
|
||||
}
|
||||
|
||||
void ScrollBar::moveSlider( double min, double max )
|
||||
{
|
||||
const int sliderTicks = qRound( ( max - min ) /
|
||||
( d_maxBase - d_minBase ) * d_baseTicks );
|
||||
|
||||
// setRange initiates a valueChanged of the scrollbars
|
||||
// in some situations. So we block
|
||||
// and unblock the signals.
|
||||
|
||||
blockSignals( true );
|
||||
|
||||
setRange( sliderTicks / 2, d_baseTicks - sliderTicks / 2 );
|
||||
int steps = sliderTicks / 200;
|
||||
if ( steps <= 0 )
|
||||
steps = 1;
|
||||
|
||||
setSingleStep( steps );
|
||||
setPageStep( sliderTicks );
|
||||
|
||||
int tick = mapToTick( min + ( max - min ) / 2 );
|
||||
if ( isInverted() )
|
||||
tick = d_baseTicks - tick;
|
||||
|
||||
setSliderPosition( tick );
|
||||
blockSignals( false );
|
||||
}
|
||||
|
||||
double ScrollBar::minBaseValue() const
|
||||
{
|
||||
return d_minBase;
|
||||
}
|
||||
|
||||
double ScrollBar::maxBaseValue() const
|
||||
{
|
||||
return d_maxBase;
|
||||
}
|
||||
|
||||
void ScrollBar::sliderRange( int value, double &min, double &max ) const
|
||||
{
|
||||
if ( isInverted() )
|
||||
value = d_baseTicks - value;
|
||||
|
||||
const int visibleTicks = pageStep();
|
||||
|
||||
min = mapFromTick( value - visibleTicks / 2 );
|
||||
max = mapFromTick( value + visibleTicks / 2 );
|
||||
}
|
||||
|
||||
double ScrollBar::minSliderValue() const
|
||||
{
|
||||
double min, dummy;
|
||||
sliderRange( value(), min, dummy );
|
||||
|
||||
return min;
|
||||
}
|
||||
|
||||
double ScrollBar::maxSliderValue() const
|
||||
{
|
||||
double max, dummy;
|
||||
sliderRange( value(), dummy, max );
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
int ScrollBar::mapToTick( double v ) const
|
||||
{
|
||||
const double pos = ( v - d_minBase ) / ( d_maxBase - d_minBase ) * d_baseTicks;
|
||||
return static_cast<int>( pos );
|
||||
}
|
||||
|
||||
double ScrollBar::mapFromTick( int tick ) const
|
||||
{
|
||||
return d_minBase + ( d_maxBase - d_minBase ) * tick / d_baseTicks;
|
||||
}
|
||||
|
||||
void ScrollBar::catchValueChanged( int value )
|
||||
{
|
||||
double min, max;
|
||||
sliderRange( value, min, max );
|
||||
Q_EMIT valueChanged( orientation(), min, max );
|
||||
}
|
||||
|
||||
void ScrollBar::catchSliderMoved( int value )
|
||||
{
|
||||
double min, max;
|
||||
sliderRange( value, min, max );
|
||||
Q_EMIT sliderMoved( orientation(), min, max );
|
||||
}
|
||||
|
||||
int ScrollBar::extent() const
|
||||
{
|
||||
QStyleOptionSlider opt;
|
||||
opt.init( this );
|
||||
opt.subControls = QStyle::SC_None;
|
||||
opt.activeSubControls = QStyle::SC_None;
|
||||
opt.orientation = orientation();
|
||||
opt.minimum = minimum();
|
||||
opt.maximum = maximum();
|
||||
opt.sliderPosition = sliderPosition();
|
||||
opt.sliderValue = value();
|
||||
opt.singleStep = singleStep();
|
||||
opt.pageStep = pageStep();
|
||||
opt.upsideDown = invertedAppearance();
|
||||
if ( orientation() == Qt::Horizontal )
|
||||
opt.state |= QStyle::State_Horizontal;
|
||||
return style()->pixelMetric( QStyle::PM_ScrollBarExtent, &opt, this );
|
||||
}
|
53
examples/realtime/scrollbar.h
Normal file
53
examples/realtime/scrollbar.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
#ifndef _SCROLLBAR_H
|
||||
#define _SCROLLBAR_H 1
|
||||
|
||||
#include <qscrollbar.h>
|
||||
|
||||
class ScrollBar: public QScrollBar
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ScrollBar( QWidget *parent = NULL );
|
||||
ScrollBar( Qt::Orientation, QWidget *parent = NULL );
|
||||
ScrollBar( double minBase, double maxBase,
|
||||
Qt::Orientation o, QWidget *parent = NULL );
|
||||
|
||||
void setInverted( bool );
|
||||
bool isInverted() const;
|
||||
|
||||
double minBaseValue() const;
|
||||
double maxBaseValue() const;
|
||||
|
||||
double minSliderValue() const;
|
||||
double maxSliderValue() const;
|
||||
|
||||
int extent() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void sliderMoved( Qt::Orientation, double, double );
|
||||
void valueChanged( Qt::Orientation, double, double );
|
||||
|
||||
public Q_SLOTS:
|
||||
virtual void setBase( double min, double max );
|
||||
virtual void moveSlider( double min, double max );
|
||||
|
||||
protected:
|
||||
void sliderRange( int value, double &min, double &max ) const;
|
||||
int mapToTick( double ) const;
|
||||
double mapFromTick( int ) const;
|
||||
|
||||
private Q_SLOTS:
|
||||
void catchValueChanged( int value );
|
||||
void catchSliderMoved( int value );
|
||||
|
||||
private:
|
||||
void init();
|
||||
|
||||
bool d_inverted;
|
||||
double d_minBase;
|
||||
double d_maxBase;
|
||||
int d_baseTicks;
|
||||
};
|
||||
|
||||
#endif
|
480
examples/realtime/scrollzoomer.cpp
Normal file
480
examples/realtime/scrollzoomer.cpp
Normal file
|
@ -0,0 +1,480 @@
|
|||
#include <qevent.h>
|
||||
#include <qwt_plot_canvas.h>
|
||||
#include <qwt_plot_layout.h>
|
||||
#include <qwt_scale_engine.h>
|
||||
#include <qwt_scale_widget.h>
|
||||
#include "scrollbar.h"
|
||||
#include "scrollzoomer.h"
|
||||
|
||||
class ScrollData
|
||||
{
|
||||
public:
|
||||
ScrollData():
|
||||
scrollBar( NULL ),
|
||||
position( ScrollZoomer::OppositeToScale ),
|
||||
mode( Qt::ScrollBarAsNeeded )
|
||||
{
|
||||
}
|
||||
|
||||
~ScrollData()
|
||||
{
|
||||
delete scrollBar;
|
||||
}
|
||||
|
||||
ScrollBar *scrollBar;
|
||||
ScrollZoomer::ScrollBarPosition position;
|
||||
Qt::ScrollBarPolicy mode;
|
||||
};
|
||||
|
||||
ScrollZoomer::ScrollZoomer( QWidget *canvas ):
|
||||
QwtPlotZoomer( canvas ),
|
||||
d_cornerWidget( NULL ),
|
||||
d_hScrollData( NULL ),
|
||||
d_vScrollData( NULL ),
|
||||
d_inZoom( false )
|
||||
{
|
||||
for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
|
||||
d_alignCanvasToScales[ axis ] = false;
|
||||
|
||||
if ( !canvas )
|
||||
return;
|
||||
|
||||
d_hScrollData = new ScrollData;
|
||||
d_vScrollData = new ScrollData;
|
||||
}
|
||||
|
||||
ScrollZoomer::~ScrollZoomer()
|
||||
{
|
||||
delete d_cornerWidget;
|
||||
delete d_vScrollData;
|
||||
delete d_hScrollData;
|
||||
}
|
||||
|
||||
void ScrollZoomer::rescale()
|
||||
{
|
||||
QwtScaleWidget *xScale = plot()->axisWidget( xAxis() );
|
||||
QwtScaleWidget *yScale = plot()->axisWidget( yAxis() );
|
||||
|
||||
if ( zoomRectIndex() <= 0 )
|
||||
{
|
||||
if ( d_inZoom )
|
||||
{
|
||||
xScale->setMinBorderDist( 0, 0 );
|
||||
yScale->setMinBorderDist( 0, 0 );
|
||||
|
||||
QwtPlotLayout *layout = plot()->plotLayout();
|
||||
|
||||
for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
|
||||
layout->setAlignCanvasToScale( axis, d_alignCanvasToScales[ axis ] );
|
||||
|
||||
d_inZoom = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !d_inZoom )
|
||||
{
|
||||
/*
|
||||
We set a minimum border distance.
|
||||
Otherwise the canvas size changes when scrolling,
|
||||
between situations where the major ticks are at
|
||||
the canvas borders (requiring extra space for the label)
|
||||
and situations where all labels can be painted below/top
|
||||
or left/right of the canvas.
|
||||
*/
|
||||
int start, end;
|
||||
|
||||
xScale->getBorderDistHint( start, end );
|
||||
xScale->setMinBorderDist( start, end );
|
||||
|
||||
yScale->getBorderDistHint( start, end );
|
||||
yScale->setMinBorderDist( start, end );
|
||||
|
||||
QwtPlotLayout *layout = plot()->plotLayout();
|
||||
for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
|
||||
{
|
||||
d_alignCanvasToScales[axis] =
|
||||
layout->alignCanvasToScale( axis );
|
||||
}
|
||||
|
||||
layout->setAlignCanvasToScales( false );
|
||||
|
||||
d_inZoom = true;
|
||||
}
|
||||
}
|
||||
|
||||
QwtPlotZoomer::rescale();
|
||||
updateScrollBars();
|
||||
}
|
||||
|
||||
ScrollBar *ScrollZoomer::scrollBar( Qt::Orientation orientation )
|
||||
{
|
||||
ScrollBar *&sb = ( orientation == Qt::Vertical )
|
||||
? d_vScrollData->scrollBar : d_hScrollData->scrollBar;
|
||||
|
||||
if ( sb == NULL )
|
||||
{
|
||||
sb = new ScrollBar( orientation, canvas() );
|
||||
sb->hide();
|
||||
connect( sb,
|
||||
SIGNAL( valueChanged( Qt::Orientation, double, double ) ),
|
||||
SLOT( scrollBarMoved( Qt::Orientation, double, double ) ) );
|
||||
}
|
||||
return sb;
|
||||
}
|
||||
|
||||
ScrollBar *ScrollZoomer::horizontalScrollBar() const
|
||||
{
|
||||
return d_hScrollData->scrollBar;
|
||||
}
|
||||
|
||||
ScrollBar *ScrollZoomer::verticalScrollBar() const
|
||||
{
|
||||
return d_vScrollData->scrollBar;
|
||||
}
|
||||
|
||||
void ScrollZoomer::setHScrollBarMode( Qt::ScrollBarPolicy mode )
|
||||
{
|
||||
if ( hScrollBarMode() != mode )
|
||||
{
|
||||
d_hScrollData->mode = mode;
|
||||
updateScrollBars();
|
||||
}
|
||||
}
|
||||
|
||||
void ScrollZoomer::setVScrollBarMode( Qt::ScrollBarPolicy mode )
|
||||
{
|
||||
if ( vScrollBarMode() != mode )
|
||||
{
|
||||
d_vScrollData->mode = mode;
|
||||
updateScrollBars();
|
||||
}
|
||||
}
|
||||
|
||||
Qt::ScrollBarPolicy ScrollZoomer::hScrollBarMode() const
|
||||
{
|
||||
return d_hScrollData->mode;
|
||||
}
|
||||
|
||||
Qt::ScrollBarPolicy ScrollZoomer::vScrollBarMode() const
|
||||
{
|
||||
return d_vScrollData->mode;
|
||||
}
|
||||
|
||||
void ScrollZoomer::setHScrollBarPosition( ScrollBarPosition pos )
|
||||
{
|
||||
if ( d_hScrollData->position != pos )
|
||||
{
|
||||
d_hScrollData->position = pos;
|
||||
updateScrollBars();
|
||||
}
|
||||
}
|
||||
|
||||
void ScrollZoomer::setVScrollBarPosition( ScrollBarPosition pos )
|
||||
{
|
||||
if ( d_vScrollData->position != pos )
|
||||
{
|
||||
d_vScrollData->position = pos;
|
||||
updateScrollBars();
|
||||
}
|
||||
}
|
||||
|
||||
ScrollZoomer::ScrollBarPosition ScrollZoomer::hScrollBarPosition() const
|
||||
{
|
||||
return d_hScrollData->position;
|
||||
}
|
||||
|
||||
ScrollZoomer::ScrollBarPosition ScrollZoomer::vScrollBarPosition() const
|
||||
{
|
||||
return d_vScrollData->position;
|
||||
}
|
||||
|
||||
void ScrollZoomer::setCornerWidget( QWidget *w )
|
||||
{
|
||||
if ( w != d_cornerWidget )
|
||||
{
|
||||
if ( canvas() )
|
||||
{
|
||||
delete d_cornerWidget;
|
||||
d_cornerWidget = w;
|
||||
if ( d_cornerWidget->parent() != canvas() )
|
||||
d_cornerWidget->setParent( canvas() );
|
||||
|
||||
updateScrollBars();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QWidget *ScrollZoomer::cornerWidget() const
|
||||
{
|
||||
return d_cornerWidget;
|
||||
}
|
||||
|
||||
bool ScrollZoomer::eventFilter( QObject *object, QEvent *event )
|
||||
{
|
||||
if ( object == canvas() )
|
||||
{
|
||||
switch( event->type() )
|
||||
{
|
||||
case QEvent::Resize:
|
||||
{
|
||||
int left, top, right, bottom;
|
||||
canvas()->getContentsMargins( &left, &top, &right, &bottom );
|
||||
|
||||
QRect rect;
|
||||
rect.setSize( static_cast<QResizeEvent *>( event )->size() );
|
||||
rect.adjust( left, top, -right, -bottom );
|
||||
|
||||
layoutScrollBars( rect );
|
||||
break;
|
||||
}
|
||||
case QEvent::ChildRemoved:
|
||||
{
|
||||
const QObject *child =
|
||||
static_cast<QChildEvent *>( event )->child();
|
||||
|
||||
if ( child == d_cornerWidget )
|
||||
d_cornerWidget = NULL;
|
||||
else if ( child == d_hScrollData->scrollBar )
|
||||
d_hScrollData->scrollBar = NULL;
|
||||
else if ( child == d_vScrollData->scrollBar )
|
||||
d_vScrollData->scrollBar = NULL;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return QwtPlotZoomer::eventFilter( object, event );
|
||||
}
|
||||
|
||||
bool ScrollZoomer::needScrollBar( Qt::Orientation orientation ) const
|
||||
{
|
||||
Qt::ScrollBarPolicy mode;
|
||||
double zoomMin, zoomMax, baseMin, baseMax;
|
||||
|
||||
if ( orientation == Qt::Horizontal )
|
||||
{
|
||||
mode = d_hScrollData->mode;
|
||||
baseMin = zoomBase().left();
|
||||
baseMax = zoomBase().right();
|
||||
zoomMin = zoomRect().left();
|
||||
zoomMax = zoomRect().right();
|
||||
}
|
||||
else
|
||||
{
|
||||
mode = d_vScrollData->mode;
|
||||
baseMin = zoomBase().top();
|
||||
baseMax = zoomBase().bottom();
|
||||
zoomMin = zoomRect().top();
|
||||
zoomMax = zoomRect().bottom();
|
||||
}
|
||||
|
||||
bool needed = false;
|
||||
switch( mode )
|
||||
{
|
||||
case Qt::ScrollBarAlwaysOn:
|
||||
needed = true;
|
||||
break;
|
||||
case Qt::ScrollBarAlwaysOff:
|
||||
needed = false;
|
||||
break;
|
||||
default:
|
||||
{
|
||||
if ( baseMin < zoomMin || baseMax > zoomMax )
|
||||
needed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return needed;
|
||||
}
|
||||
|
||||
void ScrollZoomer::updateScrollBars()
|
||||
{
|
||||
if ( !canvas() )
|
||||
return;
|
||||
|
||||
const int xAxis = QwtPlotZoomer::xAxis();
|
||||
const int yAxis = QwtPlotZoomer::yAxis();
|
||||
|
||||
int xScrollBarAxis = xAxis;
|
||||
if ( hScrollBarPosition() == OppositeToScale )
|
||||
xScrollBarAxis = oppositeAxis( xScrollBarAxis );
|
||||
|
||||
int yScrollBarAxis = yAxis;
|
||||
if ( vScrollBarPosition() == OppositeToScale )
|
||||
yScrollBarAxis = oppositeAxis( yScrollBarAxis );
|
||||
|
||||
|
||||
QwtPlotLayout *layout = plot()->plotLayout();
|
||||
|
||||
bool showHScrollBar = needScrollBar( Qt::Horizontal );
|
||||
if ( showHScrollBar )
|
||||
{
|
||||
ScrollBar *sb = scrollBar( Qt::Horizontal );
|
||||
sb->setPalette( plot()->palette() );
|
||||
sb->setInverted( !plot()->axisScaleDiv( xAxis ).isIncreasing() );
|
||||
sb->setBase( zoomBase().left(), zoomBase().right() );
|
||||
sb->moveSlider( zoomRect().left(), zoomRect().right() );
|
||||
|
||||
if ( !sb->isVisibleTo( canvas() ) )
|
||||
{
|
||||
sb->show();
|
||||
layout->setCanvasMargin( layout->canvasMargin( xScrollBarAxis )
|
||||
+ sb->extent(), xScrollBarAxis );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( horizontalScrollBar() )
|
||||
{
|
||||
horizontalScrollBar()->hide();
|
||||
layout->setCanvasMargin( layout->canvasMargin( xScrollBarAxis )
|
||||
- horizontalScrollBar()->extent(), xScrollBarAxis );
|
||||
}
|
||||
}
|
||||
|
||||
bool showVScrollBar = needScrollBar( Qt::Vertical );
|
||||
if ( showVScrollBar )
|
||||
{
|
||||
ScrollBar *sb = scrollBar( Qt::Vertical );
|
||||
sb->setPalette( plot()->palette() );
|
||||
sb->setInverted( !plot()->axisScaleDiv( yAxis ).isIncreasing() );
|
||||
sb->setBase( zoomBase().top(), zoomBase().bottom() );
|
||||
sb->moveSlider( zoomRect().top(), zoomRect().bottom() );
|
||||
|
||||
if ( !sb->isVisibleTo( canvas() ) )
|
||||
{
|
||||
sb->show();
|
||||
layout->setCanvasMargin( layout->canvasMargin( yScrollBarAxis )
|
||||
+ sb->extent(), yScrollBarAxis );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( verticalScrollBar() )
|
||||
{
|
||||
verticalScrollBar()->hide();
|
||||
layout->setCanvasMargin( layout->canvasMargin( yScrollBarAxis )
|
||||
- verticalScrollBar()->extent(), yScrollBarAxis );
|
||||
}
|
||||
}
|
||||
|
||||
if ( showHScrollBar && showVScrollBar )
|
||||
{
|
||||
if ( d_cornerWidget == NULL )
|
||||
{
|
||||
d_cornerWidget = new QWidget( canvas() );
|
||||
d_cornerWidget->setAutoFillBackground( true );
|
||||
d_cornerWidget->setPalette( plot()->palette() );
|
||||
}
|
||||
d_cornerWidget->show();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( d_cornerWidget )
|
||||
d_cornerWidget->hide();
|
||||
}
|
||||
|
||||
layoutScrollBars( canvas()->contentsRect() );
|
||||
plot()->updateLayout();
|
||||
}
|
||||
|
||||
void ScrollZoomer::layoutScrollBars( const QRect &rect )
|
||||
{
|
||||
int hPos = xAxis();
|
||||
if ( hScrollBarPosition() == OppositeToScale )
|
||||
hPos = oppositeAxis( hPos );
|
||||
|
||||
int vPos = yAxis();
|
||||
if ( vScrollBarPosition() == OppositeToScale )
|
||||
vPos = oppositeAxis( vPos );
|
||||
|
||||
ScrollBar *hScrollBar = horizontalScrollBar();
|
||||
ScrollBar *vScrollBar = verticalScrollBar();
|
||||
|
||||
const int hdim = hScrollBar ? hScrollBar->extent() : 0;
|
||||
const int vdim = vScrollBar ? vScrollBar->extent() : 0;
|
||||
|
||||
if ( hScrollBar && hScrollBar->isVisible() )
|
||||
{
|
||||
int x = rect.x();
|
||||
int y = ( hPos == QwtPlot::xTop )
|
||||
? rect.top() : rect.bottom() - hdim + 1;
|
||||
int w = rect.width();
|
||||
|
||||
if ( vScrollBar && vScrollBar->isVisible() )
|
||||
{
|
||||
if ( vPos == QwtPlot::yLeft )
|
||||
x += vdim;
|
||||
w -= vdim;
|
||||
}
|
||||
|
||||
hScrollBar->setGeometry( x, y, w, hdim );
|
||||
}
|
||||
if ( vScrollBar && vScrollBar->isVisible() )
|
||||
{
|
||||
int pos = yAxis();
|
||||
if ( vScrollBarPosition() == OppositeToScale )
|
||||
pos = oppositeAxis( pos );
|
||||
|
||||
int x = ( vPos == QwtPlot::yLeft )
|
||||
? rect.left() : rect.right() - vdim + 1;
|
||||
int y = rect.y();
|
||||
|
||||
int h = rect.height();
|
||||
|
||||
if ( hScrollBar && hScrollBar->isVisible() )
|
||||
{
|
||||
if ( hPos == QwtPlot::xTop )
|
||||
y += hdim;
|
||||
|
||||
h -= hdim;
|
||||
}
|
||||
|
||||
vScrollBar->setGeometry( x, y, vdim, h );
|
||||
}
|
||||
if ( hScrollBar && hScrollBar->isVisible() &&
|
||||
vScrollBar && vScrollBar->isVisible() )
|
||||
{
|
||||
if ( d_cornerWidget )
|
||||
{
|
||||
QRect cornerRect(
|
||||
vScrollBar->pos().x(), hScrollBar->pos().y(),
|
||||
vdim, hdim );
|
||||
d_cornerWidget->setGeometry( cornerRect );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScrollZoomer::scrollBarMoved(
|
||||
Qt::Orientation o, double min, double max )
|
||||
{
|
||||
Q_UNUSED( max );
|
||||
|
||||
if ( o == Qt::Horizontal )
|
||||
moveTo( QPointF( min, zoomRect().top() ) );
|
||||
else
|
||||
moveTo( QPointF( zoomRect().left(), min ) );
|
||||
|
||||
Q_EMIT zoomed( zoomRect() );
|
||||
}
|
||||
|
||||
int ScrollZoomer::oppositeAxis( int axis ) const
|
||||
{
|
||||
switch( axis )
|
||||
{
|
||||
case QwtPlot::xBottom:
|
||||
return QwtPlot::xTop;
|
||||
case QwtPlot::xTop:
|
||||
return QwtPlot::xBottom;
|
||||
case QwtPlot::yLeft:
|
||||
return QwtPlot::yRight;
|
||||
case QwtPlot::yRight:
|
||||
return QwtPlot::yLeft;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return axis;
|
||||
}
|
67
examples/realtime/scrollzoomer.h
Normal file
67
examples/realtime/scrollzoomer.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
#ifndef _SCROLLZOOMER_H
|
||||
#define _SCROLLZOOMER_H
|
||||
|
||||
#include <qglobal.h>
|
||||
#include <qwt_plot_zoomer.h>
|
||||
#include <qwt_plot.h>
|
||||
|
||||
class ScrollData;
|
||||
class ScrollBar;
|
||||
|
||||
class ScrollZoomer: public QwtPlotZoomer
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum ScrollBarPosition
|
||||
{
|
||||
AttachedToScale,
|
||||
OppositeToScale
|
||||
};
|
||||
|
||||
ScrollZoomer( QWidget * );
|
||||
virtual ~ScrollZoomer();
|
||||
|
||||
ScrollBar *horizontalScrollBar() const;
|
||||
ScrollBar *verticalScrollBar() const;
|
||||
|
||||
void setHScrollBarMode( Qt::ScrollBarPolicy );
|
||||
void setVScrollBarMode( Qt::ScrollBarPolicy );
|
||||
|
||||
Qt::ScrollBarPolicy vScrollBarMode () const;
|
||||
Qt::ScrollBarPolicy hScrollBarMode () const;
|
||||
|
||||
void setHScrollBarPosition( ScrollBarPosition );
|
||||
void setVScrollBarPosition( ScrollBarPosition );
|
||||
|
||||
ScrollBarPosition hScrollBarPosition() const;
|
||||
ScrollBarPosition vScrollBarPosition() const;
|
||||
|
||||
QWidget* cornerWidget() const;
|
||||
virtual void setCornerWidget( QWidget * );
|
||||
|
||||
virtual bool eventFilter( QObject *, QEvent * );
|
||||
|
||||
virtual void rescale();
|
||||
|
||||
protected:
|
||||
virtual ScrollBar *scrollBar( Qt::Orientation );
|
||||
virtual void updateScrollBars();
|
||||
virtual void layoutScrollBars( const QRect & );
|
||||
|
||||
private Q_SLOTS:
|
||||
void scrollBarMoved( Qt::Orientation o, double min, double max );
|
||||
|
||||
private:
|
||||
bool needScrollBar( Qt::Orientation ) const;
|
||||
int oppositeAxis( int ) const;
|
||||
|
||||
QWidget *d_cornerWidget;
|
||||
|
||||
ScrollData *d_hScrollData;
|
||||
ScrollData *d_vScrollData;
|
||||
|
||||
bool d_inZoom;
|
||||
bool d_alignCanvasToScales[ QwtPlot::axisCnt ];
|
||||
};
|
||||
|
||||
#endif
|
266
examples/realtime/start.xpm
Normal file
266
examples/realtime/start.xpm
Normal file
|
@ -0,0 +1,266 @@
|
|||
/* XPM */
|
||||
static const char *start_xpm[] = {
|
||||
/* width height num_colors chars_per_pixel */
|
||||
" 32 32 227 2",
|
||||
/* colors */
|
||||
".. c #040204",
|
||||
".# c #848684",
|
||||
".a c #c4c2b4",
|
||||
".b c #843a04",
|
||||
".c c #444244",
|
||||
".d c #ece2cc",
|
||||
".e c #fca234",
|
||||
".f c #c45e04",
|
||||
".g c #bca27c",
|
||||
".h c #646264",
|
||||
".i c #e4c69c",
|
||||
".j c #847254",
|
||||
".k c #c4a684",
|
||||
".l c #443e34",
|
||||
".m c #a48e6c",
|
||||
".n c #f4f2e4",
|
||||
".o c #24261c",
|
||||
".p c #a44a04",
|
||||
".q c #c4825c",
|
||||
".r c #644634",
|
||||
".s c #b4b2ac",
|
||||
".t c #747274",
|
||||
".u c #844e2c",
|
||||
".v c #ece6dc",
|
||||
".w c #c4b6a4",
|
||||
".x c #a49274",
|
||||
".y c #343634",
|
||||
".z c #fcd69c",
|
||||
".A c #b4aa9c",
|
||||
".B c #8c8e8c",
|
||||
".C c #545254",
|
||||
".D c #f4f2ec",
|
||||
".E c #fcb67c",
|
||||
".F c #e4965c",
|
||||
".G c #e46634",
|
||||
".H c #141614",
|
||||
".I c #d4c2a4",
|
||||
".J c #746a5c",
|
||||
".K c #fcc2a4",
|
||||
".L c #342a1c",
|
||||
".M c #fc9204",
|
||||
".N c #a45e2c",
|
||||
".O c #94521c",
|
||||
".P c #a4560c",
|
||||
".Q c #645e54",
|
||||
".R c #ec7a04",
|
||||
".S c #f4deac",
|
||||
".T c #5c462c",
|
||||
".U c #bcaa8c",
|
||||
".V c #d4be9c",
|
||||
".W c #fcfaf4",
|
||||
".X c #d4cab4",
|
||||
".Y c #1c0a04",
|
||||
".Z c #6c6a6c",
|
||||
".0 c #e4caa4",
|
||||
".1 c #2c2a1c",
|
||||
".2 c #74462c",
|
||||
".3 c #84562c",
|
||||
".4 c #f4eee4",
|
||||
".5 c #c4beb4",
|
||||
".6 c #a49a84",
|
||||
".7 c #f4ba7c",
|
||||
".8 c #dc966c",
|
||||
".9 c #948674",
|
||||
"#. c #fc8a04",
|
||||
"## c #f4eab4",
|
||||
"#a c #fcb26c",
|
||||
"#b c #c4ae94",
|
||||
"#c c #f4e6d4",
|
||||
"#d c #9c8e74",
|
||||
"#e c #fc7e04",
|
||||
"#f c #140604",
|
||||
"#g c #b4a28c",
|
||||
"#h c #6c625c",
|
||||
"#i c #8c7e64",
|
||||
"#j c #f4ae84",
|
||||
"#k c #e4decc",
|
||||
"#l c #ac5204",
|
||||
"#m c #e48a4c",
|
||||
"#n c #7c7a7c",
|
||||
"#o c #ccba9c",
|
||||
"#p c #fcd2b4",
|
||||
"#q c #bcae9c",
|
||||
"#r c #dcc6a4",
|
||||
"#s c #ac723c",
|
||||
"#t c #e4ceb4",
|
||||
"#u c #ec9e74",
|
||||
"#v c #8c8a8c",
|
||||
"#w c #8c4204",
|
||||
"#x c #4c4a34",
|
||||
"#y c #7c3a04",
|
||||
"#z c #fcfecc",
|
||||
"#A c #2c221c",
|
||||
"#B c #ac4e04",
|
||||
"#C c #d48264",
|
||||
"#D c #bcb2a4",
|
||||
"#E c #a49684",
|
||||
"#F c #b4aeac",
|
||||
"#G c #5c5a5c",
|
||||
"#H c #fcf2ec",
|
||||
"#I c #fcb28c",
|
||||
"#J c #7c6e5c",
|
||||
"#K c #fcce9c",
|
||||
"#L c #3c2e24",
|
||||
"#M c #bc9e71",
|
||||
"#N c #fc922c",
|
||||
"#O c #bc622c",
|
||||
"#P c #b45604",
|
||||
"#Q c #f47a08",
|
||||
"#R c #fcdeb8",
|
||||
"#S c #544e44",
|
||||
"#T c #fcfefc",
|
||||
"#U c #e4ceaa",
|
||||
"#V c #8c5a2c",
|
||||
"#W c #e49e7c",
|
||||
"#X c #f4eadb",
|
||||
"#Y c #9c9284",
|
||||
"#Z c #f4ae90",
|
||||
"#0 c #c47e5c",
|
||||
"#1 c #bc824c",
|
||||
"#2 c #e47634",
|
||||
"#3 c #e46e24",
|
||||
"#4 c #b48e6c",
|
||||
"#5 c #7c5a4c",
|
||||
"#6 c #744e2c",
|
||||
"#7 c #fcba9c",
|
||||
"#8 c #cccacc",
|
||||
"#9 c #f4722c",
|
||||
"a. c #c46224",
|
||||
"a# c #e47a54",
|
||||
"aa c #ac663c",
|
||||
"ab c #fce2cc",
|
||||
"ac c #945634",
|
||||
"ad c #fceacc",
|
||||
"ae c #3c3e3c",
|
||||
"af c #ec9e54",
|
||||
"ag c #843e1c",
|
||||
"ah c #fccab0",
|
||||
"ai c #8c8274",
|
||||
"aj c #4c4634",
|
||||
"ak c #ecc2ac",
|
||||
"al c #8c765c",
|
||||
"am c #7c7264",
|
||||
"an c #e49a7c",
|
||||
"ao c #6c4e34",
|
||||
"ap c #fc9a2c",
|
||||
"aq c #4c4a4c",
|
||||
"ar c #ccbea4",
|
||||
"as c #fcf6dc",
|
||||
"at c #3c3a3c",
|
||||
"au c #949294",
|
||||
"av c #fceebc",
|
||||
"aw c #fcaa7c",
|
||||
"ax c #ecdac8",
|
||||
"ay c #0c0604",
|
||||
"az c #fc8204",
|
||||
"aA c #847664",
|
||||
"aB c #e4d6c4",
|
||||
"aC c #fcd2ac",
|
||||
"aD c #1c1a14",
|
||||
"aE c #342e2c",
|
||||
"aF c #240e04",
|
||||
"aG c #2c2e2c",
|
||||
"aH c #fcbe7c",
|
||||
"aI c #fc8e14",
|
||||
"aJ c #fc7a14",
|
||||
"aK c #944604",
|
||||
"aL c #7c3e14",
|
||||
"aM c #fcfadc",
|
||||
"aN c #645244",
|
||||
"aO c #bcb6b4",
|
||||
"aP c #bc5604",
|
||||
"aQ c #7c522c",
|
||||
"aR c #cc8264",
|
||||
"aS c #dccab0",
|
||||
"aT c #ac9a84",
|
||||
"aU c #f4e2cc",
|
||||
"aV c #a45e3c",
|
||||
"aW c #9c5634",
|
||||
"aX c #fca634",
|
||||
"aY c #c4aa89",
|
||||
"aZ c #a44e07",
|
||||
"a0 c #b4b6b4",
|
||||
"a1 c #c4baa9",
|
||||
"a2 c #a4967c",
|
||||
"a3 c #b4aea4",
|
||||
"a4 c #d4c6a8",
|
||||
"a5 c #5c4a34",
|
||||
"a6 c #bcae94",
|
||||
"a7 c #845a2c",
|
||||
"a8 c #948a7c",
|
||||
"a9 c #c4b299",
|
||||
"b. c #b4a690",
|
||||
"b# c #6c6658",
|
||||
"ba c #fcd6b4",
|
||||
"bb c #2c261d",
|
||||
"bc c #fcf6f0",
|
||||
"bd c #fcb694",
|
||||
"be c #fc9624",
|
||||
"bf c #646664",
|
||||
"bg c #747674",
|
||||
"bh c #eceadc",
|
||||
"bi c #545654",
|
||||
"bj c #b49e7c",
|
||||
"bk c #6c6e6c",
|
||||
"bl c #fc8e04",
|
||||
"bm c #fcb66c",
|
||||
"bn c #7c7e7c",
|
||||
"bo c #5c5e5c",
|
||||
"bp c #8c8674",
|
||||
"bq c #fc8604",
|
||||
"br c #bc5a04",
|
||||
"bs c #fca23c",
|
||||
"bt c #443e3c",
|
||||
"bu c #a4927c",
|
||||
"bv c #b4aaa4",
|
||||
"bw c #746a64",
|
||||
"bx c #342a24",
|
||||
"by c #fcfafc",
|
||||
"bz c #2c2a24",
|
||||
"bA c #a49a8c",
|
||||
"bB c #bcbabc",
|
||||
"bC c #9c8e7c",
|
||||
"bD c #8c7e6c",
|
||||
"bE c #ccbaa4",
|
||||
"bF c #fcd2bc",
|
||||
"bG c #fcb294",
|
||||
/* pixels */
|
||||
"#Gbi#G.#bnbg.t.Zbfbf.hbo#G.Caqaq.c.C.C.C.C.C.C.C.C.C.C.Cbi#Gbi#G",
|
||||
"#Gbi#Gbg#8#8.a#8#8#8#8#8#8#8#8.B#8#8#8#8#8#8#8#8#8#8#8.C#Gbi#Gbi",
|
||||
"bi#Gbi#n#8#T#T#T#T#T#T#T#T#T#TbB#T#T#T#T#T#T#T#T#T#T#8aq#6afbm#z",
|
||||
"#Gbi#Gbk#8#T#T#T#T#T#T#T#T#T#TbB#T#T#T#T#T#T#T#T#T#T#8#6af#aavaX",
|
||||
"bi#Gbibk#8#T#T#T#T#T#T#T#T#T#TbB#T#T#T#T#T#T#T#T#T#T#6af#a##aX#.",
|
||||
"#Gbi#Gbk#8#T#T#T#T#T#T#T#T#T#TbB#T#T#T#T#T#T#T#T#T.3af#a.S.e#.bq",
|
||||
"#Gbi#G.Z#8#T#T#T#T#T#T#T#T#T#TbB#T#T#T#T#T#T#T#TaQaf#a#R.e#eazbq",
|
||||
"bi#GbibkaubBbBbBbBbBbBbBbBbBbBbBbBbBbBbBbBbBbBa7af#aba.e#eazbq.M",
|
||||
"#Gbi#G.Z#8#T#T#T#T#T#T#T#T#T#TbB#T#T#T#T#T#T#Vaf#ababs#ebqbq#.az",
|
||||
"#Gbi#Gbf#8#T#T#T#T#T#T#T#T#T#TbB#T#T#Tby#T#saf#a#Kap#ebqbqbl#Q.f",
|
||||
"bi#Gbi.Z#8#T#T#T#T#T#T#T#T#T#TbB#T#T#T#T.Naf#a.z#N#ebqbqbl.R.f#l",
|
||||
"#Gbi#Gbf#8#T#T#T#T#T#T#T#T#T#TbB#T#T#T#1af.EaHbe#ebqbq#..Rbr#B#y",
|
||||
"bi#Gbibf#8#T#T#T#T#T#T#T#T#T#TbB#T#T.F.7#jawaI#ebqbqbl.R#PaZ.b..",
|
||||
"#Gbi#GbfaubBbBbBbBbBbBbBbBbBbBbBbBbG#RaMak#m#ebqbqbl#Q#P#B#w.Y.y",
|
||||
"bi#Gbibf#8#T#T#T#T#T#T#T#T#T#TaObyaC.Wab#Z#2bqbq.M.RaP.p#way.y.y",
|
||||
"#Gbi#G.h#8#T#T#T#T#T#T#T#T#Tbya0#I#Tad.K#j#2#QaJ.Rbr.p#yaF.y.yat",
|
||||
"bi#Gbi.h#8#T#T#T#T#T#T#T#Tby.W.saCasba#Za#.G#9#3aPaZaK.Y.y.yat.c",
|
||||
"#Gbi#Gbo#8#T#T#T#T#T#T#Tby.Wbc#I#T#p#7.8#0a.#O.P.paLay...yatbtaq",
|
||||
"bi#Gbi.h#8#T#T#T#T#T#Tby.Wbc.DaCadah#W#0aa.O.2.ragaF#h..ataeaq.C",
|
||||
"#Gbi#GboaubBbBbBbBbBaOa0.sa3bdasahanaRaV.u.Ta5ae#f.Q#S..aeaq.Cbi",
|
||||
"bi#Gbibo#8#T#T#T#T.Wbcbc.D#HaCbF#uaRaWaQa5ajbt.HbDai#J..aq.Cbibi",
|
||||
"#Gbi#Gbo#8#T#Tby.W.W.D#H.nbdab#u#Cac.uaN.o..bDaiaia8#i...Cbibi#G",
|
||||
"bi#Gbibo#8#T#Tbybc.Dbc.n.4#4.8.q#5.r.l..#vbDaia8a2#g#d..bibi#Gbi",
|
||||
"#Gbi#G#G#8#T.Wbc.D#H.D#X.j.Lao#5#L.H#vaibpbpbCaT.U#oa2..bi#Gbi#G",
|
||||
"bi#Gbi#G#8.Wbc.D#H.n.4bjajaD#A...#bpai.9bC#E#ga9.V#r.gbb#Gbi#Gbi",
|
||||
"#Gbi#Gbiaua0.s.s#Fa3bvaG....#vbwb#b#.JbwaA#i.9bC.m.xal.1bi#Gbi#G",
|
||||
"bi#Gbi#G#8.D#H.4.4#X.v#x#v#qbAb##Y.6b.a6ar.I#r#r.0.i.g.Lbi#Gbi#G",
|
||||
"bi#Gbibi#8.D.4.4#X#c.vax.X.AbAamb.#D#oa4aS#r.0.0.i.i#M#A#Gbi#Gbi",
|
||||
"#Gbi#G.C#8.n.4#X#X.daUaBaS.wa6aiar#raS.0#U#U.0.i.0#r#Mbb#Gbi#Gbi",
|
||||
"bi#Gbiaq#8.4#Xbh.v#c.d#kaB.Xa4buaS#U#t#U#U.0.0#r.i.i#Mbbbi#Gbi#G",
|
||||
"#Gbi#Gae.a.a.5a1bE.w.w.w#ba6.U#iaYaYaY.k.g.g.g#M#M#M#M.Lbi#Gbi#G",
|
||||
"bi#Gbi.HbxaEbxaEbz.LaEbzbzbbbzbbbbbxbb.Lbbbb.1.Lbb.1#Aay#Gbi#Gbi"
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue