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 10.9k 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.
  • K Offline
    K Offline
    Kira
    wrote on 20 Feb 2020, 09:48 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

    S 1 Reply Last reply 20 Feb 2020, 09:52
    0
    • K Kira
      20 Feb 2020, 09:48

      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

      S Offline
      S Offline
      sankarapandiyan
      wrote on 20 Feb 2020, 09:52 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
      );
      }
      
      K 1 Reply Last reply 20 Feb 2020, 11:21
      1
      • S sankarapandiyan
        20 Feb 2020, 09:52

        @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
        );
        }
        
        K Offline
        K Offline
        Kira
        wrote on 20 Feb 2020, 11:21 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

        S 1 Reply Last reply 21 Feb 2020, 04:50
        0
        • V Offline
          V Offline
          VRonin
          wrote on 20 Feb 2020, 12:01 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

          K 1 Reply Last reply 24 Feb 2020, 09:20
          6
          • K Kira
            20 Feb 2020, 11:21

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

            S Offline
            S Offline
            sankarapandiyan
            wrote on 21 Feb 2020, 04:50 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

            K 1 Reply Last reply 24 Feb 2020, 05:53
            2
            • S sankarapandiyan
              21 Feb 2020, 04:50

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

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

              K Offline
              K Offline
              Kira
              wrote on 24 Feb 2020, 05:53 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
              • V VRonin
                20 Feb 2020, 12:01

                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));
                    }
                };
                
                K Offline
                K Offline
                Kira
                wrote on 24 Feb 2020, 09:20 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

                V 1 Reply Last reply 24 Feb 2020, 09:47
                0
                • K Kira
                  24 Feb 2020, 09:20

                  @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

                  V Offline
                  V Offline
                  VRonin
                  wrote on 24 Feb 2020, 09:47 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 24 Feb 2020, 09:49 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.

                    V 1 Reply Last reply 24 Feb 2020, 10:16
                    5
                    • J.HilkJ J.Hilk
                      24 Feb 2020, 09:49

                      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

                      V Offline
                      V Offline
                      VRonin
                      wrote on 24 Feb 2020, 10:16 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
                      • K Offline
                        K Offline
                        Kira
                        wrote on 25 Feb 2020, 04:59 last edited by
                        #11

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

                        1 Reply Last reply
                        0

                        1/11

                        20 Feb 2020, 09:48

                        • Login

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