本页内容

StyleKit 功能概述

本页简要介绍了 StyleKit 的主要功能。如需查看所有可用类型和属性的完整参考文档,请参阅QML Types 页面。

创建样式

Style 是一个 QML 对象,用于描述 Qt Quick Controlsbutton 、slider 、checkBox 等。每个控件在样式中都有自己的组,您可以在其中为构成控件的视觉部分设置颜色、大小、半径和阴影等属性。

control group 具有特殊性,因为它充当了所有其他控件组的后备方案。例如,如果您未为slider 设置某些属性,系统将转而从control 中读取这些属性。 若在slider 或control 中未设置的属性,将进一步回退到fallback style ,该样式与“基本样式”类似,是一个完整的样式。这意味着您不必为所有可用控件设置样式,只需自定义您想要的控件即可——回退机制会自动处理其余控件的样式:

// PlainStyle.qml

Style {
    control {
        // control does not map to an actual Qt Quick Control, but is a shared
        // fallback for all other controls. Use it to define styling that is
        // common to all of them. Unset properties fall back to Style.fallbackStyle.
        padding: 6
        text.color: "white"
        background {
            radius: 4
            border.color: "gray"
        }
        indicator {
            width: 20
            height: 20
            border.width: 1
            radius: 3
        }
        handle {
            width: 20
            height: 20
            radius: 10
        }
    }

    slider {
        // slider defines the styling for a Qt Quick Slider.
        // Unset properties fall back to control.
        handle.color: "white"
        indicator {
            fillWidth: true
            height: 6
            color: "steelblue"
            foreground.color: "skyblue"
        }
    }

    abstractButton {
        // abstractButton does not map to an actual Qt Quick Control, but
        // is a shared fallback for button-like controls, such as button,
        // radioButton, checkBox). Use it to define styling that is common
        // to all of them. Unset properties fall back to control.
        background.shadow {
            opacity: 0.6
            verticalOffset: 2
            horizontalOffset: 2
            color: "gray"
        }
    }

    button {
        // button defines the styling for a Qt Quick Button.
        // Unset properties fall back to abstractButton.
        background {
            width: 120
            color: "lightsteelblue"
            gradient: Gradient {
                GradientStop { position: 0.0; color: Qt.alpha("black", 0.0)}
                GradientStop { position: 1.0; color: Qt.alpha("black", 0.2)}
            }
        }
    }

    // Controls left undefined — such as radioButton, checkBox, roundButton
    // or switchControl — fall back to their immediate base type, which in
    // this style will be either abstractButton or control directly.
}

激活样式

要激活该样式,请将其分配给根控件 `ApplicationWindow` 上的 `StyleKit.style `。随后,应用程序中的所有控件都会自动采用该样式:

// Main.qml

import QtQuick
import Qt.labs.StyleKit

ApplicationWindow {
    id: app
    width: 1024
    height: 800
    visible: true

    // Assign the style to be used
    StyleKit.style: PlainStyle {}

    // Controls are used as normal
    Column {
        anchors.fill: parent
        anchors.margins: 10
        spacing: 10

        Button {
            text: "Button"
        }

        Slider {
            width: 200
        }
    }
}

控件状态

控件的外观会根据用户交互而变化——按钮在悬停、按下或禁用时看起来不同。StyleKit 允许您通过在受影响的属性前添加state 名称,在样式中表达这种变化,从而在控件处于该状态时为其赋予相应的替代值。

状态可以嵌套,且更具体的组合(例如hovered.checked )优先于其单独的组成部分:

button {
    text.color: "aliceblue"
    background.color: "cornflowerblue"
    pressed.background.color: "deepskyblue"
    hovered.background.color: "lightskyblue"
    focused.background.color: "lightsteelblue"
    checked.background.color: "royalblue"
    highlighted.background.color: "lightblue"
    disabled {
        background.color: "lightgray"
        background.border.color: "darkgray"
    }

    // Nested states, such as hovered.checked in this case, takes
    // precedence over both hovered and checked:
    hovered.checked.background.color: "steelblue"
}

