Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QLabel image with round corners.



  • How do I make QLabel image with round corners like in the image bellow, "circle avatar". StyleSheet does not work. Any help? Thanks.

    avatar.png



  • @Christian-Ehrlicher I translated another PyQt script, the first one did not even run in python this one Qlabel with image in round shape does the job in python. With some tweaks it worked in c++ for me. The only issue I'm facing is the picture only shows one part, it's zooming. I have set KeepAspectRatio or KeepAspectRatioByExpanding, but still. Bellow is the code and the result.

       QPixmap target = QPixmap(size());
        target.fill(Qt::transparent);
    
        QPixmap p;
        p.load(":/new/fotosx/mypc");
        p.scaled(200, 200, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
    
    
        QPainter painter (&target);
    
        painter.setRenderHint(QPainter::Antialiasing, true);
        painter.setRenderHint(QPainter::HighQualityAntialiasing, true);
        painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
    
        QPainterPath path = QPainterPath();
        path.addRoundedRect(200, 200, 200, 200, 100, 100);
        painter.setClipPath(path);
        painter.drawPixmap(200, 200, p);
        ui->label->setPixmap(target);
    

    result

    RoundLabel.PNG


  • Lifetime Qt Champion

    Hi,

    Here you have an example with PyQt5 but you can easily translate it in C++.

    Hope it helps



  • @SGaist thanks. I have tried to translate to C++, but it gives these errors:

    QPainter::begin: Paint device returned engine == 0, type: 3
    QPainter::setBrush: Painter not active
    QPainter::setPen: Painter not active
    QPainter::setRenderHint: Painter must be active to set rendering hints
    QPainter::end: Painter not active, aborted
    QPixmap::scaled: Pixmap is a null pixmap
    

    Please have a look at the code. It seems that the ByteArray is not reaching the function or is because of some mistakes I made. This is what I have tried:

    mainwindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    
    
    QT_BEGIN_NAMESPACE
    namespace Ui { class MainWindow; }
    QT_END_NAMESPACE
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    
    private:
        void mask_image(QByteArray inByteArray);
        Ui::MainWindow *ui;
    };
    #endif // MAINWINDOW_H
    
    

    mainwindow.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QImage>
    #include <QByteArray>
    #include <QBuffer>
    #include <QtGlobal>
    #include <QRect>
    #include <QPainter>
    #include <QWindow>
    #include <QLabel>
    #include <QPixmap>
    #include <QDebug>
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        QPixmap inPixmap;
        inPixmap.load(":/new/testPics/pictwo");
        QByteArray inByteArray;
    
        QBuffer inBuffer( &inByteArray );
        inBuffer.open( QIODevice::WriteOnly );
        inPixmap.save( &inBuffer, "JPG" );
    
        QPixmap outPixmap = QPixmap();
        outPixmap.loadFromData( inByteArray );
    
        //Testing without round, it won't show if sent to mask_image()
        ui->label->setPixmap(outPixmap.scaled(100,100,Qt::KeepAspectRatio));
    
        qDebug() << "pic" << inByteArray.toHex(); //it doesn't print??
    
        mask_image(inByteArray);
    
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::mask_image(QByteArray inByteArray){
    
         qDebug() << "Reach to function???" << inByteArray.toHex();
    
        QImage imgdatas;
        imgdatas.fromData(inByteArray); // imgdatas.fromData(inByteArray, "JPG");??
        imgdatas.convertToFormat(QImage::Format_RGB32);
    
        int imgsize = qMin(imgdatas.width(), imgdatas.height());
    
        QRect selection;
        selection.setRect((imgdatas.width() - imgsize) / 2, (imgdatas.height() - imgsize) / 2, imgsize, imgsize);
    
    
        imgdatas.copy(selection);
        QImage newTransparent;
        newTransparent = QImage(imgsize, imgsize, QImage::Format_RGB32);
        newTransparent.fill(Qt::transparent);
    
        QBrush brush = (imgdatas);
        QPainter painter(&newTransparent);
        painter.setBrush(brush);
        painter.setPen(Qt::NoPen);
        painter.setRenderHint(QPainter::Antialiasing, true);
        painter.drawEllipse(0, 0, imgsize, imgsize);
        painter.end();
        int size = 100;
        qreal pr = QWindow().devicePixelRatio();
        QPixmap pm = QPixmap::fromImage(newTransparent);
        pm.setDevicePixelRatio(pr);
        size *= pr;
        ui->label->setPixmap(pm.scaled(size, size,Qt::KeepAspectRatio, Qt::SmoothTransformation));
    
    }
    

    mainwindow.ui

    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
     <class>MainWindow</class>
     <widget class="QMainWindow" name="MainWindow">
      <property name="geometry">
       <rect>
        <x>0</x>
        <y>0</y>
        <width>800</width>
        <height>600</height>
       </rect>
      </property>
      <property name="windowTitle">
       <string>MainWindow</string>
      </property>
      <widget class="QWidget" name="centralwidget">
       <widget class="QWidget" name="verticalLayoutWidget">
        <property name="geometry">
         <rect>
          <x>250</x>
          <y>50</y>
          <width>181</width>
          <height>221</height>
         </rect>
        </property>
        <layout class="QVBoxLayout" name="verticalLayout">
         <item>
          <widget class="QLabel" name="label">
           <property name="text">
            <string/>
           </property>
          </widget>
         </item>
         <item>
          <widget class="QLabel" name="label_2">
           <property name="text">
            <string>the pic</string>
           </property>
          </widget>
         </item>
         <item>
          <widget class="QLabel" name="label_3">
           <property name="text">
            <string>TextLabel</string>
           </property>
          </widget>
         </item>
        </layout>
       </widget>
      </widget>
      <widget class="QMenuBar" name="menubar">
       <property name="geometry">
        <rect>
         <x>0</x>
         <y>0</y>
         <width>800</width>
         <height>21</height>
        </rect>
       </property>
      </widget>
      <widget class="QStatusBar" name="statusbar"/>
     </widget>
     <resources/>
     <connections/>
    </ui>
    
    

    main.cpp

    #include "mainwindow.h"
    
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
        return a.exec();
    }
    
    

  • Qt Champions 2019

    @Ucn_ You're not calling painter.begin() as far as I can see.



  • @jsulm Even with painter.begin() still gives the same error


  • Qt Champions 2019

    @Ucn_ make sure imgdatas is valid / check the size you're creating your new QImage from. I would guess it's 0/0



  • @Christian-Ehrlicher I translated another PyQt script, the first one did not even run in python this one Qlabel with image in round shape does the job in python. With some tweaks it worked in c++ for me. The only issue I'm facing is the picture only shows one part, it's zooming. I have set KeepAspectRatio or KeepAspectRatioByExpanding, but still. Bellow is the code and the result.

       QPixmap target = QPixmap(size());
        target.fill(Qt::transparent);
    
        QPixmap p;
        p.load(":/new/fotosx/mypc");
        p.scaled(200, 200, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
    
    
        QPainter painter (&target);
    
        painter.setRenderHint(QPainter::Antialiasing, true);
        painter.setRenderHint(QPainter::HighQualityAntialiasing, true);
        painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
    
        QPainterPath path = QPainterPath();
        path.addRoundedRect(200, 200, 200, 200, 100, 100);
        painter.setClipPath(path);
        painter.drawPixmap(200, 200, p);
        ui->label->setPixmap(target);
    

    result

    RoundLabel.PNG



  • I solve by applying painter.drawPixmap(200, 200, p.scaled(400, 400, Qt::KeepAspectRatio, Qt::SmoothTransformation));


Log in to reply