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. QToolButton as big as QPushButton
Forum Updated to NodeBB v4.3 + New Features

QToolButton as big as QPushButton

Scheduled Pinned Locked Moved Solved General and Desktop
5 Posts 3 Posters 3.3k Views 2 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.
  • VRoninV Offline
    VRoninV Offline
    VRonin
    wrote on last edited by VRonin
    #1

    The Problem

    QToolButton in a QHBoxLayout with other QPushButtons is visibly smaller in height. Any suggestion on how to make it as big as its cousin?

    My Config

    Qt 5.8 MSVC2013 Windows 7

    Test Code

    #include <QApplication>
    #include <QWidget>
    #include <QPushButton>
    #include <QToolButton>
    #include <QHBoxLayout>
    
    int main(int argc, char *argv[])
    {
        QApplication app(argc,argv);
        QWidget mainWid;
        QHBoxLayout* mainLay=new QHBoxLayout(&mainWid);
        mainLay->addWidget(new QPushButton("Button 1",&mainWid));
        mainLay->addWidget(new QPushButton("Button 2",&mainWid));
        QToolButton *toolButton = new QToolButton(&mainWid);
        toolButton->setPopupMode(QToolButton::MenuButtonPopup);
        toolButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
        toolButton->setText("Tool Button");
        mainLay->addWidget(toolButton);
        mainLay->addWidget(new QPushButton("Button 3",&mainWid));
        mainWid.show();
        app.exec();
    }
    

    "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

    J.HilkJ 1 Reply Last reply
    0
    • VRoninV Offline
      VRoninV Offline
      VRonin
      wrote on last edited by VRonin
      #5

      This Is what I went for in the end. Good enough for me (still not perfect though. I get a 1px difference still:

      #include <QToolButton>
      #include <QStyle>
      #include <QStyleOptionToolButton>
      #include <QStyleOptionButton>
      class BiggerToolButton : public QToolButton{
          Q_DISABLE_COPY(BiggerToolButton)
      public:
          BiggerToolButton(QWidget* parent = Q_NULLPTR)
              : QToolButton(parent)
          {}
          virtual QSize sizeHint() const Q_DECL_OVERRIDE{
              const QSize baseHint = QToolButton::sizeHint();
              QStyleOptionToolButton btnOpt;
              initStyleOption(&btnOpt);
              int h =qMax(0,btnOpt.iconSize.height());
              int w =btnOpt.iconSize.width()+4;
              const QSize fntSize = fontMetrics().size(Qt::TextShowMnemonic,btnOpt.text);
              w+=fntSize.width();
              h= qMax(h,fntSize.height());
      
              QStyleOptionButton opt;
              opt.direction = btnOpt.direction;
              opt.features = QStyleOptionButton::None;
              if(btnOpt.features & QStyleOptionToolButton::Menu)
                  opt.features |= QStyleOptionButton::HasMenu;
              opt.fontMetrics = btnOpt.fontMetrics;
              opt.icon = btnOpt.icon;
              opt.iconSize = btnOpt.iconSize;
              opt.palette = btnOpt.palette;
              opt.rect = btnOpt.rect;
              opt.state = btnOpt.state;
              opt.styleObject = btnOpt.styleObject;
              opt.text = btnOpt.text;
              const QSize pushSize = style()->sizeFromContents(QStyle::CT_PushButton,&opt,QSize(w,h) ,this);
              return baseHint.expandedTo(pushSize);
          }
      };
      

      "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
      0
      • VRoninV VRonin

        The Problem

        QToolButton in a QHBoxLayout with other QPushButtons is visibly smaller in height. Any suggestion on how to make it as big as its cousin?

        My Config

        Qt 5.8 MSVC2013 Windows 7

        Test Code

        #include <QApplication>
        #include <QWidget>
        #include <QPushButton>
        #include <QToolButton>
        #include <QHBoxLayout>
        
        int main(int argc, char *argv[])
        {
            QApplication app(argc,argv);
            QWidget mainWid;
            QHBoxLayout* mainLay=new QHBoxLayout(&mainWid);
            mainLay->addWidget(new QPushButton("Button 1",&mainWid));
            mainLay->addWidget(new QPushButton("Button 2",&mainWid));
            QToolButton *toolButton = new QToolButton(&mainWid);
            toolButton->setPopupMode(QToolButton::MenuButtonPopup);
            toolButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
            toolButton->setText("Tool Button");
            mainLay->addWidget(toolButton);
            mainLay->addWidget(new QPushButton("Button 3",&mainWid));
            mainWid.show();
            app.exec();
        }
        
        J.HilkJ Offline
        J.HilkJ Offline
        J.Hilk
        Moderators
        wrote on last edited by
        #2

        @VRonin hi, the easiest way would be to set the Vertical sizepolicy to Prefered

        toolButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);

        however that changes will let the cause the toolbutton to expand when, you stretch it in height.

        So setting the height as the same height as the button:

        toolButton->setMinimumHeight(23);
        toolButton->setMaximumHeight(23);
        

        should do the trick as well, 23 is the btn height after it is shown, 30 is after initialisation. That is, funny enough, same value as toolbutton has. But toolbutton gets resized to 19, during the showevent, not sure why.


        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.

        1 Reply Last reply
        0
        • Chris KawaC Offline
          Chris KawaC Offline
          Chris Kawa
          Lifetime Qt Champion
          wrote on last edited by Chris Kawa
          #3

          You shouldn't hardcode these values to fixed numbers. They depend on the platform style, font size, scaling factor etc. The fact that is 23 or 42 on one system doesn't mean it's the right size on every other.
          The "correct" way to make a toolbutton behave like a pushbutton is to subclass it and reimplement sizeHint() by copy-pasting it from the push button code.
          A lazy version of that is to copy the calculated value from existing pushbutton and set it as the fixed height:

          auto pushbutton = new QPushButton("Button 1");
          auto toolbutton = new QToolButton();
          toolbutton->setFixedHeight(pushbutton->sizeHint().height());
          

          Note though that this should be redone if the style or font changes at runtime. The sizeHint() approach is the most coding initially, but the least amount of worries later on.

          VRoninV 1 Reply Last reply
          0
          • Chris KawaC Chris Kawa

            You shouldn't hardcode these values to fixed numbers. They depend on the platform style, font size, scaling factor etc. The fact that is 23 or 42 on one system doesn't mean it's the right size on every other.
            The "correct" way to make a toolbutton behave like a pushbutton is to subclass it and reimplement sizeHint() by copy-pasting it from the push button code.
            A lazy version of that is to copy the calculated value from existing pushbutton and set it as the fixed height:

            auto pushbutton = new QPushButton("Button 1");
            auto toolbutton = new QToolButton();
            toolbutton->setFixedHeight(pushbutton->sizeHint().height());
            

            Note though that this should be redone if the style or font changes at runtime. The sizeHint() approach is the most coding initially, but the least amount of worries later on.

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

            @Chris-Kawa said in QToolButton as big as QPushButton:

            The sizeHint() approach is the most coding initially, but the least amount of worries later on.

            I'm currently exploring this route but instead of implementing the huge QPushButton::sizeHint I'll just skip to the style()->sizeFromContents(QStyle::CT_PushButton, &opt part.
            The size policy doesn't really achieve what I want

            "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
            0
            • VRoninV Offline
              VRoninV Offline
              VRonin
              wrote on last edited by VRonin
              #5

              This Is what I went for in the end. Good enough for me (still not perfect though. I get a 1px difference still:

              #include <QToolButton>
              #include <QStyle>
              #include <QStyleOptionToolButton>
              #include <QStyleOptionButton>
              class BiggerToolButton : public QToolButton{
                  Q_DISABLE_COPY(BiggerToolButton)
              public:
                  BiggerToolButton(QWidget* parent = Q_NULLPTR)
                      : QToolButton(parent)
                  {}
                  virtual QSize sizeHint() const Q_DECL_OVERRIDE{
                      const QSize baseHint = QToolButton::sizeHint();
                      QStyleOptionToolButton btnOpt;
                      initStyleOption(&btnOpt);
                      int h =qMax(0,btnOpt.iconSize.height());
                      int w =btnOpt.iconSize.width()+4;
                      const QSize fntSize = fontMetrics().size(Qt::TextShowMnemonic,btnOpt.text);
                      w+=fntSize.width();
                      h= qMax(h,fntSize.height());
              
                      QStyleOptionButton opt;
                      opt.direction = btnOpt.direction;
                      opt.features = QStyleOptionButton::None;
                      if(btnOpt.features & QStyleOptionToolButton::Menu)
                          opt.features |= QStyleOptionButton::HasMenu;
                      opt.fontMetrics = btnOpt.fontMetrics;
                      opt.icon = btnOpt.icon;
                      opt.iconSize = btnOpt.iconSize;
                      opt.palette = btnOpt.palette;
                      opt.rect = btnOpt.rect;
                      opt.state = btnOpt.state;
                      opt.styleObject = btnOpt.styleObject;
                      opt.text = btnOpt.text;
                      const QSize pushSize = style()->sizeFromContents(QStyle::CT_PushButton,&opt,QSize(w,h) ,this);
                      return baseHint.expandedTo(pushSize);
                  }
              };
              

              "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
              0

              • Login

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