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.
Update:
The only way is to override the paintEvent for QLabel
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?
try to set mask on the label like:
int w = // set the width here
int h = // set the height here
QRect *rct = new QRect(0, 0, w, h);
QRegion *reg = new QRegion(*rct, QRegion::Ellipse);
label->setMask(*reg);
see: http://doc.qt.io/archives/qt-4.8/qwidget.html#setMask
The solution by overriding QLabel paintEvent method.
Code:
void AccountImage::paintEvent(QPaintEvent *event)
{
QPixmap pixmap(":/Icon/my_avatar.png");
QPixmap scaled = pixmap.scaled(width(), height(), Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
QBrush brush(scaled);
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.setBrush(brush);
painter.drawRoundedRect(0, 0, width(), height(), 100, 100);
QLabel::paintEvent(event);
}
Result:
Related
I've trying to draw a circle with the center transparent using Qt in paintEvent.
I have this code:
void CircleWidget::paintEvent(QPaintEvent * event)
{
QPainter painter;
QPixmap pix1(width(), height());
QPixmap pix2(width()/2, height()/2);
QBitmap mask1(pix1.size());
QBitmap mask2(pix2.size());
mask1.fill(Qt::color0);
mask2.fill(Qt::color0);
pix1.setMask(mask1);
pix2.setMask(mask2);
if (painter.begin(&pix1))
{
painter.setPen(Qt::NoPen);
painter.setRenderHint(QPainter::Antialiasing);
painter.setBrush(QBrush(QColor(0xff, 0x0, 0x0)));
painter.drawEllipse(0, 0, width(), height());
painter.end();
if (painter.begin(&pix2))
{
painter.setPen(Qt::NoPen);
painter.setRenderHint(QPainter::Antialiasing);
painter.setBrush(QBrush(QColor(0x0, 0xff, 0xff)));
painter.drawEllipse(0, 0, width()/2, height()/2);
painter.end();
if (painter.begin(this))
{
painter.drawPixmap(0, 0, pix1);
painter.setCompositionMode(QPainter::CompositionMode_Clear);
painter.drawPixmap(width()/4, height()/4, pix2);
painter.end();
}
}
}
}
But, the result is this:
Do you have any idea? Thanks a lot.
i.e. if I specify some cubic lines from example specified in Qt5 tutorial:
QPainterPath path;
path.addRect(20, 20, 60, 60);
path.moveTo(0, 0);
path.cubicTo(99, 0, 50, 50, 99, 99);
path.cubicTo(0, 99, 50, 50, 0, 0);
QPainter painter(this);
painter.fillRect(0, 0, 100, 100, Qt::white);
painter.setPen(QPen(QColor(79, 106, 25), 1, Qt::SolidLine,
Qt::FlatCap, Qt::MiterJoin));
painter.setBrush(QColor(122, 163, 39));
painter.drawPath(path);
which constructs this set of curves
Now I'd like to render only a part of those curves on QImage specified by some region with starting point=[20px,50px] with width=80px and height=50px so resulting would look like this:
Or if it is possible, to render with 3x zoom, so resulting QImage would look the same but had size=[240px,150px]
I am new to Qt, so could someone please showed me a working code example?
You can transform the painter coordinate system:
QPainter painter(this);
painter.scale(3, 3); // zoom 3 times
painter.translate(-20, -50); // offset origin to 20x50
// ... render stuff
This has an advantage over the other answer, because it will be rendered as if you provided larger coordinates, instead of rendering it small and then enlarging the raster image, which will degrade image quality. Also, it is possible that Qt will optimize it to not render outside of the image, so it will render less, and you don't need to crop and throw results away.
Result:
Compare that to an upscaled raster:
I've got a code example for you. But it isn't that hard to find out how. You just have to read the documentation, all is easy to find. Qt's documentation is really great.
QApplication a(argc, argv);
QImage img(100, 100, QImage::Format_ARGB32);
QPainterPath path;
path.addRect(20, 20, 60, 60);
path.moveTo(0, 0);
path.cubicTo(99, 0, 50, 50, 99, 99);
path.cubicTo(0, 99, 50, 50, 0, 0);
QPainter painter(&img);
painter.fillRect(0, 0, 100, 100, Qt::white);
painter.setPen(QPen(QColor(79, 106, 25), 1, Qt::SolidLine,
Qt::FlatCap, Qt::MiterJoin));
painter.setBrush(QColor(122, 163, 39));
painter.drawPath(path);
painter.end();
QPixmap pixmap( QPixmap::fromImage(img).copy(20, 50, 80, 50).scaled(240,150) );
// option 1, use a QLabel ( only for simple cases )
QLabel label;
label.setPixmap( pixmap );
label.show();
// option 2, use a QGraphicsScene ( far more flexible )
QGraphicsView view;
QGraphicsScene scene;
scene.addPixmap( pixmap );
scene.setSceneRect( img.rect() );
view.setScene(&scene);
view.show();
return a.exec();
I have a custom class called Window that extends QWidget.
#include "window.h"
// This is the base that all (MDI) sub-windows extend off
Window::Window()
{
// Add fake icon to remove icon in all
setWindowIcon(QIcon("."));
}
void Window::paintEvent(QPaintEvent *)
{
QStyleOption opt;
opt.init(this);
QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}
css:
QWidget:title
{
background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #ca0619);
}
When I do this the buttons (minimize, maximize and close) disappear (as seen in the picture below).
So my question, how do I properly style my Window titlebar?
How can I set the background color for a part of the background like in the following image:
Of course, without border frames, I want to set only the cyan color.
I need to set the length of the left part (cyan) as the percentage of the widget length, e.g 30%.
With css I would hack qlineargradient a little bit. Note that edge of cyan may be a little blurry.
QFrame
{
background-color: qlineargradient(x1:0, x2: 1, stop: 0 cyan, stop: 0.29 cyan, stop: 0.2901 white, stop: 1 white);
}
If you want it hard-coded in the application, you can overload the paintEvent function in a widget. Something like this:
void MyWidget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
QPen pen(Qt::NoPen);
painter.setPen(pen);
painter.fillRect(0, 0, width(), height(), Qt::white);
painter.fillRect(0, 0, 0.3*width(), height(), Qt::cyan);
...
}
In my customized QWidget paintEvent method, I want to draw a circle with a circle shaped image icon. The source image is loaded from file and then automatically casted into circle using QPainter composition. How to do it? Thank you!
void DotGraphView::paintNodes(QPainter & painter)
{
painter.setPen(Qt::blue);
painter.drawEllipse(x, y, 36, 36);
QPixmap icon("./image.png");
QImage fixedImage(64, 64, QImage::Format_ARGB32_Premultiplied);
QPainter imgPainter(&fixedImage);
imgPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
imgPainter.drawPixmap(0, 0, 64, 64, icon);
imgPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
imgPainter.setBrush(Qt::transparent);
imgPainter.drawEllipse(32, 32, 30, 30);
imgPainter.end();
painter.drawPixmap(x, y, 64, 64, QPixmap::fromImage(fixedImage));
}
The above code does not work. The output display is not a circle shaped image.
I don't know if I understood correctly, but this might do what you want:
#include <QtGui/QApplication>
#include <QLabel>
#include <QPixmap>
#include <QBitmap>
#include <QPainter>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// Load the source image.
QPixmap original(QString("/path/here.jpg"));
if (original.isNull()) {
qFatal("Failed to load.");
return -1;
}
// Draw the mask.
QBitmap mask(original.size());
QPainter painter(&mask);
mask.fill(Qt::white);
painter.setBrush(Qt::black);
painter.drawEllipse(QPoint(mask.width()/2, mask.height()/2), 100, 100);
// Draw the final image.
original.setMask(mask);
// Show the result on the screen.
QLabel label;
label.setPixmap(original);
label.show();
return a.exec();
}
Cache the result in your QWidget subclass and blit to the screen the required bounding rect in your paint event when requested.
You can do this relatively simply with a clipping path:
QPainter painter(this);
painter.setPen(Qt::blue);
painter.drawEllipse(30, 30, 36, 36);
QPixmap icon("./image.png");
QImage fixedImage(64, 64, QImage::Format_ARGB32_Premultiplied);
fixedImage.fill(0); // Make sure you don't have garbage in there
QPainter imgPainter(&fixedImage);
QPainterPath clip;
clip.addEllipse(32, 32, 30, 30); // this is the shape we want to clip to
imgPainter.setClipPath(clip);
imgPainter.drawPixmap(0, 0, 64, 64, icon);
imgPainter.end();
painter.drawPixmap(0, 0, 64, 64, QPixmap::fromImage(fixedImage));
(I'd cache the pixmaps if you do this often.)