首页 > 代码库 > QT Demo 之 threading(2) Spinner

QT Demo 之 threading(2) Spinner

QT Demo 之 threading一章中我们使用到了Spinner,但是由于Spinner本身和thread部分关系不大,而是作为一个独立的自定义组件,因此我们在这一章中单独讲解。

Spinner定义在threading/workerscript/Spinner.qml文件中,由一个Text和Rectangle组成:

Rectangle {
    width: 64
    height: 64
    property alias value: list.currentIndex
    property alias label: caption.text

    Text {...}

    Rectangle {...}
}
Text就是Spinner上面的标签,如在threading示例中使用到的两个Spinner,其标签分别是Row和Column:

而Rectangle部分则是下面的具体数据部分,包括了一个ListView和一个子Rectangle:

    Rectangle {
        anchors.top: caption.bottom
        anchors.topMargin: 4
        anchors.horizontalCenter: parent.horizontalCenter
        height: 48
        width: 32
        color: "black"
        ListView {...}
        Rectangle {...}
    }

ListView部分

在这个示例中,我们遇到了ListView的几个新的属性和使用方法,先看代码如下:

        ListView {
            id: list
            anchors.fill: parent
            highlightRangeMode: ListView.StrictlyEnforceRange
            preferredHighlightBegin: height/3
            preferredHighlightEnd: height/3
            clip: true
            model: 64
            delegate: Text {
                font.pixelSize: 18;
                color: "white";
                text: index;
                anchors.horizontalCenter: parent.horizontalCenter
            }
        }
其中highlightRangeMode以及preferredHighlightBegin和preferredHighlightEnd这三个属性描述了ListView的高亮部分,以及高亮部分的显示属性。

这里,preferredHighlightBegin和preferredHighlightEnd的值都是height/3,实际上描述的是一个线,然后在配合highlightRangeMode的值是StrictlyEnforceRange,那么也就意味着,显示的Item在ListView中不可以上下移动,只要鼠标上下拖到,就会切换到另外一个item上。

假如把preferredHighlightBegin的值设置为0、把preferredHighlightEnd的值设置为height,那么运行的效果就是可以在整个显示区域内拖动,而不改变item的值,只有当item完全越界后才会切换到下一个item(用语言比较不好描述,读者可以自己改变这几个属性的值来看一下具体的效果)。

model部分

这里的model比较奇怪,只是一个数值64,实际运行效果ListView可显示的数值是从0-63(^_^看来从0开始计数的影响甚广啊~)。
通过帮助文档我们了解到,这是一种Integers as Models的方式,官方文档中如下的解释:
An integer can be used as a model that contains a certain number of types. In this case, the model does not have any data roles.
但是如何显示model中的数据呢,那么就看下面的delegate部分。

delegate部分

还是从帮助文档入手,我们找到下面的说明:

Views need a delegate to visually represent an item in a list. A view will visualize each item list according to the template defined by the delegate. Items in a model are accessible through the index property as well as the item‘s properties.

以及

A special index role containing the index of the item in the model is also available to the delegate.

这里面提到,我们可以使用内置变量index来访问当前Item的index,如果model是Integers as Models的方式,那么Item和index就一一对应了。

Rectangle部分

在最后代码中的Rectangle部分则是定义了整个ListView的渐变色效果,代码如下:

        Rectangle {
            anchors.fill: parent
            gradient: Gradient {
                GradientStop { position: 0.0; color: "#FF000000" }
                GradientStop { position: 0.2; color: "#00000000" }
                GradientStop { position: 0.8; color: "#00000000" }
                GradientStop { position: 1.0; color: "#FF000000" }
            }
        }
这里定义了中间0.2-0.8的部分是全透明,上下分别0.2的部分是黑色渐变,整体的效果如下:

注意其中的6和8以及3和5的显示效果。

这里为什么设置上下两边是黑色,中间是全透明的原因,是gradient生效的是一个完全独立的Rectangle,大小和外面的Rectangle一致,相当于在外面的Rectangle上面覆盖一个具有渐变效果的蒙板。如果直接对外面的Rectangle进行渐变处理,由于又涉及到显示文字,比较难实现,不如直接进行一个蒙板处理。

关于gradient渐变,帮助文档中的一个例子则更加直观:

Rectangle {
    width: 100; height: 100
    gradient: Gradient {
        GradientStop { position: 0.0; color: "red" }
        GradientStop { position: 0.33; color: "yellow" }
        GradientStop { position: 1.0; color: "green" }
    }
}
效果如下:

总结

本节学到的知识点:

  1. 如何通过自定义组件完成滑动列表的效果
  2. 如何使用Integers as Models的方式在ListView中显示数据
  3. 学习Rectangle的渐变色效果处理

在这一章中,我们可以看到结合Rectangle和ListView就可以实现一个滑动列表,并且通过渐变处理使得显示效果比较人性化。

//FIXME:这里留下一下疑问,就是如何通过限定条件,可以完成滑动列表中的循环,即当鼠标滑动到最后一个Item时,如何使得下面紧接的回到第一个item?

QT Demo 之 threading(2) Spinner