da hab ich mal n beispielcode fuer dich:
header:
Code:
#ifndef _FUNCTIONPLOT_H
#define _FUNCTIONPLOT_H
#include <qapplication.h>
#include <qwidget.h>
typedef struct {
double x, y;
} valuePair;
//................................................... Klasse FunctionPlot
class FunctionPlot : public QWidget
{
public:
//... Konstruktor, dem die Anzahl der Wertepaare fuer
//... die zu plottende Funktion uebergeben wird
FunctionPlot( int n, QWidget *p=0, const char *name=0 );
//... Destruktor; gibt den fuer die Wertepaare
//... reservierten Speicherplatz wieder frei
~FunctionPlot() { delete [] values; }
//... setzt das i.te Wertepaar auf die Werte v.x und v.y
void setValue( int i, valuePair v );
//... setzt die ersten n Wertepaare auf die Werte aus dem Array v
void setValues( int n, valuePair v[] );
//... legt die minimalen und maximalen x- und y-Werte
//... des Bereichs fest, der von der Funktion anzuzeigen ist
void setPlotView( double minx, double miny, double maxx, double maxy );
//... bewirkt, dass die Funktion gezeichnet wird
void plotIt( void );
protected:
//... bewirkt ein Vergroessern des Funktionsbereichs
//... "Cursor rechts": negative x-Achse wird verlaengert
//... "Cursor links" : positive x-Achse wird verlaengert
//... "Cursor hoch" : negative y-Achse wird verlaengert
//... "Cursor tief" : positive y-Achse wird verlaengert
virtual void keyPressEvent( QKeyEvent *ev );
//... leitet ein Zoomen (Verkleinern des Funktionsbereichs) ein
virtual void mousePressEvent( QMouseEvent *ev );
//... Zoomen (Verkleinern des Funktionsbereichs) findet gerade statt
virtual void mouseMoveEvent( QMouseEvent *ev );
//... Zoomen (Verkleinern des Funktionsbereichs) wird abgeschlossen
virtual void mouseReleaseEvent( QMouseEvent *ev );
//... bewirkt ein Neumalen der Funktion in dem aktuell
//... festgelegten Funktionsbereich
virtual void paintEvent( QPaintEvent *ev );
private:
//... zeichnen die x- bzw. y-Achse
void drawXScale( QPainter *p, double i, int yp );
void drawYScale( QPainter *p, double i, int xp );
int valueNo; // Anzahl der Wertepaare der Funktion
valuePair *values; // enthaelt die einzelnen Wertepaare
bool plotViewSet; // zeigt an, ob explizit ein eigener
// anzuzeigender Funktionsbereich festgelegt
// wurde, also setPlotView() aufgerufen wurde.
// plotViewSet=false, werden die minimalen
// und maximalen x- und y-Werte des
// anzuzeigenden Bereichs implizit bestimmt
double minX, minY, maxX, maxY, // minimale und maximale x- und y-Werte
// des anzuzeigenden Bereichs
xFactor, yFactor; // interne Projektionsfaktoren
QPoint startPos, letztePos, neuePos; // Mauspositionen, die fuer
// das Zoomen mit der Maus
// benoetigt werden.
bool dragging, ersteMal; // fuer Ziehen der Maus benoetigt
QColor farbe; // zeigt an, ob Zoomen aktiviert ist (gruen)
// oder nicht (rot)
};
#endif
implementierung:
Code:
#include <qpainter.h>
#include <stdio.h>
#include "functionplot.h"
//.............................................. Konstruktor FunctionPlot
FunctionPlot::FunctionPlot( int n, QWidget *p, const char *name )
: QWidget( p, name ) {
valueNo = n;
values = new valuePair [n];
for ( int i=0; i<n; i++ )
values[i].x = values[i].y = 0.0;
plotViewSet = false;
}
//.............................................................. setValue
void FunctionPlot::setValue( int i, valuePair v ) {
if ( i >= valueNo || i < 0 )
return;
values[i] = v;
}
//............................................................. setValues
void FunctionPlot::setValues( int n, valuePair v[] ) {
for ( int i=0; i<n; i++ )
setValue( i, v[i] );
}
//........................................................... setPlotView
void FunctionPlot::setPlotView( double minx, double miny,
double maxx, double maxy ) {
plotViewSet = true;
minX = minx;
minY = miny;
maxX = maxx;
maxY = maxy;
}
//.............................................................. plotIt
void FunctionPlot::plotIt( void ) {
if ( !plotViewSet ) {
minX = maxX = values[0].x;
minY = maxY = values[0].y;
for ( int i=1; i<valueNo; i++ ) {
if ( values[i].x < minX ) minX = values[i].x;
if ( values[i].x > maxX ) maxX = values[i].x;
if ( values[i].y < minY ) minY = values[i].y;
if ( values[i].y > maxY ) maxY = values[i].y;
}
//.... Sicherstellen, dass Achsen sichtbar
if ( minX > 0 ) minX = 0;
if ( maxX < 0 ) maxX = 0;
if ( minY > 0 ) minY = 0;
if ( maxY < 0 ) maxY = 0;
}
repaint();
}
//....................................................... keyPressEvent
void FunctionPlot::keyPressEvent( QKeyEvent *ev ) {
double diffX = (maxX-minX) / 10,
diffY = (maxY-minY) / 10;
switch (ev->key() ) {
case Key_Right: minX -= diffX; repaint(); break;
case Key_Left: maxX += diffX; repaint(); break;
case Key_Up: minY -= diffY; repaint(); break;
case Key_Down: maxY += diffY; repaint(); break;
}
}
//..................................................... mousePressEvent
void FunctionPlot::mousePressEvent( QMouseEvent *ev ) {
ersteMal = true;
dragging = false;
startPos = ev->pos();
repaint( false );
}
//...................................................... mouseMoveEvent
void FunctionPlot::mouseMoveEvent( QMouseEvent *ev ) {
if ( !dragging )
//.... Dragging (Ziehen) einschalten, wenn
//.... neue Position mind. 20 Pixel entfernt ist
if ( QABS( startPos.x() - ev->pos().x() ) >= 20 ||
QABS( startPos.y() - ev->pos().y() ) >= 20 )
dragging = true;
if ( dragging ) {
neuePos = ev->pos();
//.... Farbe zeigt an, ob Zoom aktiviert ist
if ( QABS( startPos.x() - ev->pos().x() ) >= 50 &&
QABS( startPos.y() - ev->pos().y() ) >= 50 )
farbe = Qt::green.light( 60 );
else
farbe = Qt::red.light( 150 );
repaint( false );
}
}
//................................................... mouseReleaseEvent
void FunctionPlot::mouseReleaseEvent( QMouseEvent *ev ) {
//.... Bedingung soll versehentliches Zoomen verhindern
if ( QABS( startPos.x() - ev->pos().x() ) >= 50 &&
QABS( startPos.y() - ev->pos().y() ) >= 50 ) {
if ( ev->pos().x() > startPos.x() ) {
maxX = ev->pos().x() / xFactor + minX;
minX = startPos.x() / xFactor + minX;
} else {
maxX = startPos.x() / xFactor + minX;
minX = ev->pos().x() / xFactor + minX;
}
if ( ev->pos().y() > startPos.y() ) {
minY = maxY - ev->pos().y() / yFactor;
maxY = maxY - startPos.y() / yFactor;
} else {
minY = maxY - startPos.y() / yFactor;
maxY = maxY - ev->pos().y() / yFactor;
}
}
dragging = false;
repaint();
}
//.......................................................... paintEvent
void FunctionPlot::paintEvent( QPaintEvent * ) {
QPainter p( this );
double xp, yp, diffX, diffY, i;
xFactor = width() / (maxX -minX),
yFactor = height() / (maxY -minY);
if ( dragging ) {
if ( !ersteMal )
p.eraseRect( QRect( startPos, letztePos ) );
p.fillRect( QRect( startPos, neuePos ), farbe );
letztePos = neuePos;
ersteMal = false;
}
p.setPen( Qt::yellow ); //.... x- und y-Achsen zeichnen
xp = -minX * xFactor;
yp = maxY * yFactor;
p.drawLine( 0, yp, width(), yp ); // x-Achse
p.drawLine( xp, 0, xp, height() ); // y-Achse
diffX = (maxX-minX) / 10; //.... x-Skalen zeichnen/beschriften
for ( i = -diffX; i>=minX; i-=diffX )
drawXScale( &p, i, yp );
for ( i = diffX; i<=maxX; i+=diffX )
drawXScale( &p, i, yp );
diffY = (maxY-minY) / 10; //.... y-Skalen zeichnen/beschriften
for ( i = -diffY; i>=minY; i-=diffY )
drawYScale( &p, i, xp );
for ( i = diffY; i<=maxY; i+=diffY )
drawYScale( &p, i, xp );
//.... Funktion zeichnen
xp = ( values[0].x - minX ) * xFactor;
yp = ( maxY - values[0].y ) * yFactor;
p.moveTo( xp, yp );
p.setPen( Qt::black );
p.setBrush( Qt::black );
p.drawEllipse( xp-1, yp-1, 2, 2 );
for ( i=1; i<valueNo; i++ ) {
xp = ( values[(int)i].x - minX ) * xFactor;
yp = ( maxY - values[(int)i].y ) * yFactor;
p.setPen( Qt::blue.light( 140 ) );
p.lineTo( xp, yp );
p.setPen( Qt::blue.light( 120 ) );
p.drawEllipse( xp, yp, 2, 2 );
}
}
//............................................................ drawXScale
void FunctionPlot::drawXScale( QPainter *p, double i, int yp ) {
QString text;
double xs = (i-minX) * xFactor;
text.sprintf( "%.3g", i );
p->drawLine( xs, yp-2, xs, yp+2 );
p->drawText( xs+1, yp-2, text );
p->setPen( QPen( Qt::yellow, 0, Qt::DotLine ) ); // Raster
p->drawLine( xs, 0, xs, height() );
p->setPen( QPen( Qt::yellow, 0, Qt::SolidLine ) );
}
//............................................................ drawYScale
void FunctionPlot::drawYScale( QPainter *p, double i, int xp ) {
QString text;
double ys = (maxY-i) * yFactor;
text.sprintf( "%.3g", i );
p->drawLine( xp-2, ys, xp+2, ys );
p->drawText( xp+4, ys, text );
p->setPen( QPen( Qt::yellow, 0, Qt::DotLine ) ); // Raster
p->drawLine( 0, ys, width(), ys );
p->setPen( QPen( Qt::yellow, 0, Qt::SolidLine ) );
}
und das beispiel dafuer:
Code:
#include <qapplication.h>
#include <qwidget.h>
#include <math.h>
#include "functionplot.h"
int main( int argc, char* argv[] )
{
QApplication myapp( argc, argv );
const double pi = 4*atan(1);
valuePair v;
int i=0, z=0;
for ( double x=-2*pi; x<3*pi; x+=0.01 ) // Zaehlen der Werte
z++;
FunctionPlot* plotWindow = new FunctionPlot( z );
plotWindow->resize( 500, 500 );
for ( v.x=-2*pi; v.x<=3*pi; v.x+=0.01 ) {
v.y = sin(v.x);
plotWindow->setValue( i, v );
i++;
}
plotWindow->plotIt();
myapp.setMainWidget( plotWindow );
plotWindow->show();
return myapp.exec();
}
Quelle: Das Qt-Buch, SuSE Press von Helmut Herold kapitel 18.
das duerfte das sein was dich interessiert.
gruss michi
Lesezeichen