【问题标题】:QT QML how to change only one feature of a, say, button styleQT QML如何仅更改按钮样式的一个功能
【发布时间】:2017-03-11 22:01:25
【问题描述】:

更改组件的style,似乎替换了所有默认样式的功能。有没有办法只改变一个功能?

例如,假设我想要一个红色按钮;

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" }
        }
    }
}

用background 重新定义ButtonStyle 可以很好地更改按钮的颜色,但是系统默认ButtonStyle 中的所有其他内容都消失了。例如边框和点击高亮。

如何只更改一项功能并保留其余功能?

抱歉,之前有人问过这个问题。

谢谢,

更新

上面的问题是针对控件 1 的,但是控件 2 也存在同样的问题。下面是控件 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" }
    }
}

【问题讨论】:

    标签: qt qml qtquick2 qtquickcontrols


    【解决方案1】:

    前言
    QtQuick.Controls 1.4 的目的是提供具有原生外观和感觉的控件。如果您想要更轻松的可调节控件,并且不需要原生外观,您应该考虑更新更快的QtQuick.Controls 2.0。

    主要
    您想要的是 - afaik - 不可能,因为默认样式由两个 Rectangles 和一个 Image 组成,其中 Image 似乎是最重要的。您可以在以下位置找到 mingw-package 中的图像:

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

    要访问控件的对象,您可以在此处找到它们:

        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])
        }
    

    所以,我想到的最简单的解决方案是使用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
        }
    }
    

    或者更笼统地说:要调整样式,请使用着色器。

    QtQuick.Controls 2.0
    还有另一种情况:background 是 Rectangle 而不仅仅是Component。但是如果你不给自己分配一个,它只会在Button之后创建。

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

    不可能,因为当您尝试分配颜色时,背景并未实例化。
    您可以使用Component.onCompleted 处理程序来执行此操作:

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

    但是你当然会覆盖原始样式的Binding,它会在Button 被按下时处理颜色变化按下

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

    将再次启用颜色更改,但您不会拥有原始颜色。 您可以通过尝试恢复原始颜色:

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

    这将为您输出pressed 的两种状态的颜色。但也许还有更多!所以最简单的解决方案是使用条件Binding:

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

    【讨论】:

    • 臭虫。抱歉,是的,我应该使用 Controls2.Button。我改成这个了,但是除了Label -> contentItem之外,都是一样的。然后我有同样的问题,每当我覆盖时,说background。我喜欢你关于着色器的想法和Colorize。我认为添加样式比更改这些属性更好。 FWIW,如果您不能以某种方式继承原始属性,我认为这些属性是糟糕的设计。谢谢。我会接受你的建议。
    • 请更新您的问题以反映您实际使用的内容。它们是两种截然不同的样式 API。
    • 虽然我已经更新了答案以解决您对QtQuick.Controls 2.x 的一些可能性,但更新问题、匹配它会很好,因此它也可以帮助其他人。此外,如果它包含您正在寻找的内容,请不要忘记接受答案。对于您其他问题的所有答案,也请这样做,因为这既是:对花时间回答的人有礼貌,又要帮助人们找到答案,如果他们和您有同样的问题。跨度>
    • @derM。我很欣赏你的回答,但这个问题没有得到回答。更改 Controls 2 样式的简单属性似乎不可能或非常复杂。我与其他 C2 有类似的问题;例如CheckBox。如何更改复选标记的颜色。每当我阅读 QML 的实现时,它都会使用一些私有特性,所以这不仅仅是复制它的问题。
    • 我看不到您的问题。 cb 是我的 CheckBox。我想在选中时将指示器的颜色更改为红色。我使用:Binding { when: cb.checkState === Qt.Checked; target: cb.indicator; property: 'color'; value: 'red' }。不涉及私有类的实例化。关于这个indicator 的唯一事情是,它仅在CheckBox 完成时才被实例化,以提高内存效率。 (可以有数百个CheckBoxs
    【解决方案2】:

    所有派生自 Control 的 QC2 类型都有一个名为 palette 的成员。 (参见here)出于某种原因,当他们描述如何自定义不同的控件时,他们在文档中没有提到这一点。但是您可以查看源代码以查看您需要为您的对象修改哪些调色板颜色。例如,要将Button 的背景更改为红色,您只需要这样:

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

    您可以通过更改ApplicationWindow 中的调色板来更改应用程序中的所有按钮,如下所示:

    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"
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-28
      • 1970-01-01
      • 2019-02-08
      • 2014-09-23
      • 1970-01-01
      • 2014-09-29
      • 1970-01-01
      相关资源
      最近更新 更多