Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Creating circular QPushbutton
Forum Updated to NodeBB v4.3 + New Features

Creating circular QPushbutton

Scheduled Pinned Locked Moved Solved General and Desktop
11 Posts 4 Posters 11.0k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • KiraK Offline
    KiraK Offline
    Kira
    wrote on last edited by
    #1

    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

    sankarapandiyanS 1 Reply Last reply
    0
    • KiraK Kira

      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

      sankarapandiyanS Offline
      sankarapandiyanS Offline
      sankarapandiyan
      wrote on last edited by
      #2

      @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
      );
      }
      
      KiraK 1 Reply Last reply
      1
      • sankarapandiyanS sankarapandiyan

        @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
        );
        }
        
        KiraK Offline
        KiraK Offline
        Kira
        wrote on last edited by
        #3

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

        sankarapandiyanS 1 Reply Last reply
        0
        • VRoninV Offline
          VRoninV Offline
          VRonin
          wrote on last edited by
          #4

          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));
              }
          };
          

          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
          ~Napoleon Bonaparte

          On a crusade to banish setIndexWidget() from the holy land of Qt

          KiraK 1 Reply Last reply
          6
          • KiraK Kira

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

            sankarapandiyanS Offline
            sankarapandiyanS Offline
            sankarapandiyan
            wrote on last edited by
            #5

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

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

            KiraK 1 Reply Last reply
            2
            • sankarapandiyanS sankarapandiyan

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

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

              KiraK Offline
              KiraK Offline
              Kira
              wrote on last edited by
              #6

              @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.

              1 Reply Last reply
              0
              • VRoninV VRonin

                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));
                    }
                };
                
                KiraK Offline
                KiraK Offline
                Kira
                wrote on last edited by
                #7

                @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

                VRoninV 1 Reply Last reply
                0
                • KiraK Kira

                  @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

                  VRoninV Offline
                  VRoninV Offline
                  VRonin
                  wrote on last edited by
                  #8

                  @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

                  "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                  ~Napoleon Bonaparte

                  On a crusade to banish setIndexWidget() from the holy land of Qt

                  1 Reply Last reply
                  2
                  • J.HilkJ Offline
                    J.HilkJ Offline
                    J.Hilk
                    Moderators
                    wrote on last edited by J.Hilk
                    #9

                    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


                    Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                    Q: What's that?
                    A: It's blue light.
                    Q: What does it do?
                    A: It turns blue.

                    VRoninV 1 Reply Last reply
                    5
                    • J.HilkJ J.Hilk

                      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

                      VRoninV Offline
                      VRoninV Offline
                      VRonin
                      wrote on last edited by VRonin
                      #10

                      @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

                      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                      ~Napoleon Bonaparte

                      On a crusade to banish setIndexWidget() from the holy land of Qt

                      1 Reply Last reply
                      2
                      • KiraK Offline
                        KiraK Offline
                        Kira
                        wrote on last edited by
                        #11

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

                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved