Circle user avatar issue
-
Hi! I want to make
QLabel
with the image circle:Code:
QLabel *label = new QLabel(this); QPixmap avatarPixmap(":/Icon/default_avatar.png"); label->setPixmap(avatarPixmap); label->setStyleSheet("border: 0.5px solid red; border-radius: 50%; background-clip: padding;");
It only rounds the
QLabel
, not the image. How to fix it? Thanks. -
The easiest Way would be to make the Image rounded with Gimp or Photoshop.
But if you want to do that with Code you need to override the paintEvent of the QLabel. With something like this.
void CoverWidget::paintEvent(QPaintEvent *e) { Q_UNUSED(e) QImage image("image.jpg"); QBrush brush(image); QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); painter.setBrush(brush); painter.drawRoundedRect(0, 0, width(), height(), 5, 5); }
-
Yes, the only way is to override the
paintEvent
forQLabel
Code:
void AccountImage::paintEvent(QPaintEvent *event) { QPixmap pixmap(":/Icon/default_avatar.png"); QBrush brush(pixmap); QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); painter.setBrush(brush); painter.drawRoundedRect(0, 0, width(), height(), 100, 100); QLabel::paintEvent(event); }
The image is rounded but not properly scaled. Any ideas?
-
Hi, did you have scaleContent on the QLabel ?
since its now much bigger than before.
you can use pixmap::scaled to scale it before drawing it.
(notice it returns the scaled copy, not modify the original pixmap)Also note, its possible to draw on image with painter before setting it on QLabel
so overriding paintEvent is not the only way. (strictly speaking)QPixmap pixmap(":/Icon/default_avatar.png"); QBrush brush(pixmap); QPainter painter(&pixmap); painter.setRenderHint(QPainter::Antialiasing); painter.setBrush(brush); painter.drawRoundedRect(0, 0, pixmap.width(), pixmap.height(), 100, 100); label->setPixmap(pixmap);
-
I have tried your solution.
QPixmap pixmap(":/Icon/default_avatar.png"); QBrush brush(pixmap); QPainter painter(&pixmap); painter.setRenderHint(QPainter::Antialiasing); painter.setBrush(brush); painter.drawRoundedRect(0, 0, pixmap.width(), pixmap.height(), 100, 100); ui->label->setScaledContents(true); ui->label->setFixedSize(100, 100); ui->label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); ui->label->setPixmap(pixmap);
But it displays:
-
Hi
You control the circle with
painter.drawRoundedRect(0, 0, pixmap.width(), pixmap.height(), 100, 100);
Currently it uses the width/height of the pixmap and will give that result.Maybe the
http://doc.qt.io/qt-5/qpainter.html#drawEllipse
will work better ? -
Hi
What aboutpainter.drawEllipse( QPoint(pixmap.width()/2, pixmap.height()/2), 80, 80);
-
@Cobra91151
Hi
Yeah if you need click on label
https://wiki.qt.io/Clickable_QLabel
Then subclass is better.Just used the scaled function from pixmap to scale it.
QPixmap scaled =pixmap.scaled(width(), height(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
painter->drawPixmap(0,0, scaled); -
I have override the paint event method:
void AccountImage::paintEvent(QPaintEvent *event) { QPixmap pixmap(":/Icon/default_avatar.png"); QPixmap scaled = pixmap.scaled(width(), height(), Qt::KeepAspectRatio, Qt::SmoothTransformation); QBrush brush(scaled); QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); painter.setBrush(brush); painter.drawPixmap(0, 0, scaled); QLabel::paintEvent(event); }
The result is:
-
@Cobra91151
Ok , that looks right ? -
No, it's just the image without circle borders.
I have found another solution. To use
setMask
method:QPixmap pixmap(":/Icon/default_avatar.png"); label->setPixmap(pixmap); label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); label->setFixedSize(100, 100); QRegion *region = new QRegion(0, 0, label->width(), label->height(), QRegion::Ellipse); label->setScaledContents(true); label->setMask(*region);
The result:
It's looks good but the image edges is sharpen. Any ideas how to smooth it?
-
@Cobra91151
Hi
But the code you shown did NOT draw circle so i thought you were aware of that ?
The image looked rightly scaled.As far as i know its not possible to smooth a mask.
-
Hi
Do you need to do this dynamically since using 2 images would be much easier.
But i assume you need multiple avatar images and hence having a "circled" version is
not optimal ? -
@Cobra91151
One that is normal
and one where you have drawn the highlight/circle on.
and when you select/click QLabel you switch to that image. -
Ah so user will bring his own avatar image ?
-
@Cobra91151
Ok, then painting yourself seems better :)
What was wrong with the paintEvent + scaled + drawEllipse ?
since you are now looking into masks -
I draws the image but not rounds it.
void AccountImage::paintEvent(QPaintEvent *event) { QPixmap pixmap(":/Icon/default_avatar.png"); QPixmap scaled = pixmap.scaled(width(), height(), Qt::KeepAspectRatio, Qt::SmoothTransformation); QBrush brush(scaled); QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); painter.setBrush(brush); painter.drawPixmap(0, 0, scaled); QLabel::paintEvent(event); }