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();
}