当前位置:   article > 正文

QML中常见布局方法_qml 布局

qml 布局

引言

UI界面由诸多元素构成,如Label、Button、Input等等,各种元素需要按照一定规律进行排布才能提高界面的可读性、美观度,需要调整元素的绝对坐标,也就是x、y,使得界面上的元素保持一定的间距,通过间距表达元素之间的关联性或者是区别。

排布策略多种多样,诸如行排列、列排列、栅格排列等等,将元素排布的策略抽象出来,也就是我们所说的布局。Qt Quick中提供了多种布局方法,本文旨在展示不同的布局方法以及探讨其适合的使用场景。

常见方法

锚定(anchors)

在这里插入图片描述

锚定是Qt Quick中较为特殊的布局方式,通过设置Item的anchors属性去调整元素的水平、垂直位置,如上图所示比较重要的基准线AnchorLine有left、righit、top、bottom以及horizontalCenter、verticalCenter,还有一条baseline只针对Text元素不常用,类似文字下划线的位置。示例代码如下:

Rectangle {
    anchors.centerIn: parent
    width: 300
    height: 100
    color: Qt.rgba(247 / 255, 220 / 255, 111 / 255)

    Text {
        anchors.left: parent.left
        anchors.bottom: parent.top
        text: "To Be Continue"
        font.family: "Microsoft YaHei"
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

需要注意的是,fill、centerIn的锚定对象不再是AnchorLine,而是Item,与上述的属性互斥。

定位器

anchors对于单个元素的布局非常灵活、适应性很高,但是对于多个元素的成组的布局而言,代码可读性不高且可拓展性较差。下面将以4个Rectangle的水平排列为例子,对比使用anchors和定位器的实现方案。

在这里插入图片描述
anchors实现代码如下:

Rectangle {
    id: rect1
    width: 200
    height: 100
    color: "gold"
}

Rectangle {
    id: rect2
    anchors.left: rect1.right
    width: 100
    height: 50
    color: "lightseagreen"
}

Rectangle {
    id: rect3
    anchors.left: rect2.right
    width: 80
    height: 150
    color: "lightcoral"
}

Rectangle {
    anchors.left: rect3.right
    width: 100
    height: 120
    color: "lightskyblue"
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

定位器实现代码如下:

Row {
    anchors.fill: parent

    Rectangle {
        width: 200
        height: 100
        color: "gold"
    }

    Rectangle {
        width: 100
        height: 50
        color: "lightseagreen"
    }

    Rectangle {
        width: 80
        height: 150
        color: "lightcoral"
    }

    Rectangle {
        width: 100
        height: 120
        color: "lightskyblue"
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

可以看到使用anchors的实现方式,元素之间需要依次锚定,若需要在水平布局后继续追加,则需要延续这个规则,若需要调换两个元素的位置,需要调整自身的锚定和与之相关的元素的锚定,如rect2需要调整只末尾,在调整自身的anchors.left之外,还需要调整rect3的anchors.left,在界面元素较多的情况下很容易出现遗漏且很难排查。

而使用Row定位器的实现方式,Row会调整自身的所有子元素,将它们按照水平布局进行排布,子元素内部只需要考虑自身的宽高,相互之间并没有直接耦合关系,插入和调整顺序只需要整个代码段进行调节,后期对于间距的调整也可以通过定位器的spacing属性去调节。

Row、Column

Row和Column为行定位器和列定位器,顾名思义就是水平排布以及垂直排布,前面比较中有展示,此处不再赘述。

Grid

Grid为栅格定位器,一般用在元素较多的表单布局中,示例代码如下:

Grid {
    anchors.fill: parent
    columns: 3
    spacing: 5

    Rectangle {
        width: 100
        height: 100
        color: "gold"
    }

    Rectangle {
        width: 100
        height: 100
        color: "lightseagreen"
    }

    Rectangle {
        width: 100
        height: 100
        color: "lightcoral"
    }

    Rectangle {
        width: 100
        height: 100
        color: "lightskyblue"
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

在这里插入图片描述

Flow

Flow为流定位器,功能与Grid类似,用于元素较多的布局,但是可以动态调整列的数量。可以看到Grid示例中固定了列数为3列,而其右侧还有空间并未被填满,Flow则为解决这个问题,示例代码如下:

Flow {
    anchors.fill: parent
    spacing: 5

    Rectangle {
        width: 100
        height: 100
        color: "gold"
    }

    Rectangle {
        width: 100
        height: 100
        color: "lightseagreen"
    }

    Rectangle {
        width: 100
        height: 100
        color: "lightcoral"
    }

    Rectangle {
        width: 100
        height: 100
        color: "lightskyblue"
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

在这里插入图片描述

布局管理器

上述两种布局方式锚定和定位器都只针对元素的坐标,除了anchors.fill之外,都没有对元素的宽高进行调整,实际很多情况下是希望元素能够铺满整个窗口的,也就是元素的宽高能够跟随窗口宽度的变化而变化的。而布局管理器则是为了处理这种情况而出现的,示例代码如下:

RowLayout {
    anchors.fill: parent
    spacing: 5

    Rectangle {
        Layout.preferredWidth: 100
        Layout.fillHeight: true
        color: "gold"
    }

    Rectangle {
        Layout.fillWidth: true
        Layout.fillHeight: true
        color: "lightseagreen"
    }

    Rectangle {
        Layout.preferredWidth: 100
        Layout.fillHeight: true
        color: "lightcoral"
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

在这里插入图片描述

可以看到,左右两个元素设置了固定的宽度Layout.preferredWidth为100,而中间的元素设置Layout.fillWidth填充宽度,在窗口调整时改变的是中间的元素而两侧不变。

布局管理器实现方式与定位器类似,都是管理子元素的位置信息,在使用时需要注意,原本的width、height将不再生效,取而代之的是附加属性Layout.preferredWidth、Layout.preferredHeight或是隐式宽高implicitWidth、implicitHeight,推荐使用附加属性。

Layout.preferredWidth : real
This property holds the preferred width of an item in a layout. If the preferred width is -1 it will be ignored, and the layout will use implicitWidth instead. The default is -1.

在实际使用时还有一个小技巧,可以使用空的Item元素设置Layout.fillWidth: true或Layout.fillHeight: true作为水平布局和垂直布局的弹簧使用,类似QBoxLayout::addStretch()去使用。

RowLayout、ColumnLayout

RowLayout、ColumnLayout为行布局和列布局,用法与Row、Column类似,附加属性Layout有很多参数可以调节,如fillWidth、maximumWidth、minimumWidth、margins等等。

GridLayout

GridLayout为栅格布局,用法与Grid类似,主要是通过附加属性Layout.row、Layout.column调整行号、列号,以此完成特殊的表单布局。

StackLayout

StackLayout为栈布局,主要用于多页签切换使用,示例代码如下:

StackLayout {
    id: stackLayout
    anchors.fill: parent

    Rectangle {
        color: "gold"
    }

    Rectangle {
        color: "lightseagreen"
    }

    Rectangle {
        color: "lightcoral"
    }

    Rectangle {
        color: "lightskyblue"
    }
}

Button {
    text: "Swich"
    font.family: "Microsoft YaHei"

    onClicked: {
        stackLayout.currentIndex = (stackLayout.currentIndex + 1) % stackLayout.count
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

在这里插入图片描述

总结

对于单个相对独立的元素而言,推荐使用anchors。对于多个元素而言,布局定位器的功能更为强大,考虑到后续的可拓展性,多数情况下布局管理器比定位器更好,推荐使用布局管理器,根据开发需要可以酌情使用定位器。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/334684
推荐阅读
相关标签
  

闽ICP备14008679号