QML控件使用踩坑记录

227 阅读5分钟

前言

在平时工作中,对QML的使用还是非常多的,但是经常有一些小问题值得记录和思考,本篇文章持续更新,来记录这些细节问题和踩坑记录。

正文

包含一些自己的理解,以及一些使用问题,方便后续查找。

1. clip属性

表示裁剪属性,在我们的固定思维中,或许觉得把一个控件定义在父控件内,其子控件就不会超过父控件,其实不然。比如下面代码:

        Rectangle {
            width: 100
            height: 100
            border.width: 3
            border.color: "black"
            //裁剪属性为false
            clip: false

            Rectangle {
                width: 70
                height: 70
                color: "red"
            }

            Rectangle {
                x: 50
                y: 50
                width: 70
                height: 70
                color: "yellow"
            }
        }

Rectangleclip默认属性为false,上面代码效果是:

image.png

可以发现虽然黄色的矩形框定义在父控件内,但是其仍然可以在父控件外绘制,如果我们把父控件的clip属性设置为true,效果如下:

image.png

在这种情况下,父控件就像是一个有边界的容器,子控件是无法在其范围外绘制,这就是clip的作用和效果。

2.Flickable控件

这是一个在触摸屏上使用非常广泛的一个控件,当我们想在有限的屏幕上显示更多的内容,最佳的方案就是使用滚动。但是传统的用户界面中,可以使用ScrollView来滚动视图,用户可以拖动滚动条来滚动视图显示,下面是使用ScrollView的效果:

image.png

在这种情况下,一般都是通过拖拽来完成视图滚动

但是在基于触摸的用户界面中,就不仅仅是拖拽了,还有轻扫的动作,即像手机浏览内容一样,在手指轻轻滑动离开手机后,视图可以继续滚动,在这种情况下就需要使用Flickable控件了,对于嵌入式设备来说,可以像手机一样浏览内容是非常好的交互效果。

其实对于Flickable控件,很多就直接翻译为滚动控件,其实我个人觉得还是其英文原来的意思最好。因为在UI交互中,dragflick是2种不同的手势操作:

  • drag:翻译为拖动,是指用户按住某个对象,将其移动到新的位置,在交互中常用来移动控件的位置。
  • flick:翻译为轻扫,是指用户迅速用手指在触摸屏上划过的动作,在交互中常用来实现快速滚动、切换页面或者浏览内容等操作。

当进行浏览内容时,用户在flick之后,内容依旧会有一个惯性效果,不会立马停止滚动,这种交互也更符合习惯。下面就来简单介绍一下Flickable控件的使用:

  1. 属性contentWidthcontentHeight,用来定义Flickable中内容的实际尺寸。这就要注意了,在使用Flickable时不仅仅要设置自己的宽高,也需要设置内容的宽高,当内容宽高大于自身的尺寸,就可以通过滚动来查看超出部分的内容。
  2. 属性flickableDirection,用来定义可以滚动的方向,正常情况下是不需要设置的,当Flickable的内容宽高大于自身宽高时便可以滚动。
  3. 属性boundsBehavior用来定义边界行为。当拖动或者轻扫时,且Flickable内容小于自身控件时,我们可以设置为Flickable.StopAtBounds来让其在边界时静止滚动;当Flickable可以滚动时,且内容滚动到边界时,默认会有惯性效果,会超过边界的效果,同样可以静止这种效果。
  4. Flickableclip属性默认为false,在使用时建议设置为true

简单使用代码:

        Flickable {
                id: flickable
                width: 300
                height: 400
                contentWidth: 300
                contentHeight: rec.height
                clip: true
                boundsBehavior: Flickable.StopAtBounds

                Rectangle {
                    id: rec
                    width: 300
                    height: repeater.model * 50
                    color: "lightblue"

                    ColumnLayout {
                        anchors.fill: parent
                        Repeater {
                            id: repeater
                            model: 20
                            delegate: Text {
                                text: "Item " + index
                                width: parent.width
                                height: 50
                                verticalAlignment: Text.AlignVCenter
                                horizontalAlignment: Text.AlignHCenter
                                color: "black"
                                font.pixelSize: 20
                            }
                        }
                    }
                }
        }

代码效果如下:

image.png

使用Flickable的主要注意点就是正确设置其内容的宽高。

3. ChartViewgridLinePen属性

在使用ChartView绘制折线图时,我们通常有个不太关注的需求点,就是设置其背景网格的样式,这里我们是使用ValuesAxis来设置X、Y轴的样式,以及背景网格线的颜色等,比如下面代码:

ChartView {
            id: line
            Layout.rightMargin: 0
            Layout.preferredHeight: enLargedMode ? 693 : 400
            Layout.fillWidth: true
            Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
            legend.visible: false
            antialiasing: true

            MouseArea {
                anchors.fill: parent
                onClicked: chartClick()
            }

            //重点看这里
            ValuesAxis{
                id: axisX
                min: 0
                max: chartTotalTime
                labelsFont.pixelSize: 20
                color: "#000000"
                gridLinePen: gcDataResolve.qmlPen()
            }

            ValuesAxis{
                id: axisY
                min: 0
                max: chartMaxTemperature
                labelsFont.pixelSize: 20
                color: "#000000"
                gridLinePen: gcDataResolve.qmlPen()
            }
...省略            

在上面注释的地方,我们对X轴以及水平方向的网格线做了处理,比如设置了颜色,但是却没有设置其宽度的属性,可以看见:

image.png 这里有颜色可以设置,如果想设置宽度要如何做呢?只有使用gridLinePen属性,当使用它时,却发现QML语法并不支持也没有QPen控件,对于这种情况我们可以使用C++代码来创建一个QPen对象,然后调用它,如上面代码中的qmlPen()方法:

QPen GCDataResolve::qmlPen()
{
    QPen pen;
    pen.setWidthF(1.5);
    return pen;
}

只需要注册该类进入QML系统,便可以调用该方法获取一个QPen对象了。

总结

本篇文章持续更新,记录QML中控件的使用细节。