定位器

Row

Row:默认将子项从左往右水平排列

  1. 示例:
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts

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

    Row {
        anchors.centerIn: parent
        spacing: 12
        Rectangle {
            width: 100
            height: 100
            color: "#fbe7e7"
            Text {
                anchors.centerIn: parent
                text: "A"
                font.pixelSize:  12
            }
        }
        Rectangle {
            width: 100
            height: 100
            color: "#789d65"
            Text {
                anchors.centerIn: parent
                text: "B"
                font.pixelSize:  12
            }
        }
        Rectangle {
            width: 100
            height: 100
            color: "#ff0000"
            Text {
                anchors.centerIn: parent
                text: "C"
                font.pixelSize:  12
            }
        }
    }
}

  1. 效果
    image
Column

column将子项从上到下排列

  1. 示例程序:
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts

Window {
    width: 600
    height: 400
    visible: true
    title: "test"

    Column {
        anchors.centerIn: parent
        spacing: 24
        Button {
            width: 120
            height: 60
            text: "按钮"
        }
        Button {
            width: 120
            height: 60
            text: "按钮"
        }
        Button {
            width: 120
            height: 60
            text: "按钮"
        }
    }
}

  1. 效果
    image
Flow

支持自动换行

Grid

默认按照行优先排列,形成网格

  1. 示例程序:
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts

Window {
    width: 600
    height: 800
    visible: true
    title: "test"

    Grid {
        columns: 3
        spacing: 4
        anchors.centerIn: parent
        // 列优先
        // flow: Grid.TopToBottom
        Repeater {
            model: 4
            Rectangle {
                width:  100
                height: 100
                color: Qt.rgba(Math.random(),Math.random(),Math.random(),1)
                radius: 5
                Text {
                    text: index + 1
                    anchors.centerIn: parent
                }
            }
        }
    }
}

  1. 效果:
    image

锚布局

anchors属性集:将元素与父元素或者其他元素进行对齐

  1. 示例程序:
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts

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

   Item {
       id: item
       width: 100
       height: 100
       // 水平居中
       // anchors.horizontalCenter: parent.horizontalCenter
       // 垂直居中
       //anchors.verticalCenter: parent.verticalCenter
       // 正中间
       //anchors.centerIn: parent
       // 右上角
       // anchors.right: parent.right
       // 右下角
        anchors.bottom: parent.bottom
        anchors.right: parent.right
       Rectangle {
           anchors.fill: parent
           color: "#7ba167"
       }
   }
}

布局管理器

布局管理器有RowLayout,ColumnLayout,GridLayout等。常用属性有:

  1. Layout.fillWidth:是否水平拉伸以填充剩余空间
  2. Layout.fillHeight:是否垂直拉伸以填充剩余空间
  3. Layout.preferredWidth:期望宽度
  4. Layout.preferredHeight:期望高度
  5. Layout.minimumWidth:最小宽度
  6. Layout.maximumWidth:最大宽度
  7. Layout.margins:外边距
  8. Layout.alignment:在布局单元内的对齐方式,在布局管理器的子元素中使用
RowLayout
  1. 示例程序:
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts

Window {
    width: 600
    height: 400
    visible: true
    title: "test"

    RowLayout {
        width: parent.width
        height: 50
        spacing: 10

        Rectangle {
            // 填充父布局的剩余空间
            Layout.fillWidth: true
            // 期望宽度(建议值),通常和Layout.fillWidth一起使用,作为权重
            Layout.preferredWidth: 1  // 权重1
            height: parent.height
            color: "#1794c9"
            Text { anchors.centerIn: parent; text: "1/3" }
        }

        Rectangle {
            Layout.fillWidth: true
            Layout.preferredWidth: 2  // 权重2(宽度是左边的2倍)
            height: parent.height
            color: "#27ae60"
            Text { anchors.centerIn: parent; text: "2/3" }
        }
    }
}

  1. 效果如下:
    image
ColumnLayout

单列垂直布局

GridLayout

网格布局容器,它可以将子元素排列成行和列的矩阵形式,即多行多列网格布局

  1. 示例:实现一个简单的登录界面
GridLayout {
    columns: 2
    anchors.centerIn: parent
    rowSpacing: 15
    columnSpacing: 20
    Label {
       text: "用户名:"
       Layout.alignment: Qt.AlignRight
       font.pixelSize: 14
   }
   TextField {
       id: username
       placeholderText: "请输入用户名"
       Layout.fillWidth: true
       Layout.preferredWidth: 200
   }

   Label {
       text: "密码:"
       Layout.alignment: Qt.AlignRight
       font.pixelSize: 14
   }
   TextField {
       id: password
       echoMode: TextField.Password
       placeholderText: "请输入密码"
       Layout.fillWidth: true
   }

   Button {
       text: "登录"
       Layout.columnSpan: 2 // 占据两列
       Layout.fillWidth: true
       Layout.preferredHeight: 35
       onClicked: console.log("登录:", username.text, password.text)
   }
}
  1. 效果如下:
    image

调试

  1. 可以在容器的onCompleted方法中打印信息
Component.onCompleted: {
    console.log("ColumnLayout 宽度:", width)
    console.log("父元素宽度:", parent.width)
    console.log("是否占满:", width === parent.width)
}
  1. 观察Item,Rectangle等容器的颜色
Item {
    id: root
    width: 800
    height: 600
    Rectangle {
        anchors.fill: parent
        color:  "red"
    }
}

一些实践

  1. 对于布局管理器的子元素,使用Layout属性进行元素的定位,而不是使用anchors
  2. 对于布局管理器内的子元素,子元素之间的间隙不一致,可以使用空的Item元素进行占位。而对于自身布局管理器,如果其父元素不是布局管理器,则使用anchors进行定位。比如说:
RowLayout {
    anchors.left: parent.left
    anchors.top:  parent.top
    width:600
    height: 100
    Rectangle {
        Layout.preferredWidth: 100
        Layout.fillWidth: true
        Layout.preferredHeight: 100
        color:  "green"
    }
    Item {
        Layout.preferredWidth: 60
        Layout.fillWidth: false
    }

    Rectangle {
        Layout.preferredWidth: 100
        Layout.fillWidth: true
        Layout.preferredHeight: 100
        color:  "red"
    }
    Item {
        Layout.preferredWidth: 10
        Layout.fillWidth: false
    }
    Rectangle {
        Layout.preferredWidth: 100
        Layout.fillWidth: true
        Layout.preferredHeight: 100
        color:  "blue"
    }
}
  1. Item作为不可见元素,其visible可以用来控制一些页面元素的显示和隐藏
  2. 对于页面编写,需要注意字体的相关属性:
Text {
  color: ""      // 字体颜色
  font.family:"" // 哪一种字体
  font.weight:  Font.DemiBold or Font.Normal // 字重,DemiBold表示字重为600,Normal表示字重为400
  font.pixSize:字体大小
  lineHeightMode: Text.FixedHeight
  lineHeight: 54  // 行高
  horizontalAlignment: Text.AlignHCenter  // 水平居中
  verticalAlignment: Text.AlignVCenter    // 垂直居中
}
  1. 使用定位器对子元素进行定位,可以使用leftPadding,rightPadding,topPadding,bottomPadding这些属性设置内边距