9.QML中的布局

原创
2022-12-02
5193
23

1. 锚布局

锚布局(anchors)提供了一种方式,让你可以指定一个元素与其他元素的关系来确定原色在界面中的位置。
每个Item都用7条不可见的锚线:左(left)、水平中心(horizontalCenter)、上(top)、下(bottom)、右(right)、垂直居中(verticalCenter);除了锚线外,还可以指定4个区域的留白:上(topMargin)、下(bottomMargin)、左(leftMargin)、右(rightMargin)
还可以使用anchors.fill来填充整个区域,使用anchors.center使某个Item居中
下面是关于锚布局的一个简单的示例,显示效果如下

整体代码如下:

import QtQuick 2.0
import QtQuick.Window 2.0
import QtQuick.Controls 1.4

Window {
    id: mainWindow
    width: 800
    height: 600
    visible: true

    Rectangle {
        // 填充整个区域
        anchors.fill: parent
        color: '#505050'

        Rectangle {
            // 左上角
            anchors.top: parent.top
            anchors.topMargin: 10
            anchors.left: parent.left
            anchors.leftMargin: 10
            color: 'blue'
            width: 100
            height: 100
        }

        Rectangle {
            // 右上角
            anchors.top: parent.top
            anchors.topMargin: 10
            anchors.right: parent.right
            anchors.rightMargin: 10
            color: 'blue'
            width: 100
            height: 100
        }

        Rectangle {
            // 左下角
            anchors.bottom: parent.bottom
            anchors.bottomMargin: 10
            anchors.left: parent.left
            anchors.leftMargin: 10
            color: 'blue'
            width: 100
            height: 100
        }

        Rectangle {
            // 右下角
            anchors.bottom: parent.bottom
            anchors.bottomMargin: 10
            anchors.right: parent.right
            anchors.rightMargin: 10
            color: 'blue'
            width: 100
            height: 100
        }

        Rectangle {
            // 居中
            anchors.centerIn: parent
            color: 'blue'
            width: 100
            height: 100
        }

        Rectangle {
            // 中上
            anchors.top: parent.top
            anchors.topMargin: 10
            anchors.horizontalCenter: parent.horizontalCenter
            color: 'blue'
            width: 100
            height: 100
        }

        Rectangle {
            // 左中
            anchors.left: parent.left
            anchors.leftMargin: 10
            anchors.verticalCenter: parent.verticalCenter
            color: 'blue'
            width: 100
            height: 100
        }

        Rectangle {
            // 右中
            anchors.right: parent.right
            anchors.rightMargin: 10
            anchors.verticalCenter: parent.verticalCenter
            color: 'blue'
            width: 100
            height: 100
        }

        Rectangle {
            // 中下
            anchors.bottom: parent.bottom
            anchors.bottomMargin: 10
            anchors.horizontalCenter: parent.horizontalCenter
            color: 'blue'
            width: 100
            height: 100
        }
    }
}

2. 定位器

常用的定位器有如下几种,RowColumnGridFlow

  • Row: 沿一行放置它的子Item。
  • Column: 垂直放置一列Item。
  • Grid: 在网格上放置它的子Item。可以使用rowscolumns指定表格的行数和列数。使用rowSpacingcolumnSpacing指定行、列间距;flow指定表格的流模式, Grid.LeftToRight为默认值,从左到右放置Item,当设置为 Grid.TopToBottom时,表示从上到下放置Item。
  • Flow: 与Grid类似不同之处在于,不用指定行数和列数,他会计算Item的尺寸然后与自身尺寸比较自动换行。
  • 上面的几个编辑器都具有如下属性:addmovepopulate
  • 都具有Positioner的附加属性,可以通过PositionerindexisFirstItemisLastItem获取当前显示Item的信息。

下面是一个简单的关于定位器布局的示例:

完整的QML代码如下:

import QtQuick 2.0
import QtQuick.Window 2.0
import QtQuick.Controls 1.4

Window {
    id: mianWindow

    width: 800
    height: 600
    visible: true

    Rectangle {
        anchors.fill: parent
        color: '#505050'

        Row {
            anchors.top: parent.top
            anchors.topMargin: 5
            anchors.left: parent.left
            anchors.leftMargin: 5
            spacing: 5

            Repeater {
                model: 4
                Rectangle {
                    width: 50
                    height: 50
                    id: positionerRow
                    color: getRectColor()

                    function getRectColor() {
                        if (Positioner.index === 0)
                            return 'red'
                        else if (Positioner.index === 1)
                            return 'yellow'
                        else if (Positioner.index === 2)
                            return 'blue'
                        else
                            return 'green'
                    }
                }
            }
        }
    }

    Column {
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 5
        anchors.left: parent.left
        anchors.leftMargin: 5
        spacing: 5

        Repeater {
            model: 4

            Rectangle {
                width: 50
                height: 50
                color: getRectColor()

                function getRectColor() {
                    if (Positioner.index === 0)
                        return 'red'
                    else if (Positioner.index === 1)
                        return 'yellow'
                    else if (Positioner.index === 2)
                        return 'blue'
                    else
                        return 'green'
                }
            }
        }
    }

    Grid {
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 5
        anchors.right: parent.right
        anchors.rightMargin: 5
        columns: 4
        spacing: 5

        Repeater {
            model: 14
            Rectangle {
                width: 50
                height: 50
                color: getRectColor()

                function getRectColor() {
                    if (Positioner.index % 5 === 0)
                        return 'red'
                    else if (Positioner.index % 5 === 1)
                        return 'yellow'
                    else if (Positioner.index % 5 === 2)
                        return 'blue'
                    else if (Positioner.index % 5 === 3)
                        return '#00FFFF'
                    else
                        return 'green'
                }
            }
        }
    }

    Flow {
        anchors.top: parent.top
        anchors.topMargin: 5
        anchors.right: parent.right
        anchors.rightMargin: 5
        width: 200
        spacing: 5

        Repeater {
            model: 14
            Rectangle {
                width: 50
                height: 50
                color: getRectColor()

                function getRectColor() {
                    if (Positioner.index % 5 === 0)
                        return 'red'
                    else if (Positioner.index % 5 === 1)
                        return 'yellow'
                    else if (Positioner.index % 5 === 2)
                        return 'blue'
                    else if (Positioner.index % 5 === 3)
                        return '#00FFFF'
                    else
                        return 'green'
                }
            }
        }
    }
}

