QToolButton as big as QPushButton

  • Qt Champions 2018

    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->setText("Tool Button");
        mainLay->addWidget(new QPushButton("Button 3",&mainWid));

  • Moderators

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


    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.

  • Moderators

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

    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.

  • Qt Champions 2018

    @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

  • Qt Champions 2018

    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{
        BiggerToolButton(QWidget* parent = Q_NULLPTR)
            : QToolButton(parent)
        virtual QSize sizeHint() const Q_DECL_OVERRIDE{
            const QSize baseHint = QToolButton::sizeHint();
            QStyleOptionToolButton btnOpt;
            int h =qMax(0,btnOpt.iconSize.height());
            int w =btnOpt.iconSize.width()+4;
            const QSize fntSize = fontMetrics().size(Qt::TextShowMnemonic,btnOpt.text);
            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);

Log in to reply

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.