Important: Please read the Qt Code of Conduct -

How to change the hovered color of a default/systemstyle Button

  • Hello everybody,

    i am looking for a possibility how to change only hovered color or background color for a button in QML / QtQuick.Controls(Button) and keep the systembased geometry for this button. So that means without describing my own ButtonStyle component.
    Or another way how can i derive from systembased style and change some colors there.

    If somebody have an idea or a solution, please help me :-)

    Thanks a lot !!!

    P.S. Is it possible to derive from QWindosStyle and set this style as style property for QtQuick button. And use this button as a special button ?

  • Hi,
    I'm almost sure this is all impossible with the current QtQuick.Controls. :-/
    The easiest way in my oppinion would be to copy and paste the button's BorderImages from the Qt sources and create a custom button that uses these border images and thus looks like the original button and then change the color of the images with Gimp or whatever as you like.

  • I might not understand the question fully but it sounds like changing the default background color (i.e. non-hovered) is an acceptable solution. You can just embed a rectangle with the desired color and use the onHoveredChanged property to modify the opacity from 0 to something visible, like this
    : @Button {
    text: "Push me"
    id: myRectId
    anchors.fill: parent
    anchors.margins: 1
    color: "green"
    opacity : .2;
    onHoveredChanged: hovered ? myRectId.opacity = 0 :
    myRectId.opacity = .2;
    ! Hover/Not Hovered)!

    No styles were injured during the making of this post.

  • Hi Rolias!

    The main problem with that solution is that this just puts an overlay on top of the button and thus the button's colors (background and text) and those of the overlay are beeing mixed.

    Another problem ist, that a rectangled overlay does not fit the button's geometry in general (I think by now buttons have some sort of rounded corners on all platforms).

  • I do realize none of this answers the question about inheriting the base ButtonStyle but...

    Did you try the reverse? I just did and it seems to work. You can have the opacity 0 when it's not hovered and .2 when it is. This keeps your button background and text pure. If your buttons are a fixed size, I would think you could find a margin setting that would keep the hover effect inside the rounded corners. I tried buttons from the default size up to 200X50 with a margin of 2 and I can't see any bleed past the corners. I'm assuming from your question that you're using the standard button style so it's not some odd shape. It could be that my green at 20% is too subtle to see bleeding but it looks clean to me.

    The overlay rectangle does mix with the normal highlight gradient but since what you're after is a custom hover color that shouldn't be a problem.That or I didn't understand your question. I realize this is still a workaround but thought it might be worth considering if you don't find a better solution.

    Of course if you do find a way to just change a single part of a base style I'd love to know how to do it. Might be worth making a feature request.

  • I'm not sure if this is true, also i'll look it up a bit further later, but i'll try to give you an explanation:

    Button derives from BasicButton which derives from Control.
    Control is loading the style for all the Components which derive from it:
    property Component style
    property QtObject __style: styleLoader.item
    property alias __styleData: styleLoader.styleData
    Loader {
    id: panelLoader
    anchors.fill: parent
    sourceComponent: __style ? __style.panel : null
    onStatusChanged: if (status === Loader.Error) console.error("Failed to load Style for", root)
    Loader {
    id: styleLoader
    sourceComponent: style
    property Item __control: root
    property QtObject styleData: null
    onStatusChanged: {
    if (status === Loader.Error)
    console.error("Failed to load Style for", root)

    The loaded style is a ButtonStyle which has got a property named background:

    @property Component background: Item { ... }@

    Accessing the property in that way:

    @Button {
    anchors.centerIn: parent
    Component.onCompleted: console.log(__style.background)

    returns a valid QQmlComponent, but it looks like you can't read or modify it's properties, therefore you can only assign a new ButtonStyle to the style property. But as i said, i'll look it up a bit further later.

    Edit 1:
    @style: Qt.createComponent( + "/ButtonStyle.qml", button)@

    Afaik, using and assigning a ButtonStyle should not have any overhead. The Loader is either loading the default ButtonStyle as you can see above, or your custom ButtonStyle. Even if it creates an overhead by loading a ButtonStyle twice(first the default, then the custom), you still can create a custom Button.qml similar to the original one and reassigning the style, but this could get obsolete with newer QML versions.

    Edit 2:
    Guess i forgot to mention i am using Qt 5.4.0 with QtCreator 3.3.0.

    Edit 3:
    To access Settings and the string style which refers to the style directory you need to import QtQuick.Controls.Private 1.0

Log in to reply