Solved 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 iconQCommonStyle style; _ui->Forward->setIconSize({ _ui->btnXForward->width(),_ui->btnXForward->height() }); _ui->Forward->setIcon(style.standardIcon(QStyle::SP_ArrowForward));
-
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
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 -
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 insideCircularButton::rect
but outside the pained circle would still trigger the click so you need to combine this with thesetMask
implementationEdit: code fixed
-
@J-Hilk @VRonin @sankarapandiyan : Thanks everyone for the clarification :)