Solved QToolButton as big as QPushButton
-
The Problem
QToolButton
in aQHBoxLayout
with otherQPushButtons
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(); }
-
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); } };
-
@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.
-
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 reimplementsizeHint()
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. -
@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 thestyle()->sizeFromContents(QStyle::CT_PushButton, &opt
part.
The size policy doesn't really achieve what I want -
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); } };