The example program on this page may be used, distributed and modified without limitation. C0664 510077 qtdoc-1.2-a4-2.ps

QMag

This is a simple magnifier-type program. It shows how one can do some quite low-level operations portably using Qt.

Run it, click in the magnifier window, then click where you want to magnify. Two combo boxes let you select amplification and refresh frequency, and a text label tells you the color of the pixel the cursor is on.


//
// Qt Example Application: qmag
//
// Magnifies parts of the screen.
//

#include <qcombo.h>
#include <qpushbt.h>
#include <qpixmap.h>
#include <qimage.h>
#include <qlabel.h>

#include <qapp.h>
#include <qpainter.h>
#include <qwmatrix.h>

class MagWidget : public QWidget
{
    Q_OBJECT
public:
    MagWidget( QWidget *parent=0, const char *name=0 );

public slots:
    void        setZoom( int );
    void        setRefresh( int );

protected:
    void        paintEvent( QPaintEvent * );
    void        mousePressEvent( QMouseEvent * );
    void        mouseMoveEvent( QMouseEvent * );
    void        focusOutEvent( QFocusEvent * );
    void        timerEvent( QTimerEvent * );
    void        resizeEvent( QResizeEvent * );

private:
    void        grab();

    QComboBox   *zoom;
    QComboBox   *refresh;
    QPushButton *quitButton;
    QPixmap     pm;             // pixmap, magnified
    QLabel      *rgb;
    int         yoffset;        // pixels in addition to the actual picture
    int         z;              // magnification factor
    int         r;              // autorefresh rate (index into refreshrates)
    bool        grabbing;       // true if qmag is currently grabbing
    int         grabx, graby;
};

static const char *zoomfactors[] = {
    "100%", "200%", "300%", "400%", "500%",
    "600%", "700%", "800%", "1600%", 0 };

static const char *refreshrates[] = {
    "No autorefresh", "4 per second", "3 per second", "2 per second",
    "Every second", "Every two seconds", "Every three seconds",
    "Every five seconds", "Every ten seconds", 0 };

static const int timer[] = {
    0, 250, 333, 500, 1000, 2000, 3000, 5000, 10000 };

MagWidget::MagWidget( QWidget *parent, const char *name )
    : QWidget( parent, name)
{
    initMetaObject();

    zoom = new QComboBox( this );
    CHECK_PTR(zoom);
    zoom->insertStrList( zoomfactors, 9 );
    connect( zoom, SIGNAL(activated(int)), SLOT(setZoom(int)) );

    refresh = new QComboBox( this );
    CHECK_PTR(refresh);
    refresh->insertStrList( refreshrates, 9 );
    connect( refresh, SIGNAL(activated(int)), SLOT(setRefresh(int)) );

    int w, x, n;

    w = 0;
    for( n=0; n<9; n++) {
        int w2 = zoom->fontMetrics().width( zoomfactors[n] );
        w = QMAX(w2, w);
    }
    zoom->setGeometry( 2, 2, w+30, 20 );

    x = w+34;
    w = 0;
    for( n=0; n<9; n++) {
        int w2 = refresh->fontMetrics().width( refreshrates[n] );
        w = QMAX(w2, w);
    }
    refresh->setGeometry( x, 2, w+30, 20 );

    quitButton = new QPushButton( this );
    CHECK_PTR(quitButton);
    connect( quitButton, SIGNAL(clicked()), qApp, SLOT(quit()) );
    quitButton->setText( "Quit" );
    quitButton->setGeometry( x+w+30+2, 2,
                             10+quitButton->fontMetrics().width("Quit"), 20 );

    rgb = new QLabel( this );
    CHECK_PTR( rgb );
    rgb->setText( "" );
    rgb->setAlignment( AlignVCenter );
    rgb->resize( width(), rgb->fontMetrics().height() + 4 );

    yoffset = zoom->height()    // top buttons
        + 4                     // space around top buttons
        + rgb->height();        // color-value text height

    z = 1;                      // default zoom (100%)
    r = 0;                      // default refresh (none)
    grabx = graby = -1;
    grabbing = FALSE;

    setMinimumSize( x+w+30+2, yoffset+20 ); // at least 20 pixels high..
    resize( quitButton->geometry().topRight().x() + 2, yoffset+60 );

    setMouseTracking( TRUE );   // and do let me know what pixel I'm at, eh?
}

void MagWidget::setZoom( int index )
{
    if (index == 8)
        z = 16;
    else
        z = index+1;
    grab();
}

void MagWidget::setRefresh( int index )
{
    r = index;
    killTimers();
    if (index && !grabbing)
        startTimer( timer[r] );
}

void MagWidget::grab()
{
    if ( !isVisible() ) 
        return;                 // don't eat resources when iconified

    if ( grabx < 0 || graby < 0 )
        return;                 // don't grab until the user has said to

    int x,y, w,h;

    w = (width()+z-1)/z;
    h = (height()+z-1-yoffset)/z;
    if ( w<1 || h<1 )
        return;                 // don't ask too much from the window system :)

    x = grabx-w/2;              // find a suitable position to grab from
    y = graby-h/2;
    if ( x + w > QApplication::desktop()->width() )
        x = QApplication::desktop()->width()-w;
    else if ( x < 0 )
        x = 0;
    if ( y + h > QApplication::desktop()->height() ) 
        y = QApplication::desktop()->height()-h;
    else if ( y < 0 )
        y = 0;

    pm = QPixmap::grabWindow( QApplication::desktop()->winId(),  x, y, w, h );
    QWMatrix m;                 // after getting it, scale it
    m.scale( (double)z, (double)z );
    pm = pm.xForm( m );

    repaint( FALSE );           // and finally repaint, flicker-free
}

void MagWidget::paintEvent( QPaintEvent * )
{
    if ( !pm.isNull() ) {
        QPainter paint;
        paint.begin( this );
        paint.drawPixmap( 0, zoom->height()+4, pm, 
                          0,0, width(), height()-yoffset );
        paint.end();
    }
}

void MagWidget::mousePressEvent( QMouseEvent *e )
{
    grabbing = !grabbing;
    if ( grabbing ) {           // prepare to grab...
        killTimers();
        grabMouse( crossCursor );
    } else {                    // do grab - release mouse, restart timer
        releaseMouse();
        grabx = mapToGlobal(e->pos()).x();
        graby = mapToGlobal(e->pos()).y();
        grab();
        if ( r )
            startTimer( timer[r] );
    }
}

void MagWidget::mouseMoveEvent( QMouseEvent *e )
{
    if ( grabbing || pm.isNull() ||
         e->pos().y() > height() - zoom->fontMetrics().height() - 4 ||
         e->pos().y() < zoom->height()+4 ) {
        rgb->setText( "" );
    } else {
        int x,y;
        x = e->pos().x() / z;
        y = (e->pos().y() - zoom->height()+4) / z;
        QString label;
        label.sprintf( "x=%d, y=%d", x, y );
        rgb->setText( label );
    }
}

void MagWidget::focusOutEvent( QFocusEvent * )
{
    rgb->setText( "" );
}

void MagWidget::timerEvent( QTimerEvent * )
{
    grab();
}

void MagWidget::resizeEvent( QResizeEvent * )
{
    rgb->setGeometry( 0, height() - rgb->height(), width(), rgb->height() );
    grab();
}

#include "qmag.moc"

int main( int argc, char **argv )
{
    QApplication a( argc, argv );
    MagWidget m;
    a.setMainWidget( &m );
    m.show();
    return a.exec();
}

Generated at 17:29, 1997/04/07 for Qt version 1.2 by the webmaster at Troll Tech