状态转换

通过在控件样式中设置 `transition ` 属性,可以对状态变化进行动画效果处理。`StyleAnimation ` 提供了一种便捷的方式来对一组相关的样式属性(如所有背景色或指示器颜色)进行动画处理,但您也可以使用标准的 QML 动画,例如 `ColorAnimation ` 和 `NumberAnimation `:

comboBox {
    background.color: "lightgray"
    hovered.background.color: "plum"

    indicator.color: "white"
    hovered.indicator.color: "pink"
    hovered.indicator.border.width: 4

    transition: Transition {
        StyleAnimation {
            animateBackgroundColors: true
            animateIndicatorColors: true
            animateIndicatorBorder: true
            easing.type: Easing.OutQuad
            duration: 500
        }
    }
}

主题

StyleKit 通过 `Style` 控件上的 `light ` 和 `dark ` 属性,内置了对浅色和深色主题的支持。与 `Style` 类似,`Theme ` 允许您定义当该主题处于活动状态时,每个控件应采用的样式。未在主题中设置的属性将回退到从样式中读取:

Style {
    light: Theme {
        applicationWindow.background.color: "gainsboro"
        control.text.color: "#202020"
        control.background.color: "#f0f0f0"
        control.background.border.color: "#d0d0d0"
        button.hovered.background.color: "#4a90d9"
        radioButton.indicator.foreground.color: "#d0d0d0"
    }

    dark: Theme {
        applicationWindow.background.color: "#2b2b2b"
        control.text.color: "#e0e0e0"
        control.background.color: "#404040"
        control.background.border.color: "#606060"
        button.hovered.background.color: "#6ab0f9"
        radioButton.indicator.foreground.color: "#606060"
    }
}

自定义主题

除了浅色和深色主题之外,您还可以通过 `CustomTheme` 定义任意数量的额外主题。每个 `CustomTheme ` 都拥有一个 `name `,并包含一个与内置主题结构相同的 `Theme ` 对象:

Style {
    CustomTheme {
        name: "HighContrast"
        theme: Theme {
            control.background.color: "white"
            control.background.border.color: "black"
            control.background.border.width: 2
        }
    }

    CustomTheme {
        name: "Sepia"
        theme: Theme {
            control.text.color: "#5b4636"
            control.background.color: "#f4ecd8"
            control.background.border.color: "#c8b99a"
            applicationWindow.background.color: "#efe6d0"
        }
    }
}

要在运行时切换主题,请在应用程序的 QML 文件中将 `Style.themeName ` 设置为所需主题的名称。`Style.themeNames` 属性列出了所有可用的主题名称,这使得为选择器控件填充选项变得非常简单:

ComboBox {
    model: StyleKit.style.availableThemeNames
    onCurrentTextChanged: StyleKit.style.themeName = currentText
}

要在应用程序启动时激活某个主题,请在分配样式时设置 `themeName `:

ApplicationWindow {
    width: 1024
    height: 800
    visible: true

    StyleKit.style: MyStyleKitStyle {
        themeName: "HighContrast"
    }
}

样式变体

StyleVariation 允许您为应用程序的某些部分定义替代样式。当需要对控件进行差异化样式设置时(例如,当它们是 `ToolBar ` 或 `GroupBox` 的子元素时),或者您希望实现应用程序可选地应用于某些控件的样式提示时,此功能非常有用。

样式变体分为两种类型:类型变体和实例变体。

类型变体

类型变体包含针对作为另一种控件类型子控件(或后代)的控件的替代样式。这意味着,如果一个StyleVariation 包含按钮的样式,并且被添加到框架的variations 属性中,那么StyleKit 将相应地为应用程序中Frames 的所有Buttons 子控件应用这些样式:

Style {
    frame {
        variations: StyleVariation {
            button {
                text.color: "ghostwhite"
                background.border.width: 0
                background.color: "slategrey"
            }
        }
    }

    groupBox {
        // groupBox falls back to frame. Therefore, if the varations set on a
        // frame is not wanted on a groupBox, just override it and set it back to [].
        variations: []
    }
}

实例变体

名为StyleVariations 的样式可通过StyleVariation.variations 附加属性应用于应用程序中的单个控件。 应用后,该控件本身及其所有子控件都将采用替代样式。这与类型变体不同,后者会影响所有特定类型的控件,例如所有Frames 。实例变体仅影响其附加的控件实例(及其子控件):

Style {
    StyleVariation {
        name: "mini"
        control {
            padding: 2
            background.height: 15
            indicator.width: 15
            indicator.height: 15
            handle.width: 15
            handle.height: 15
        }
    }

    StyleVariation {
        name: "alert"
        abstractButton.background.color: "red"
    }
}

将其应用于应用程序中的控件:

GroupBox {
    title: "Mini controls"
    StyleVariation.variations: ["mini"]

    Row {
        spacing: 10
        Button { text: "Save" }
        CheckBox { text: "Option" }
        // This button also has the "alert" variation, in addition to "mini"
        Button {
            text: "Delete"
            StyleVariation.variations: ["alert"]
        }
    }
}

自定义控件

如果您的应用程序包含不属于 Qt Quick Controls,您仍可将其与StyleKit 集成。只需为每个控件添加一个CustomControl ,并像设置built-in controls 样式那样为其设置样式:

// MyStyle.qml

Style {
    id: style
    readonly property int myControlType: 0
    CustomControl {
        controlType: style.myControlType
        background {
            width: 120
            height: 30
            radius: 0
        }
        hovered.background.color: "lightslategray"
        pressed.background.color: "skyblue"
    }
}

在控件的实现中,请使用带有匹配的controlType 的StyleReader 来读取样式属性。正确的属性值是通过综合考虑Themes 、StyleVariations 、fallback types 以及属性传播来确定的。为了实现这一点,样式读取器需要了解控件的状态。 因此,请将控件的状态绑定到相关的StyleReader 属性上,例如hovered 和pressed 。每次状态发生变化时,受影响的样式属性都会被更新,从而触发控件重绘:

// Main.qml

component MyControl : Rectangle {
    StyleReader {
        id: styleReader
        controlType: StyleKit.style.myControlType
        hovered: hoverHandler.hovered
        pressed: tapHandler.pressed
        palette: app.palette
    }

    HoverHandler { id: hoverHandler }
    TapHandler { id: tapHandler }

    implicitWidth: styleReader.background.width
    implicitHeight: styleReader.background.height
    color: styleReader.background.color
    radius: styleReader.background.radius

    Text {
        font: styleReader.font
        anchors.centerIn: parent
        text: "ok"
    }
}

自定义委托

控件的每个视觉部分——background 、handle 、indicator 等——均由delegate 渲染。默认情况下,StyleKit 使用StyledItem 进行渲染,但您可以完全用您自己的QML组件替换它。

该组件需要定义两个必需属性, StyleKit 会自动填充这些属性:

  • delegateStyle —DelegateStyle ,用于承载已解析的样式属性(颜色、半径、隐式尺寸等)
  • control — 该委托所属的Qt Quick 控件

然后,将该组件赋值给您希望对其进行设置的视觉组件的 `delegate ` 属性:

// import QtQuick.Templates as T

slider {
    handle.delegate: Rectangle {
        id: handle
        required property DelegateStyle delegateStyle
        required property T.Slider control
        implicitWidth: delegateStyle.width
        implicitHeight: delegateStyle.height
        radius: delegateStyle.radius
        color: delegateStyle.color
        Text {
            anchors.centerIn: parent
            text: handle.control.value.toFixed(0)
        }
    }
}

覆盖层与底层

如果您只想增强默认渲染效果,而不是完全替换它,请将 `StyledItem ` 作为委托的根节点。添加到 `StyledItem ` 中的任何子元素都会绘制在默认渲染效果之上(即覆盖):

Style {
    component Star : Shape {
        id: star
        property color color
        ShapePath {
            fillColor: star.color
            scale: Qt.size(star.width, star.height)
            PathMove { x: 0.50; y: 0.00 }
            PathLine { x: 0.59; y: 0.35 }
            PathLine { x: 0.97; y: 0.35 }
            PathLine { x: 0.66; y: 0.57 }
            PathLine { x: 0.78; y: 0.91 }
            PathLine { x: 0.50; y: 0.70 }
            PathLine { x: 0.22; y: 0.91 }
            PathLine { x: 0.34; y: 0.57 }
            PathLine { x: 0.03; y: 0.35 }
            PathLine { x: 0.41; y: 0.35 }
            PathLine { x: 0.50; y: 0.00 }
        }
    }

    button {
        background.delegate: StyledItem {
            width: parent.width
            height: parent.height
            // Draw a star on top the default rendering
            Star {
                anchors.fill: parent
                color: "gold"
            }
        }
    }
}

若要将内容绘制在默认渲染结果的下方,请将您的委托类设置为 `Item`,将额外内容置于最前,并嵌套一个 `StyledItem ` 作为子元素,以在最上方渲染默认外观:

Style {
    component Star : Shape {
        id: star
        property color color
        ShapePath {
            fillColor: star.color
            scale: Qt.size(star.width, star.height)
            PathMove { x: 0.50; y: 0.00 }
            PathLine { x: 0.59; y: 0.35 }
            PathLine { x: 0.97; y: 0.35 }
            PathLine { x: 0.66; y: 0.57 }
            PathLine { x: 0.78; y: 0.91 }
            PathLine { x: 0.50; y: 0.70 }
            PathLine { x: 0.22; y: 0.91 }
            PathLine { x: 0.34; y: 0.57 }
            PathLine { x: 0.03; y: 0.35 }
            PathLine { x: 0.41; y: 0.35 }
            PathLine { x: 0.50; y: 0.00 }
        }
    }

    slider.handle.delegate: Item {
        // Since the root item is not a StyledItem, the following
        // required properties must be defined explicitly:
        required property DelegateStyle delegateStyle
        required property QtObject control

        implicitWidth: delegateStyle.width
        implicitHeight: delegateStyle.height
        width: parent.width
        height: parent.height
        scale: delegateStyle.scale
        rotation: delegateStyle.rotation
        visible: delegateStyle.visible

        // Draw a star underneath the default handle delegate
        Star {
            width: parent.width * 2
            height: parent.height * 2
            anchors.centerIn: parent
            color: "gold"
        }

        StyledItem {
            // Forward delegateStyle into StyledItem. StyledItem doesn't
            // use 'control' for anything, so it can be omitted.
            delegateStyle: parent.delegateStyle
        }
    }
}

自定义数据

自定义委托有时需要超出内置范围的额外样式属性——例如,为 `StyleKit ` 无法识别的子项设置样式。`data ` 属性使这成为可能。它可以持有任何 `QtObject`,因此能够承载您的委托所需的任何信息。

与所有其他样式属性一样,data 参与样式属性解析——委托始终接收与当前控件状态、活动主题和样式变体相匹配的对象。与内置属性不同,data 作为整体进行传播——对象内的各个属性不会单独传播:

component OverlayData : QtObject {
    property color overlayColor
}

toolButton {
    background.delegate: StyledItem {
        id: custom
        Text {
            color: custom.delegateStyle.data.overlayColor
            font.pixelSize: 30
            text: "シ"
        }
    }
    background.data: OverlayData {
        overlayColor: "sandybrown"
    }
    hovered.background.data: OverlayData {
        overlayColor: "magenta"
    }
}

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.