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 QWidgetand add that to the scene using QGraphicsScene::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 with QStyleSheet. How about the rounded corners?
    Is there a better approach in general?


  • Qt Champions 2016

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

    alternate text



  • @mrjj Thank you for your suggestion!
    Two problems with that:

    1. While I see the rounder corners of the border the red background still is rectangular.
    2. Now the items that are part of the layout have a black border around them too


    The screenshot shows a QFormLayout with a QLabel using the text "Hello World"


  • Qt Champions 2016

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



  • @mrjj
    Yes, that is a QFrame.
    QGraphicsScene::addWidget() takes Qt::WindowFlags as a parameter but as far as I can tell it's not related to this issue.

    Any ideas?


  • Qt Champions 2016

    @Joel-Bodenmann
    hmm not really then.
    I was thinking of
    setAttribute(Qt::WA_NoSystemBackground);.



  • @mrjj
    Well if I do that then I see the two labels but the actual rectangular box with the rounder border of the QFrame is gone.


  • Qt Champions 2016

    @Joel-Bodenmann

    is the QFormLayout inside anything ?



  • @mrjj
    Yes. I create the layout (and the label that goes into the layout) in the constructor of my SchematicPopup class which inherits from QFrame. I use setLayout() in the constructor to apply the layout to the QFrame.


  • Qt Champions 2016

    @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 a QGraphicsEffect to make rounder corners.


  • Qt Champions 2016

    @Joel-Bodenmann
    I haven't used the effects framework myself, but as far as I understand how they work you could try the following:

    1. Set your widget attributes to include Qt::WA_TranslucentBackground
    2. Subclass QGraphicsEffect and implement the pure virtual QGraphicsEffect::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 case QPainter::drawRoundedRect should suffice).
      • the geometry of the widget itself you should be able to get from QGraphicsEffect::boundingRect
    3. 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.



  • 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 :)


  • Qt Champions 2016

    @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));
        }
    };
    

Log in to reply
 

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