Custom sub-controls for custom widgets in style sheets



  • I've created a custom Qt widget, and I would like to style it using style sheets. Specifically, I would like to use the existing property types to style new types of sub-controls, as in the following example style sheet:
    @MyNewWidget
    {
    background-color: rgb(255, 0, 0);
    color: rgb(0, 0, 0);
    border: none;
    }
    MyNewWidget::my_overlays
    {
    background-color: rgba(255, 255, 255, 64);
    color: rgb(255, 255, 255);
    border: solid 1px blue;
    }@

    The overlays in this example are numbered rectangles placed over the main control using the mouse, and in this style sheet are mostly-transparent black rectangles with solid 1-pixel-wide blue borders, with the number drawn in solid white.

    My question is, how can I implement my widget to obtain this information? (That the background colour of the main widget should be solid red, for example, but the overlay rectangles should be partially-transparent black?)

    Thanks in advance for any help!

    Regards,

    Mike...



  • In the parent of your widgets stylesheet, you can simply add:
    @
    QWidget
    {
    background-color: rgba(255, 255, 255, 64);
    color: rgb(255, 255, 255);
    border: solid 1px blue;
    }
    @
    Note that this will make all widgets the above appearance,
    you can specify this even further when you add:
    @
    QLineEdit
    {
    background-color: rgba(255, 255, 255, 64);
    color: rgb(255, 255, 255);
    border: solid 1px blue;
    }
    @
    This can also be done for your custom widget.

    So for short:
    If you want to set a style for every children on a parent, you have to adjust the stylesheet of the parent.



  • Apologies for not being clear: I want to apply a style to subcontrols within a single Qt widget. That is, the custom MyNewWidget doesn't have any children, just components.

    As an example, imagine I created a QSwissCheese widget, which allows the user to draw the holes on the cheese background. I might wish to style it like this:

    @QSwissCheese
    {
    background-color: rgb(255, 240, 0);
    color: rgb(0, 0, 0);
    }
    QSwissCheese::holes
    {
    background-color: rgb(0, 0, 0);
    color: rgb(255, 255, 255);
    }
    @

    The widget background would be as simple as calling QPainter::fillRect() with my background palette colour. I would then like to draw the holes (as circles) using the holes palette.

    Any thoughts?



  • If i understand you correctly,
    you have holes wich are only 'visible' on the cheese and you want to control its appearance with a stylesheet?

    Look at "this":http://doc.qt.nokia.com/4.7/stylesheet-syntax.html#sub-controls and "this":http://doc.qt.nokia.com/4.7/stylesheet-examples.html

    I dont know if you can get something round using stylesheet, but you can try 'border-radius : 10px' or something like that and see if it fits you. but thats not absolute round.

    If that doesnt helps you, mayby you can paint the holes to.



  • Yes, in this example, I have a single widget which is a SwissCheese widget. I am painting both the background and the holes (using QPainter::drawEllipse() or QPainter::fillPath() or something similar). I want to be able to specify two different palettes, one for the main widget and one for the holes, in a stylesheet, as in the above example.

    Unfortunately, because my widget does not inherit from a widget with subcontrols, using the standard subcontrols (as you suggested "here":http://doc.qt.nokia.com/4.7/stylesheet-syntax.html#sub-controls), it is not sufficient to use an existing subcontrol; instead, I want to define a new subcontrol ("holes"), and get its palette in the paint event.



  • Why not make an object of the 'hole', then it is for sure possible to alter it with the stylesheet.
    With your case, i dont know if its possible or how to do it.

    Edit:
    look at "this":http://doc.qt.nokia.com/4.7/stylesheet-examples.html#customizing-qdockwidget section.
    where i can see its is possible to use stylesheets on signal events to. So mayby that can help you?



  • (I would still like to get an answer as to whether I can have a custom subcontrol in a style sheet. But putting that aside for a second...)

    Just to be clear, is this what you're proposing?

    Create a class called QSwissCheeseHole

    Create a QSwissCheese object with one (or more) QSwissCheeseHole objects

    When the QSwissCheese::paintEvent() is called, ask the QSwissCheeseHole class to render itself given a particular render rectangle

    In the style sheet, put:

    @QSwissCheese
    {
    background-color: rgb(255, 240, 0);
    color: rgb(0, 0, 0);
    }
    QSwissCheese > QSwissCheeseHole
    {
    background-color: rgb(0, 0, 0);
    color: rgb(255, 255, 255);
    }
    @



  • Something like that yes, look at my edit in my last post also please.

    1. @ QSwissCheese
      {
      background-color: rgb(255, 240, 0);
      color: rgb(0, 0, 0);
      }
      QSwissCheeseHole
      {
      background-color: rgb(0, 0, 0);
      color: rgb(255, 255, 255);
      } @
      this would be enough then.

    -And yes, you can have custom subcontrol in your stylesheet.-
    deleted my last sentence after the input from Andre. :)



  • Without doing your own parsing of the style sheets involved, you can not do this. At least not using public Qt API. The stylesheet-based rendering is burried quite deep in the Qt widget rendering stack.



  • I retread quietly now,
    Andre is a better help then me in (not only) this case. :)



  • This sentence from the Qt Style Sheet documentation contains a hint towards the problems associated:
    [quote]Warning: Qt style sheets are currently not supported for custom QStyle subclasses. We plan to address this in some future release.[/quote]

    I have the impression, that even this plan is not on the roadmap. QML is considdered the new way to go in terms of customizable UI's. The sentence itself hints at the fact that it is not possible to query Qt for the results of the evaluation of the style sheet, so you can not use that in your custom rendering. The same holds for custom widgets.

    And vinb: no need to retreat quietly :-) I am no oracle either.



  • Thank you, Andre. (I walked through this code, but I was hoping that I'd missed something simple.)

    One other thing: another (not as good) way to accomplish what I wanted to do is to set properties in the widget to set the values you wish, and then set those properties in a stylesheet. Using the above example, I could create holeBackgroundColor and holeColor QBrush properties for the QSwissCheese widget, and then use the following style sheet:
    @QSwissCheese
    {
    background-color: rgb(255, 240, 0);
    color: rgb(0, 0, 0);
    qproperty-holeBackgroundColor: rgb(0, 0, 0);
    qproperty-holeColor: rgb(255, 255, 255);
    }@

    Unfortunately, by doing so, these properties can then be set in an IDE (like Qt Designer), and the style sheet will override them, leading to potential confusion. I'm also not sure if you can set more complicated style sheet property types, like Box Colors or Box Lengths.



  • @Andre, thanks for those words. :)
    But i know for sure, that your knowledge of Qt is much greater then mine.


Log in to reply
 

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