Solved Draw the frame of a QGroupBox around a QFrame (Fusion style QGroupBox bug workaround)
-
Hi :-)
I've been working on the following problem for quite some time now, and I can't get it to work.
The basic problem is that there is a bug in the Fusion style that, other than with other styles (like Breeze), causes a
QGroupBox
without a title to have an unneeded top border. There's a quite old bug report about this: https://bugreports.qt.io/browse/QTBUG-44056 that has been closed with a patch meanwhile. The problem is that the patch does fix the border spacing, but it introduces a new spacing issue (cf. the screenshot I posted in the bug), so it's actually not fixed.In the Gerrit review, one dev proposed to simply use a
QFrame
instead of a title-lessQGroupBox
. While I think that simply using another widget instead of fixing a bug in Qt's default style is not the right way to go, I tried that.Problem is that there doesn't seem to be an easy way to make a
QFrame
look like aQGroupBox
. And here we are: Is it possible to make aQFrame
draw theQGroupBox
frame around it and have the same backgound color? So that theQFrame
simply looks like aQGroupBox
without a title and without the spcing problem?Surely, I'd rather see Fusion to be fixed, but looking at the code I have no idea how to fix the new spacing issue. I would simply patch my local installation otherwise. And maybe, it will take another couple of years until this gets fixed upstream. If ever. So I think to work around this via a
QFrame
would be okay – if it looks the same, both for e. g. Breeze and Fusion. Or does somebody know how to fix Fusion? That would be the best of course ;-)I would be really glad to be able to work around this. Thanks for all help in advance!
-
Hi,
Can you provide a complete minimal compilable project on the bug report ?
That will allow for easier reproduction of your issue. -
That's quite simple, just add two or more
QGroupBoxes
without a title in aQVBoxLayout
. Here's some minimalistic example:main.cpp:
#include <QApplication> #include "MainWindow.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); MainWindow mainWindow; mainWindow.show(); return app.exec(); }
MainWindow.h:
#include <QMainWindow> class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(); };
MainWindow.cpp:
#include "MainWindow.h" #include <QVBoxLayout> #include <QGroupBox> #include <QLabel> MainWindow::MainWindow() { QWidget *widget = new QWidget; setCentralWidget(widget); QVBoxLayout *layout = new QVBoxLayout(widget); QGroupBox *box1 = new QGroupBox; QVBoxLayout *box1Layout = new QVBoxLayout(box1); box1Layout->addWidget(new QLabel(QStringLiteral("text"))); layout->addWidget(box1); QGroupBox *box2 = new QGroupBox; QVBoxLayout *box2Layout = new QVBoxLayout(box2); box2Layout->addWidget(new QLabel(QStringLiteral("text"))); layout->addWidget(box2); }
Result using Breeze:
Same program started with
-style=Fusion
produces the long-known border issue:
And here's the version compiled against Qt (in my test case 5.7.1) with the 5.14 patch from the bug report applied:
-
@SGaist Oh, you said I should post this at the bug report. I simply added a link to this post here, is this okay?
-
… but to come back to the initial question (for a workaround):
I tried to use
QFrame
instead ofQGroupBox
for the title-less boxes. The problem is thatQGroupBox
does not inheritQFrame
, but draws it's own frame.Using
setFrameShape(QFrame::StyledPanel)
gives a similar (not the same) look for the Fusion theme:
But using e. g. KDE's Breeze theme, no frame is drawn at all:
So this is not the way to go, as I need a solution/workaround that does not only work for the Fusion theme …
-
@l3u_ said in Draw the frame of a QGroupBox around a QFrame:
@SGaist Oh, you said I should post this at the bug report. I simply added a link to this post here, is this okay?
Please add the project to the report. Links can break and having a test case with the bug reports make things way easier.
-
@SGaist I attached the sources. Thanks for the hint!
-
Okay, I found a workaround: I define a CSS border for my
QGroupBox
es which imitates thre Breeze look so that the native style isn't used, along with a property for the ones without a title, and I only use it if the Fusion style is used.main.cpp:
if (application.style()->objectName() == QLatin1String("fusion")) { application.setStyleSheet(QStringLiteral(R"END( QGroupBox { border: 1px solid palette(Mid); border-radius: 2px; padding-top: 1.2em; } QGroupBox[notitle=true] { padding-top: 0; } QGroupBox::title { background-color: transparent; subcontrol-origin: margin; subcontrol-position: top center; padding: 0.4em 0 0; } QScrollArea { background-color: transparent; } )END")); }
If a
QGroupBox
doesn't have a title, I define thenotitle
property:someBox->setProperty("notitle", true);
The result is quite nice, although this is surely more a hack; but the only code to change are the
setProperty
calls that are simply ignored by the styles drawing theQGroupBox
es correctly:Well, it works ;-)