3. 布局管理器

布局管理器与Qt QWidget中的布局类似,它与定位器布局之间的不同就是,布局管理器会自动调节界面的尺寸适应界面的大小。要使用布局管理器, 需要导入Layout模块,使用如下语句import QtQuick.Layouts 1.1, 主要常用的布局管理器有RowLayoutColumnLayoutGridLayout

下面以RowLayout为例说明一下Layout的一些属性;

  • Layout.minimumWidth
  • Layout.minimumHeight
  • Layout.preferredWidth
  • Layout.preferredHeight
  • Layout.maximumWidth
  • Layout.maximumHeight
  • Layout.fillWidth
  • Layout.fillHeight
  • Layout.alignment

Layout.minimumWidthLayout.minimumHeight*Layout.maximumWidthLayout.maximumHeight指明最大最小 宽度和高度;当Layout.fillWidthtrue时, Item的宽度为尽可能为最大,为false时,Item的宽度大小为Layout.preferredWidthLayout.fillHeight的用法同Layout.fillWidth类似。 Layout.alignment表示布局的Item的对齐方向。

对于GridLayout来讲,flow可以指定排列方式, rowscolumns可以指定行数和列数, Layout.columnSpan所跨的列数,Layout.rowSpan所跨的行数

下面是一个关于布局管理器的示例,效果如下:

完整代码如下:

import QtQuick 2.0
import QtQuick.Window 2.0
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1

Window {
    id: mianWindow

    width: 800
    height: 600
    visible: true

    Rectangle {
        anchors.fill: parent
        color: '#505050'

        RowLayout {
            anchors.top: parent.top
            anchors.topMargin: 5
            anchors.left: parent.left
            anchors.leftMargin: 5
            width: 500

            Rectangle {
                color: 'teal'
                Layout.fillWidth: true
                Layout.minimumWidth: 50
                Layout.preferredWidth: 100
                Layout.maximumWidth: 200
                Layout.minimumHeight: 150
                Text {
                    anchors.centerIn: parent
                    text: parent.width + 'x' + parent.height
                }
            }

            Rectangle {
                color: 'plum'
                Layout.fillWidth: false
                Layout.minimumWidth: 100
                Layout.preferredWidth: 200
                Layout.preferredHeight: 100
                Text {
                    anchors.centerIn: parent
                    text: parent.width + 'x' + parent.height
                }
            }
        }

        ColumnLayout {
            anchors.bottom: parent.bottom
            anchors.bottomMargin: 5
            anchors.left: parent.left
            anchors.leftMargin: 5
            height: 300

            Rectangle {
                color: 'teal'
                Layout.fillHeight: true
                Layout.minimumHeight: 50
                Layout.preferredWidth: 200
                Layout.preferredHeight: 100
                Layout.maximumWidth: 250
                Layout.maximumHeight: 150
                Text {
                    anchors.centerIn: parent
                    text: parent.width + 'x' + parent.height
                }
            }

            Rectangle {
                color: 'plum'
                Layout.fillHeight: false
                Layout.minimumWidth: 100
                Layout.preferredWidth: 100
                Layout.preferredHeight: 120
                //horizontalCenter: parent.horizontalCenter
                Text {
                    anchors.centerIn: parent
                    text: parent.width + 'x' + parent.height
                }
            }
        }

        GridLayout {
            anchors.bottom: parent.bottom
            anchors.bottomMargin: 5
            anchors.right: parent.right
            anchors.rightMargin: 5
            flow: GridLayout.LeftToRight
            height: 200

            columns: 3

            Rectangle {
                color: 'red'
                Layout.columnSpan: 2
                Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
                width: 50
                height: 50
            }

            Rectangle {
                color: 'yellow'
                width: 50
                height: 50
            }

            Rectangle {
                color: 'blue'
                Layout.rowSpan: 2
                width: 50
                height: 50
            }

            Rectangle {
                color: 'green'
                width: 50
                height: 50
            }
        }
    }
}
不会飞的纸飞机
扫一扫二维码,了解我的更多动态。

下一篇文章:基于QGraphicsView的简易画板EasyCanvas -- 第一版