Problems setting QTabBar tab color, and understanding stylesheet-drawControl mapping



  • I'm new to Qt, and am trying to understand how QStyles work together with stylesheets. Specifically, I've been digging into the source to try and figure out why (and then patch, if needed) my attempts at setting a QTabBar tab color are failing.

    My current tab styling looks like this (colored so I can see what is going on):
    !http://static.inky.ws/image/4573/Selection_255.png(base tabs)!

    The meat of that styling is this part (and triangular tabs):
    @
    QTabBar::tab {
    height: 22px;
    margin-left: -8px;
    margin-right: 0px;
    padding-left: 15px;
    padding-right: 10px;
    }
    @

    What I'm trying to do is change the color of the "physical" tab (not the pink background) and preserve the black tab border. However, when I style the tab with this:
    @
    QTabBar::tab {
    background-color: rgba(0, 0, 255, 30%);
    }
    @

    It ends up trashing the whole rectangular tab rect region and looking like this:
    !http://static.inky.ws/image/4575/Selection_257.png(bad tab coloring)!

    Of particular interest is that all trace of the "physical" tab shape is now gone. Both the border and background of it. I initially thought the resulting blue background of the entire tab rect was blotting out the drawn triangle tab shape somehow, but that is why I dropped the alpha on the blue (as above) to check that and it seems to not be the case.

    I wasn't sure how to interpret that, so I started digging into the source to try and figure out what was going on with the actual widget painting. Being new to Qt this was a bit daunting, but I eventually arrived at QCommonStyle::drawControl for CE_TabBarTabShape. This has been a very educational trip, but I've gotten stuck.

    First, there is this block of drawControl code, which I initially thought was be near the root of the problem...
    @
    p->setPen(QPen(tab->palette.foreground(), 0));
    if (selected) {
    p->setBrush(tab->palette.base());
    } else {
    if (widget && widget->parentWidget())
    p->setBrush(widget->parentWidget()->palette().background());
    else
    p->setBrush(tab->palette.background());
    }
    @

    The main thing I don't understand here is how the qss stylesheet info gets mapped down into the palette. For example, where does tab->palette.base() come from in the stylesheet? Or does it not? It is not clear to me.

    Looking at the rest of the CE_TabBarTabShape code I don't get how a simple change of background-color would (seemingly) prevent the painting of the triangular region (I use triangular tabs). As a result, I now wonder if the setPen and setBrush code is actually even running when I'm having issues. The pen color looks like it should be constant so the polygon border should always be visible... I think.

    I started this thinking that I was not using the right stylesheet settings to get the tab color changed, and decided to dig through the source to figure out what the correct way was (since I could not find it in the docs). Now I wonder if this is actually a bug somehow. More likely it's just that I'm not understanding it properly, although there are several examples online of people trying to change the tab color without success.

    If someone could point me in the right direction on figuring out how QSS style properties get mapped down to the palette(s) actually being used by the painters, or no how to figure out the union of all style properties in use by a given widget (I can never seem to tell in the docs and this would be handy for experiementation) that would be excellent!!

    Alternatively, although I don't really need the colored tabs, if there is a clean way I have not discovered to change the tab color I would love to hear that as well!!

    I've not yet set up a debug environment to step through this drawing code, but that is my next step, I think.

    Thanks,
    Russ


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Before going further, did you look at the "QTabBar customization":http://qt-project.org/doc/qt-5.0/qtwidgets/stylesheet-examples.html#customizing-qtabwidget-and-qtabbar example ?

    It might help you get what you want without going in the lower implementation details



  • Thanks, SGaist. I did actually go through that example. That one, along with "this":http://blog.qt.digia.com/blog/2007/06/22/styling-the-tab-widget/ complex one, is actually the main reason that QTabBar ended up being my first foray into styling.

    Looking into it again, it reminds me that I thought the root of my problem was triangular tabs. If you put the stylesheet below as the only stylesheet on a basic form with a QTabBar that has been set for triangular tabs, you'll see that "enabling" any of the border or background properties (delete the x prefix) breaks the triangular tab.

    @
    QTabBar::tab {
    xbackground: #C0C0FF;
    xborder: 2px solid red;
    xborder-bottom-color: red;
    xborder-top-left-radius: 12px;
    xborder-top-right-radius: 12px;
    }
    @

    This connects well with the main thrust of my questions which is (I think) "how do I figure out how stylesheet properties get routed through to actual QCommonStyle::drawControl usable parameters?".

    I would like to be able to fix this type of thing myself. In this case it looks like something funky is happening when a tab border or background property is set when there are triangular tabs.

    The drawControl implementation for CE_TabBarTabShape is not that big, so it seems like it should be easy to find. Essentially, the p QPainter is drawing a QPolygon and it seems like that QPolygon is getting messed up by a border/background style setting. But... the border pen is gone as well, so... ??? Must be something else? Argh. Where are those QTabBar::tab styles ending up and how are they getting painted? Are they blotting out my triangles or breaking them? Hmm.

    I'm trying to set up a debug environment where I can set some breakpoints and see what is going on. Talk about yak shaving... I don't even need this feature! Gotta figure it out, though. :) I'm learning Qt as I go, here.

    Any tips/help that shorten the pain and improve my learning would be awesome!


  • Lifetime Qt Champion

    Sorry for the late reply, widgets using style sheet are painted using QStyleSheetStyle which is a private class.

    You should have a look into it


Log in to reply
 

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