PDA

View Full Version : QLabel and its content (pixmap) position problem.



miqqo
21st September 2010, 10:05
Hi Im using QLabel to display an image like bellow:


mLabel = new QLabel();
mLabel->setBackgroundRole(QPalette::Base);
mLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
mLabel->setPixmap(QPixmap::fromImage(mImage));


I would like to know the correct position of the pixmap's first top-left pixel that is draw, relevant to QLabel. How I can get this info ? I'm writing an image color picker based on mouse position and I need to know the top and left offset of the QLabel's pixmap. I've tried several methods :
mLabel->frameGeometry().x();
mLabel->frameGeometry().y();
mLabel->margin();
mLabel->indent();
mLabel->contentsMargins().top();
mLabel->contentsMargins().left();
mLabel->contentsRect();
mLabel->getContentsMargins(&left, &top, &right, &bottom);
but none of them give me the correct result :(

JohannesMunk
21st September 2010, 10:57
Hi there!

Have a look at qlabel.cpp and voidQLabel::paintEvent(QPaintEvent*)



QRect cr = contentsRect();
cr.adjust(d->margin, d->margin, -d->margin, -d->margin);
..
if (d->pixmap && !d->pixmap->isNull()) {
QPixmap pix;
if (d->scaledcontents) {
if (!d->scaledpixmap || d->scaledpixmap->size() != cr.size()) {
if (!d->cachedimage)
d->cachedimage = new QImage(d->pixmap->toImage());
delete d->scaledpixmap;
d->scaledpixmap = new QPixmap(QPixmap::fromImage(d->cachedimage->scaled(cr.size(),Qt::IgnoreAspectRatio,Qt::SmoothT ransformation)));
}
pix = *d->scaledpixmap;
} else
pix = *d->pixmap;
QStyleOption opt;
opt.initFrom(this);
if (!isEnabled())
pix = style->generatedIconPixmap(QIcon::Disabled, pix, &opt);
style->drawItemPixmap(&painter, cr, align, pix);
}

You will have to take care of those options: scaledcontents and alignment.

If one could get the value somehow different - the Qt code would probably use it..

The style draws the pixmap like this:


void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
const QPixmap &pixmap) const
{
QRect aligned = alignedRect(QApplication::layoutDirection(), QFlag(alignment), pixmap.size(), rect);
QRect inter = aligned.intersected(rect);

painter->drawPixmap(inter.x(), inter.y(), pixmap, inter.x() - aligned.x(), inter.y() - aligned.y(), inter.width(), inter.height());
}


Edit: Be careful, the used drawPixmap function, doesn't necessarily draw the topleft of the pixmap to x,y.

From the docs:

void QPainter::drawPixmap ( int x, int y, const QPixmap & pixmap, int sx, int sy, int sw, int sh )
This is an overloaded function.

Draws a pixmap at (x, y) by copying a part of the given pixmap into the paint device.

(x, y) specifies the top-left point in the paint device that is to be drawn onto. (sx, sy) specifies the top-left point in pixmap that is to be drawn. The default is (0, 0).

(sw, sh) specifies the size of the pixmap that is to be drawn. The default, (0, 0) (and negative) means all the way to the bottom-right of the pixmap.

Johannes