Looking for help on removing a background and border from a QWidget in a Toolbar
-
Using Qt 5.15.17, I have a QToolbar with QButtons on it, and want one of the buttons to have a pop-up context menu. My toolbar is docked with another that has an edit control in it, making the toolbar a little wider, so this one button doesn't center correctly:

Forum posts and StackOverflow suggested adding a containing QWidget with a centering layout to put the button in, which works, BUT it changes the background color, the spacing, and adds a border:

The spacing is annoying but I can live with that. The border and darker background make it look like the tool is selected / active even when it's not, since it's the only control on the toolbar that does this, so I want to get rid of the border and darker tinted background, and I can't figure out how to do it without breaking something.
Here's the setup code:
QWidget * pHolder = new QWidget(); pHolder->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum)); QLayout * pLayout = new QGridLayout(pHolder); pShapeTB = new QToolButton(); QMenu * pShapeActionMenu = new QMenu(this); pShapeActionMenu->addAction(ui->actionRectangle); pShapeActionMenu->addAction(ui->actionEllipse); pShapeTB->setMenu( pShapeActionMenu ); pShapeTB->setDefaultAction(ui->actionRectangle); pShapeTB->setPopupMode(QToolButton::MenuButtonPopup); pLayout->addWidget( pShapeTB ); pHolder->adjustSize(); ui->tbTools->insertWidget(ui->actionEditNodes, pHolder);If I add this one line after creating the pHolder QWidget control, it removes the border and background, but also breaks the pop-up menu arrow positioning:
pHolder->setStyleSheet("QWidget {border: 0;}");
I've been at this for 4 or 5 hours at this point, trying all kinds of different things with API calls, layout padding, margins, WA attributes on the controls, and more. I'm about to start digging through QStyleSheet stuff on borders to see if maybe there's a different value to use there, and failing that, looking at the drawing & layout code for the QToolButton. If anyone has ideas or directions to point me in, I'd be very appreciative.
-
Using Qt 5.15.17, I have a QToolbar with QButtons on it, and want one of the buttons to have a pop-up context menu. My toolbar is docked with another that has an edit control in it, making the toolbar a little wider, so this one button doesn't center correctly:

Forum posts and StackOverflow suggested adding a containing QWidget with a centering layout to put the button in, which works, BUT it changes the background color, the spacing, and adds a border:

The spacing is annoying but I can live with that. The border and darker background make it look like the tool is selected / active even when it's not, since it's the only control on the toolbar that does this, so I want to get rid of the border and darker tinted background, and I can't figure out how to do it without breaking something.
Here's the setup code:
QWidget * pHolder = new QWidget(); pHolder->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum)); QLayout * pLayout = new QGridLayout(pHolder); pShapeTB = new QToolButton(); QMenu * pShapeActionMenu = new QMenu(this); pShapeActionMenu->addAction(ui->actionRectangle); pShapeActionMenu->addAction(ui->actionEllipse); pShapeTB->setMenu( pShapeActionMenu ); pShapeTB->setDefaultAction(ui->actionRectangle); pShapeTB->setPopupMode(QToolButton::MenuButtonPopup); pLayout->addWidget( pShapeTB ); pHolder->adjustSize(); ui->tbTools->insertWidget(ui->actionEditNodes, pHolder);If I add this one line after creating the pHolder QWidget control, it removes the border and background, but also breaks the pop-up menu arrow positioning:
pHolder->setStyleSheet("QWidget {border: 0;}");
I've been at this for 4 or 5 hours at this point, trying all kinds of different things with API calls, layout padding, margins, WA attributes on the controls, and more. I'm about to start digging through QStyleSheet stuff on borders to see if maybe there's a different value to use there, and failing that, looking at the drawing & layout code for the QToolButton. If anyone has ideas or directions to point me in, I'd be very appreciative.
Instead of a plain
QWidgettry aQFramewithQFrame::NoFramestyle option set, which in theory should draw nothing but the inner layout with your button -
Tried that already, and it didn't help, but thank you.
I think my issue is actually with QPushButton itself - If I set no border on the QPushButton, I get the same result as putting it on the owner widget. Adding some padding fixes the overlapping side arrow for the menu indicator, but now I get no color highlight when I hover or have the button checked. I can fix those with additional style settings for the QPushButton, but then any OS specific styling or theme applied will likely be overridden, which isn't ideal, and I still have the weird spacing issue to figure out.
Getting closer, but man this is cumbersome. Are there inspection tools available to pull all style off a given control at runtime or anything? Some of this stuff is so opaque it's very frustrating at times trying to figure out if it's the control, the parent, the container, the style, the OS, or the current phase of the moon.
No hover highlight color (as shown on the one below it), or "activated" color (shown on the arrow at the top), but at least it's better:

