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

Creating circular QPushbutton



  • Hello All,
    Qt pushbutton is rectangular in shape by default. I am using QCommonstyle to provide an arrow button to pushbutton which is circular in shape. My problem is that when I try to assign an icon to the button it does not turn to exact size of the icon ie. I want my push button to turn to the size of the icon

    QCommonStyle style;
        _ui->Forward->setIconSize({ _ui->btnXForward->width(),_ui->btnXForward->height() });
        _ui->Forward->setIcon(style.standardIcon(QStyle::SP_ArrowForward));
    

    a540dc2d-7333-41ea-80b9-4a86bcd229ba-image.png



  • @Kira

    use this in button style sheet

    QPushButton {
    color: #333;
    border: 2px solid #555;
    border-radius: 20px;
    border-style: outset;
    background: qradialgradient(
    cx: 0.3, cy: -0.4, fx: 0.3, fy: -0.4,
    radius: 1.35, stop: 0 #fff, stop: 1 #888
    );
    padding: 5px;
    }
    
    QPushButton:hover {
    background: qradialgradient(
    cx: 0.3, cy: -0.4, fx: 0.3, fy: -0.4,
    radius: 1.35, stop: 0 #fff, stop: 1 #bbb
    );
    }
    


  • @sankarapandiyan: Due you have sample example for the same, I tried setting the property but it did not work for me



  • You can use setMask. Something like:

    class RoundButton : public QPushButton{
        Q_DISABLE_COPY(RoundButton)
    public:
        using QPushButton::QPushButton;
    protected:
        void resizeEvent(QResizeEvent *event) override{
            QPushButton::resizeEvent(event);
            const QRect buttonRect = rect();
            setMask(QRegion(buttonRect.x(),buttonRect.y(),buttonRect.width(),buttonRect.height(),QRegion::Ellipse));
        }
    };
    


  • @Kira sure .. I will share some sample code for you ..

    https://www.dropbox.com/s/ggrpv4zo1icdj14/circle_btn.zip?dl=0



  • @sankarapandiyan @VRonin: Thanks for the revert
    @sankarapandiyan: I tried your code it's working but it works if I have pushbutton of fixed size
    If I try to change the dimensions the shape changes.
    Also, the approach doesn't seems to work if I put it into layout.



  • @VRonin: Thanks a lot for your help.
    But I can see some lines in the button and it is not completely circular
    d7caa65f-ffe5-4152-8dfc-e72e99b25314-image.png
    As we can see four lines at the corner of the button



  • @Kira said in Creating circular QPushbutton:

    As we can see four lines at the corner of the button

    That just the border of the button. you can either disable the border with the stylesheet or change the call to setMask

    setMask(QRegion(buttonRect.x(),buttonRect.y(),buttonRect.width()-x,buttonRect.height()-x,QRegion::Ellipse));

    where x is the size of the border


  • Moderators

    an other approach:

    #ifndef CIRCULARBUTTON_H
    #define CIRCULARBUTTON_H
    
    #include <QPushButton>
    
    class CircularButton : public QPushButton
    {
        Q_OBJECT
    public:
        explicit CircularButton(QWidget *parent = nullptr);
    
    signals:
    
    public slots:
    
    protected:
        virtual void paintEvent(QPaintEvent *) override;
        virtual void resizeEvent(QResizeEvent *)override;
    };
    
    #endif // CIRCULARBUTTON_H
    
    
    #include "circularbutton.h"
    
    #include <QPainter>
    
    CircularButton::CircularButton(QWidget *parent) : QPushButton(parent)
    {
    
    }
    
    void CircularButton::paintEvent(QPaintEvent *)
    {
        //Do not paint base implementation -> no styles are applied
    
        QColor background = isDown() ? QColor("grey") : QColor("lightgrey");
        int diameter = qMin(height(), width());
    
        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing, false);
        painter.translate(width() / 2, height() / 2);
    
        painter.setPen(QPen(QColor("black"), 2));
        painter.setBrush(QBrush(background));
        painter.drawEllipse(QRect(-diameter / 2, -diameter / 2, diameter, diameter));
    
    }
    
    void CircularButton::resizeEvent(QResizeEvent *e)
    {
        QPushButton::resizeEvent(e);
        int diameter = qMin(height(), width())+4 ;
        int xOff =(width() -diameter ) / 2;
        int yOff =(height() - diameter) / 2;
        setMask(QRegion(xOff,yOff, diameter, diameter,QRegion::Ellipse));
    }
    

    Edit:
    added the mask, like @VRonin suggested



  • @J-Hilk said in Creating circular QPushbutton:

    an other approach

    Using this approach clicking a point inside CircularButton::rect but outside the pained circle would still trigger the click so you need to combine this with the setMask implementation

    Edit: code fixed



  • @J-Hilk @VRonin @sankarapandiyan : Thanks everyone for the clarification :)


Log in to reply