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 QImage im; // image, not 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++) w = QMAX(zoom->fontMetrics().width( zoomfactors[n] ), w); zoom->setGeometry( 2, 2, w+30, 20 ); x = w+34; w = 0; for( n=0; n<9; n++) w = QMAX(refresh->fontMetrics().width( refreshrates[n] ), 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 ( 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 ); im = pm.convertToImage(); 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(); }