-
Tried that already, and it didn't help, but thank you.
I think my issue is actually with QPushButton itself - If I set no border on the QPushButton, I get the same result as putting it on the owner widget. Adding some padding fixes the overlapping side arrow for the menu indicator, but now I get no color highlight when I hover or have the button checked. I can fix those with additional style settings for the QPushButton, but then any OS specific styling or theme applied will likely be overridden, which isn't ideal, and I still have the weird spacing issue to figure out.
Getting closer, but man this is cumbersome. Are there inspection tools available to pull all style off a given control at runtime or anything? Some of this stuff is so opaque it's very frustrating at times trying to figure out if it's the control, the parent, the container, the style, the OS, or the current phase of the moon.
No hover highlight color (as shown on the one below it), or "activated" color (shown on the arrow at the top), but at least it's better:

@LightBurn-Software said in Looking for help on removing a background and border from a QWidget in a Toolbar:
I can fix those with additional style settings for the QPushButton, but then any OS specific styling or theme applied will likely be overridden, which isn't ideal
You can apply a style to just one specific widget instance while ignoring all the rest of the same class.
QString specialToolButtonStyle("QToolButton#YourTbObjectName { ... };"); -
@LightBurn-Software said in Looking for help on removing a background and border from a QWidget in a Toolbar:
I can fix those with additional style settings for the QPushButton, but then any OS specific styling or theme applied will likely be overridden, which isn't ideal
You can apply a style to just one specific widget instance while ignoring all the rest of the same class.
QString specialToolButtonStyle("QToolButton#YourTbObjectName { ... };");@Pl45m4 - I'm applying the style to just the button object now, not the container widget, or the whole toolbar. The issue I have now is that it's not picking up the hover-over color change, or button pressed color.
It looks like since I changed JUST the border I am now responsible for the entire rest of the style as well, which is disappointing. That's what I meant by "the rest of the styling is overridden" - I only want to remove the border and background color change from the existing style, I don't want to alter anything else, but there is no mechanism I can see to do that.
-
Is there a different way to get this button to center correctly, like the others, without requiring a container object & layout? If I don't put it into a container object, it looks and behaves exactly as I want it to, but the button is left-aligned within the vertical toolbar. If I add the container & layout, it centers, but that adds the border and darker background.
I don't understand why just putting it inside a dummy QWidget changes the way the button renders.
The worst part of all of this is I had previously written my own code to do this with some clever click-handling using a normal tool button. I took the image of whatever was there and drew a "lower quarter" triangle over it, like this:

And if you clicked in the triangle, it presented the pop up, and changed the button face and action to whatever option you chose from the menu. Then I found Qt's version, which supports the delayed pop-up variant, and a slightly nicer side-padded arrow, so I decided to use that instead, thinking it would be better to just use what was built in.
I regret this decision. :-)
-
So the magic incantation that gets me closest is this:
setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed));By setting the sizePolicy on the tool button object, I don't have to put it into a container with a layout.
The button will expand to fill the width of my vertical toolbar, which none of the action-based buttons do, so it still looks off, but it's much better than it was - no weird border or background change.
-
.... but the centering is still broken in the original way on MacOS. Sigh.
Qt provides huge value for us, but this has cost me multiple days, and a lot of hair, with no end in sight.
Does anyone have any ideas on how to make this button move to the middle of the toolbar, like all the others? It is a QToolButton object that I'm inheriting from and overriding a few functions on to get the pop-up behavior I want.

Whereas the exact same code running on Windows looks like this:

-
Another clue... On MacOS, with high-DPI displays, the tool buttons get a silly amount of vertical padding, so I have a function that iterates over the buttons and fixes the sizes. This appears to be causing the strange alignment. More digging...
-
So, on high-DPI displays, the toolbars get padded a TON, and this doesn't happen on normal res displays, so I had code that iterates over all the buttons and sets them to a fixed size. This apparently breaks the centering on buttons that didn't come from actions. I'm not sure exactly what the difference is, but I've changed my code to do this:
static void FixHighDPIButtonSpacing( QToolBar * pBar, int baseSize ) { int horizPad = 2; int vertPad = (pBar->orientation() == Qt::Vertical) ? 0 : 5; const QObjectList & list = pBar->children(); for( QObject * obj : list ) { QToolButton * btn = dynamic_cast<QToolButton *>(obj); if( btn != nullptr ) { if( btn->metaObject() != &MultiActionButton::staticMetaObject ) { btn->setFixedSize( baseSize + horizPad, baseSize + vertPad ); } } } }... and now it works. It has extra padding above & below compared to the buttons around it, but that's a fight for another day.
