Anzeige:
Ergebnis 1 bis 15 von 15

Thema: Zeichenmöglichkeit in QT

  1. #1
    Registrierter Benutzer
    Registriert seit
    29.11.2002
    Beiträge
    8

    Zeichenmöglichkeit in QT

    Hi Leute !
    Bin noch nicht sehr bewandert mit QT und dergleichen, aber der Designer und QT allgemein gefallen mir sehr gut...

    Ich wollte deshalb mal fragen, wie man am einfachsten ein Control erstellt, wo man reinzeichnen kann. Im Speziellen möchte ich einzelne pixel malen können (es soll mal ne sinuskurve anzeigen).

    Wie geht das am einfachsten ? Danke schonmal im voraus...

  2. #2
    Registrierter Benutzer Avatar von tuxipuxi
    Registriert seit
    30.08.2002
    Beiträge
    667
    hi,

    ich hab dein problem nicht ganz verstanden.
    meinst du, dass der benutzer des programms reinzeichnen koennen soll?
    dann solltest du dir mal die klasse QPainter angucken.


    ciao michi

  3. #3
    Registrierter Benutzer
    Registriert seit
    29.11.2002
    Beiträge
    8
    ne, sorry wenn ich mich missverständlich ausgedrückt habe....


    ich suche einfach ne fläche, in die man Programmseitig ne Sinuskurve reinzeichnen kann....

    Wie in Delphi zum Beispiel n Imagecontrol, da kann man mit SetPixel reinzeichnen....

    hoffe jetzt ist es klar....

  4. #4
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    lane hat schon recht.
    Du kannst mit einem QPainter auf jede Art von QPaintDevice zeichnen, d.h. zB auf jedes Widget.

    Oder in ein QPixmap.

    Ein QImage leraubt die direkt Manipulation der Pixeldaten, aber für das Zeichnen von Kurven, etc ist sicher QPainter eher geeignet.

    Für Lurven hat dir vielleicht sogra jemand die Arbeit abgenommen.
    Sie dir zB QWT an http://qwt.sourceforge.net/

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  5. #5
    Registrierter Benutzer
    Registriert seit
    29.11.2002
    Beiträge
    8
    hmm mir reicht schon ein widget in das ich einzelne pixel reinsetzten kann...so komplex werden die kurven ja nich...einfache sinuskurven...

    kann ich zum beispiel ein mit dem designer ein QPixmap widget auf meinen dialog machen und dann mit nem QPainter drauf pixel setzen ?

  6. #6
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Ein QPixmap ist kein Widget.

    Du kannst mit QPainter auf QPaintDevice zeichnen.
    QPixmap ist ein QPaintDevice, QWidget ist ein QPaintDevice.

    Du kannst mit einem QPainter also direkt in das Hauptfenster zeichnen, in einen Dialog, oder einfach in einen leeren Frame.

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  7. #7
    Registrierter Benutzer
    Registriert seit
    29.11.2002
    Beiträge
    8
    hmm kompliziert...

    also ich hab jetzt im designer nen QFrame auf meine hauptform gemacht.....das programm lässt sich auch einwandfrei compilieren, wie zeichne ich jetzt genau da einen pixel in diesen QFrame rein ???


  8. #8
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Das einfachste wird folgendes sein.

    Nimm als Element im Desiger ein Pixmap Label.

    Dann im Programm, wenn du neue Daten hast macht du dann

    Code:
    QPixmap* pixmap = label->pixmap();
    QPainter p;
    p.begin(pixmap);
    ///zeichnen
    p.end();
    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  9. #9
    Registrierter Benutzer Avatar von tuxipuxi
    Registriert seit
    30.08.2002
    Beiträge
    667
    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

  10. #10
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Boah, dass nenn ich Einsatz

    Btw, ich glaube
    Code:
    #include <qapplication.h>
    in functionplot.h ist nicht nötig.

    und die Includes der C++ Standardheader sollten so lauten

    Code:
    #include <cstdio>
    Code:
    #include <cmath>
    jeweils mit using namespace std; oder entsprechenden std:: vor den Funktionen.

    Ab GCC3.2 gibt es sonst Schwierigkeiten.

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  11. #11
    Registrierter Benutzer
    Registriert seit
    29.11.2002
    Beiträge
    8
    cool danke...

    das nenn ich Hilfsbereitschaft.....

    Gleich mal ausprobiern

  12. #12
    Registrierter Benutzer
    Registriert seit
    29.11.2002
    Beiträge
    8
    hmm....

    jetzt hab ich nochn problem, der compiler meint....

    Code:
    /usr/lib/qt-3.0.4/bin/uic mainform.ui -i mainform.h -o .ui/mainform.cpp
    g++ -c -pipe -Wall -W -O2  -DQT_NO_DEBUG -I/usr/lib/qt-3.0.4/include -I.ui/ -I/Development/sinus -I.moc/ -I/usr/lib/qt-3.0.4/mkspecs/default -o .obj/mainform.o .ui/mainform.cpp
    In file included from .ui/mainform.cpp:21:
    /Development/sinus/mainform.ui.h: In function `void init()':
    /Development/sinus/mainform.ui.h:15: `label' undeclared (first use this function)
    /Development/sinus/mainform.ui.h:15: (Each undeclared identifier is reported only once
    /Development/sinus/mainform.ui.h:15: for each function it appears in.)
    make: *** [.obj/mainform.o] Error 1
    ich habe aber das Label richtig umbenannt.... von PixmapLabel1 in label...und in die datei auch die notwendige #include "mainform.h" , wo "label" definiert ist eingetragen....funzt trotzdem net....
    weiss jemand warum ? ;-)

  13. #13
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Hmm, in mainform.cpp sollte label schon bekannt sein.

    Hab aber noch nie so ein ui.h File gehabt, vielleicht muß man da was beachten.

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  14. #14
    Registrierter Benutzer
    Registriert seit
    29.11.2002
    Beiträge
    8
    hmm

    kann doch net so schwer sein *hmpf*

    dieses ui.h file generiert "uic" nach einem make...

    eigentlich muss ja die deklaration von dem label mit übernommen werden, weil die richtige datei #include'd wurde...

    wenns nich zuviel arbeit macht könnte mal bitte jemand n simples programm zammstöpseln und mir an kixxass@gmx.net schicken, oder so ?

    ich werd nochmal bissl rumprobieren, glaub aber nich dass ich das noch hinkriege

  15. #15
    Registrierter Benutzer Avatar von tuxipuxi
    Registriert seit
    30.08.2002
    Beiträge
    667
    Original geschrieben von FireWare
    hmm

    kann doch net so schwer sein *hmpf*

    dieses ui.h file generiert "uic" nach einem make...

    eigentlich muss ja die deklaration von dem label mit übernommen werden, weil die richtige datei #include'd wurde...

    wenns nich zuviel arbeit macht könnte mal bitte jemand n simples programm zammstöpseln und mir an kixxass@gmx.net schicken, oder so ?

    ich werd nochmal bissl rumprobieren, glaub aber nich dass ich das noch hinkriege
    was fuern programm?
    versteh deine frage net

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •