65.9K
CodeProject 正在变化。 阅读更多。
Home

在 QML 控件上应用自定义默认样式

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.92/5 (11投票s)

2014 年 4 月 6 日

CPOL

4分钟阅读

viewsIcon

30231

downloadIcon

468

关于如何以类似 CSS 的方式设置和自定义 QML 控件外观的简短指南

引言

QML 是一项技术,它允许您创建平台无关的用户界面。当前的 Qt 版本 5.2 允许创建单个 GUI,该 GUI 在 Linux、Windows、OS X、iOS 和 Android 上运行,而无需更改代码库。我在这里描述的是一种类似 CSS 的 QML 控件样式设置方法,并允许重用这些控件。

背景

本文的背景是我在开发 Workspaces::Tasks 应用的 GUI 研究时遇到的一个问题:我想在所有文本块上使用 Segoe UI 字体,并能够自定义这些控件的背景色和前景色。最终,我为每个想要拥有默认样式的控件创建了一个 QML 文件。到目前为止,我已经定义了 Rectangle 和 Text 控件的样式。这些重定义定义在 CPRectangle.qml 和 CPText.qml 文件中。

为了在应用程序的主窗口中使用这些文件,它们需要位于与 main.qml 相同的位置。我已经将我的开发环境设置在 OS X 上,但这没有任何区别,因为我使用的是 Qt 5.2.1 附带的 Qt Creator - 它在 Creator 可以运行的任何操作系统上都是相同的。如果您对结果感兴趣,那就是 GUI 研究的启动屏幕。

我无法告诉您关于这项研究的更多内容,因为它仍在积极开发中(而且我仍然在为一些特定的控件选择而烦恼)。

自定义控件

首先,我需要一个 CodeProject 橙色(#ff9900)的 Rectangle,以便某些控件的背景能够以一致的方式显示 - 即使可能性不大,Chris 某天也可能决定更改主题,那样的话,如果每个控件的背景色都是手动设置的,我祝他替换愉快。做到这一点相当容易,您可以在 CPRectangle.qml 文件中看到我所做的。

import QtQuick 2.0

Rectangle {

    color:"#ff9900"

}

我所做的就是创建一个 Rectangle,并将其 color 属性设置为 CodeProject 橙色(#ff9900)。因为它定义在 CPRectangle.qml 中,所以在另一个 QML 文件中,新创建的控件可以用作 CPRectangle,我在定义 CPText(在 CPText.qml 中)时就使用了这一点。

import QtQuick 2.0

CPRectangle{
    Text {
        id:textContent
        font.family: "Segoe UI"
    }

    width: childrenRect.width
    height: childrenRect.height

    property alias text: textContent.text
    property alias textColor: textContent.color

}

这里所做的工作要稍微复杂一些。CPText 控件基本上是一个 CPRectangle,其中包含一个普通的 Text QML 控件,该控件已将其 font.family 属性设置为 Segoe UI。我通过使用 childrenRect.width 和 childrenRect.height 来定义 Rectangle 的宽度和高度,使 CPRectangle 能够自动适应文本的大小。困难之处在于使 Text 控件的某些属性能够从外部 QML 访问。以 property alias 开头的行可以做到这一点,例如 property alias text: textContent.text 允许我访问内部 Text 控件的 text 属性,如下所示:

CPText{
    text: "CodeProject Workspaces::Tasks GUI study"
}

当然,textColor 属性也同样有效。

使用自定义控件

现在我们来定义 main.qml 文件的内容,该文件定义了主窗口(或者在我的例子中,是应用的启动屏幕)。我使用了一种基于行和列的系统来让 QML 居中窗口的内容,由于这有点棘手,我也在这里展示一下。

 
import QtQuick 2.0

CPRectangle {
    id: rectangle1
    width: 360
    height: 360

    Row{//Display anchoring root
        anchors.centerIn: parent

        Column{
            anchors.centerIn: parent
            BorderImage { //CodeProject Logo
                id: splash
                width: 100
                height: 100
                source: "qrc:/logo/CPLogo.gif"
             }
             CPRectangle{//Spacing
                height:10
             }
             CPText{//Text part
                 anchors.topMargin: 1
                 text: "Workspaces::Tasks"
                 textColor:"White"
             }

        }
    }
}

背景是一个 CPRectangle,以漂亮的 CodeProject 橙色显示。在这个 CPRectangle(起了一个非常有意义的名字 rectangle1)内部,我定义了一个单行,这是我放在屏幕上的每个控件的根节点。这个行有一个单列,然后包含一个 BorderImage,其 source 属性设置为显示资源文件中定义的 CodeProject logo。此外,还有一个 CPRectangle,用作图片和文本之间的分隔符。文本是之前定义的 CPText,它将 textColor 属性的别名设置为“White”。为了使所有内容都居中,我将行和列设置为在其父控件中居中。

所有这些加在一起就得到了以下输出:

 
OS X 上的用户界面

 


Windows 7 上的用户界面

关注点

QML 允许您做很多事情,有时我认为它会增加您想做的工作的复杂性。尽管如此,我认为它是当今最好、最先进的多平台框架。我知道 Mono 非常流行,但 Qt 的文档比 Mono 更丰富,也更容易扩展。而且由于有 C++ 的后端代码,您很有可能可以集成现有的遗留代码,而无需进行大量更改。QML 的学习曲线相当陡峭,但我看到随着在线教程的发布,它变得越来越容易。当我刚开始使用 Qt 时,关于 QML 的信息很难找到,但如今网络上有一些非常聪明的人,为您提供了最好的教程,让您用 Qt 创造出一些令人惊叹的东西。有时 QML 的类似 JavaScript 的语法会令人困惑,但您使用得越多,就会越爱上它。

© . All rights reserved.