QWidget custom styling
-
I'd like to show the user a little pop-up box that contains information about a widget when he's hovering with the mouse over it for a certain time. The infobox mainly contains information in form of text and small buttons. Therefore, I subclass
QWidget
and add that to the scene usingQGraphicsScene::addWidget()
which works nicely.My problem is the styling of the widget: I'd like to customize the following:
- Background color
- Text color
- Border width and color
- Rounded corners
Colors can be changed using the
QPalette
. Border size withQStyleSheet
. How about the rounded corners?
Is there a better approach in general? -
Hi
What about using a QFrame as base and just use stylesheet ?
QFrame{background-color: red; border: 1px solid black; border-radius: 10px;}Not tried with QGraphicsScene though :)
-
@mrjj Thank you for your suggestion!
Two problems with that:- While I see the rounder corners of the border the red background still is rectangular.
- Now the items that are part of the layout have a black border around them too
The screenshot shows aQFormLayout
with aQLabel
using the text "Hello World" -
@Joel-Bodenmann
Ok. hmm.
And this is using a QFrame ?
Im wondering if QFrame is using the flag to not get bg painted before paintEvent. -
@Joel-Bodenmann
hmm not really then.
I was thinking of
setAttribute(Qt::WA_NoSystemBackground);. -
is the QFormLayout inside anything ?
-
@mrjj
Yes. I create the layout (and the label that goes into the layout) in the constructor of mySchematicPopup
class which inherits fromQFrame
. I usesetLayout()
in the constructor to apply the layout to theQFrame
. -
@Joel-Bodenmann
Try using a custom graphics effect for your widget. -
@kshegunov
Thank you for your suggestion! Can you be a bit more specific? I'm having troubles figuring out a way to implement aQGraphicsEffect
to make rounder corners. -
@Joel-Bodenmann
I haven't used the effects framework myself, but as far as I understand how they work you could try the following:- Set your widget attributes to include
Qt::WA_TranslucentBackground
- Subclass
QGraphicsEffect
and implement the pure virtualQGraphicsEffect::draw(QPainter *)
- in that method draw manually the window's border and background using the provided
QPainter
argument (you should be able to provide even more complex behavior than rounded corners if needed, but for your caseQPainter::drawRoundedRect
should suffice). - the geometry of the widget itself you should be able to get from
QGraphicsEffect::boundingRect
- in that method draw manually the window's border and background using the provided
- Install an instance of your effect on your widget with
QWidget::setGraphicsEffect
Note that the effect is supposed to be inherited through child widgets, so I'm not completely sure it won't interfere with the labels/buttons you add to the widget. In any case you could patch that up by holding a reference to the relevant widget in the effect itself.
I hope that helps.
- Set your widget attributes to include
-
Thank you for the explanation!
As this seems to be a bit more complex than it looked initially I will postpone this and just life with rectangular boxes for now :) -
@Joel-Bodenmann said:
As this seems to be a bit more complex than it looked initially I will postpone this and just life with rectangular boxes for now :)
Sure, if this is an option. However, implementing a class with a single function shouldn't be very complex ;)
class MyRoundedCornerEffects { public: MyRoundedCornerEffects(QObject * parent = NULL) : QObject(parent) { } virtual draw(QPainter * painter) { painter->setPen(QPen(Qt::black, 1)); painter->setBrush(Qt::red); painter->drawRoundedRect(boundingRect(), 10, 10); } }; class MyWidgetWithEffect : public QWidget { public: MyWidgetWithEffect(QWidget * parent) : QWidget(parent) { setAttribute(Qt::WA_TranslucentBackground); setGraphicsEffect(new MyRoundedCornerEffects(this)); } };