QT QML how to change only one feature of a, say, button style

大兔子大兔子 提交于 2021-02-08 04:01:12

问题


changing the style of a component, seems to replace all the features of the default style. is there a way to change only one feature?

For example, suppose i want a red button;

import QtQuick 2.7
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4

ApplicationWindow
{
    visible: true
    width: 640
    height: 480

    Button
    {
        height: 200
        width: 200
        text: "Press me"
        style: ButtonStyle 
        {
            // changes background but also throws away everything else
            // in standard button style
            background: Rectangle { color: "red" }
        }
    }
}

re-defining ButtonStyle with a background works fine for changing the color of the button, but then everything else within the system default ButtonStyle is gone. For example, the border and the click highlight.

How to just change one feature and keep the rest?

Sorry if this has been asked before.

thanks,

Update

The above question was for Controls 1, but the same problem exists for Controls 2. Here's the same example code for Controls 2.

import QtQuick 2.7
import QtQuick.Controls 2.1

ApplicationWindow
{
    visible: true
    width: 640
    height: 480

    Button
    {
        height: 200
        width: 200
        text: "Press me"

        // changes background but also throws away everything else
        // in standard button style
        background: Rectangle { color: "red" }
    }
}

回答1:


Preface
The purpose of QtQuick.Controls 1.4 was, to offer controls with native look and feel. If you want to have easier adjustable controls, and don't need the native look, you should consider the newer and faster QtQuick.Controls 2.0.

Main
What you desire is - afaik - impossible, as the default style consists out of two Rectangles and one Image where the Image seems to be the most important. You can find the images in the mingw-package at this location:

Qt\Qt5.7.0\5.7\mingw53_32\qml\QtQuick\Controls\Styles\Base\images

To access the objects of the control, you find them here:

    Button {
        id: but2
        x: 50
        onClicked: console.log(this.children[1].item.children[0].item.children[0], this.children[1].item.children[0].item.children[1], this.children[1].item.children[0].item.children[2])
    }

So, the easiest solution, to pop into my mind is to use Colorize

import QtQuick 2.0
import QtQuick.Window 2.0
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtGraphicalEffects 1.0
Window {
    width: 1024
    height: 800
    visible: true

    Button {
        id: but
        text: 'test'
    }
    Colorize {
        source: but
        anchors.fill: but

        // values from the documentation example.
        hue: 0.0
        saturation: 0.5
        lightness: -0.2
    }
}

Or to be more general: To just adjust the styling, go for shaders.

QtQuick.Controls 2.0
There you have another case: the background is a Rectangle not just the Component. But if you do not assign one your self, it is only created after the Button.

Button {
    id: but1
    background.color: 'red'
}

is impossible, as the background is not instantiated when you try to assign the color.
You could use the Component.onCompleted handler to do this:

Button {
    id: but1   
    Component.onCompleted: background.color = 'red'
}

But of course you overwrite the Binding of the original style, that handles the color-change while the Button is beeing pressed

Button {
    id: but1   
    Component.onCompleted: background.color = Qt.binding(function() { return (but1.pressed ? 'red' : 'green') }
}

would enable the color-change again, but you won't have the original color. You might retrive the orignal color by trying it out:

Button {
    id: but1
    onPressed: console.log(this.background.color)
    onReleased: console.log(this.background.color)
}

This will output you the colors of the two states for pressed. But maybe there are more! So the easiest solution is to use a conditional Binding as this:

Button {
    id: but1
}

Binding {
    when: but1.pressed
    target: but1
    property: 'background.color'
    value: 'red'
}



回答2:


All QC2 types that derive from a Control have a member called palette. (See here) For some reason they don't mention this in the docs when they're describing how to customize the different controls. But you can look in the source code to see which palette colors you need to modify for your object. For instance, to change a Button's background to be red, you just need this:

Button
{
    id: btn1
    palette.button: "red"
}

You can change all buttons in your application by changing the palette in your ApplicationWindow, like this:

ApplicationWindow
{
    id: mainWin

    // Change default button background to be red
    palette.button: "red"

    Button
    {
        id: btn1
        // Background will be red
    }

    Button
    {
        id: btn2

        // You can of course override the default 
        palette.button: "green"
    }
}


来源:https://stackoverflow.com/questions/42741174/qt-qml-how-to-change-only-one-feature-of-a-say-button-style

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!