PySide2学习总结(十一)QML布局

QML可以直接设置X与Y坐标的值来进行布局,但这种做法不利于布局的调整和代码的维护,因而更推荐采用定位器、布局管理器以及锚布局来完成QML布局。
QML常用的定位器有:Row, Column, Grid以及Flow;常用布局管理器有RowLayout, ColumnLayout, GridLayout,以及Anchor(锚布局)。

定位器

Row

QML 中的 Row 元素会将其子控件都排列在同一行,相互不重叠。可以使用spacing 属性来定义子控件之间的距离。

Column

QML 中的 Column元素会将其子控件都排列在同一行,相互不重叠。可以使用spacing 属性来定义子控件之间的距离。

Grid

QML 中的 Grid元素会将其子控件都均匀地排列在一个网格内,相互不重叠,每一个子控件都被放置在一个网格单元的(0,0)位置,也就是左上角。Grid的rows 和columns属性定义网格的行数和列数,列数默认是4。
可以使用Grid的spacing 属性来定义网格单元之间的距离,这里注意水平和垂直方向的spacing都是一样的。

Flow

与Grid类似不同之处在于,Flow不用指定行数和列数,他会计算Item的尺寸然后与自身尺寸比较自动换行。

编程示例

将以上定位器结合起来编辑代码如下:

import QtQuick 2.7
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.1


ApplicationWindow {
    id: _window

    // 窗口标题设置
    title: "Test App"
    width: 400
    height: 400

    // Window默认不可见,需要进行设置为可见
    visible: true

    menuBar: MenuBar {
        Menu {
            title: "File"
            Action {
            text: "New"
            shortcut: "Ctrl+N"
            }
            Action {
                text: "Open"
                shortcut: "Ctrl+O"
            }
        }
        Menu {
            title: "Help"
            Action {
                text: "About App"
                shortcut: "F1"
            }
        }
    }

    header: ToolBar {
        // 横向
        RowLayout {
            ToolButton {
                // 设置提示文字
                ToolTip.visible: hovered
                ToolTip.text: qsTr("Create new File")
                // 设置命令图标
                icon.name: "New"
                icon.source: "../img/new.png"
            }
            ToolButton {
                ToolTip.visible: hovered
                ToolTip.text: qsTr("Open File")
                icon.name: "Open"
                icon.source: "../img/open.png"
            }
        }
    }

    Grid {
        columns: 3
        spacing: 5
        Rectangle { color: "red"; width: 50; height: 50 }

        Row {
            spacing: 0
            Rectangle { color: "green"; width: 50; height: 50 }
            Rectangle { color: "gray"; width:50; height: 50 }
        }

        Column {
            spacing: 0
            Rectangle { color: "yellow"; width: 50; height: 50 }
            Rectangle { color: "black"; width: 50; height: 50 }
            Rectangle { color: "blue"; width:50; height: 50 }
        }

        Rectangle { color: "brown"; width: 50; height: 50 }
        
        Flow {
            width: 200
            spacing: 5

            Repeater {
                model: 7
                Rectangle {
                    width: 50
                    height: 50
                    color: 'green'
                }
            }
        }
    }
}

运行效果如图:
PySide2学习总结(十一)QML布局_第1张图片

布局管理器

布局管理器与定位器布局之间的不同就是,布局管理器会自动调节界面的尺寸适应界面的大小。要使用布局管理器,需要导入Layout模块:

import QtQuick.Layouts 1.1

GridLayout

GridLayout使用columns、rows属性将空间分成若干单元格,使用columnSpacing、rowSpacing确立单元格之间的间隔。
而GridLayout内部元素的大小由Layout.fillWidth、Layout.fillHeight以及Layout.preferredWidth、Layout.preferredHeight来确定,如Layout.fillWidth:true表示宽度填充整个单元格,Layout.preferredWidth则指定一个建议宽度。
Layout.minimumWidth、Layout.minimumHeight、Layout.maximumWidth、Layout.maximumHeight指明最大最小宽度和高度。
Layout.row、Layout.column确定内部元素处于哪个单元格。

RowLayout和ColumnLayout

ColumnLayout、RowLayout只是GridLayout的一种特例,ColumnLayout表示只有一列,RowLayout表示只有一行。

编程示例

在main.qml中编辑代码如下:

import QtQuick 2.7
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.1


ApplicationWindow {
    id: _window

    // 窗口标题设置
    title: "Test App"
    width: 400
    height: 400

    // Window默认不可见,需要进行设置为可见
    visible: true

    menuBar: MenuBar {
        Menu {
            title: "File"
            Action {
            text: "New"
            shortcut: "Ctrl+N"
            }
            Action {
                text: "Open"
                shortcut: "Ctrl+O"
            }
        }
        Menu {
            title: "Help"
            Action {
                text: "About App"
                shortcut: "F1"
            }
        }
    }

    header: ToolBar {
        // 横向
        RowLayout {
            ToolButton {
                // 设置提示文字
                ToolTip.visible: hovered
                ToolTip.text: qsTr("Create new File")
                // 设置命令图标
                icon.name: "New"
                icon.source: "../img/new.png"
            }
            ToolButton {
                ToolTip.visible: hovered
                ToolTip.text: qsTr("Open File")
                icon.name: "Open"
                icon.source: "../img/open.png"
            }
        }
    }

    GridLayout{
        
        // 行列数量分别为2
        columns: 2;
        rows:2;
        // 填充父元素,外边距为5
        anchors.fill: parent;
        anchors.margins: 5;
        // 行列子控件之间的距离
        columnSpacing: 5;
        rowSpacing: 5;

        Rectangle{
            color: "red";
            Layout.preferredWidth: 200;
            Layout.preferredHeight: 150;
        }

        ColumnLayout {
            spacing: 0
            Rectangle {
                color: "red";
                Layout.preferredWidth: 200;
                Layout.preferredHeight: 75;
            }
            Rectangle {
                color: "blue";
                Layout.preferredWidth: 200;
                Layout.preferredHeight: 75;
            }
        }

        RowLayout {
            spacing: 0
            Rectangle {
                color: "red";
                Layout.preferredWidth: 100;
                Layout.preferredHeight: 150;
            }
            Rectangle {
                color: "green";
                Layout.preferredWidth: 100;
                Layout.preferredHeight: 150;
            }
        }

        Rectangle{
            color: "yellow";
            Layout.preferredWidth: 200;
            Layout.preferredHeight: 150;
        }
    }

}

运行效果如图:
PySide2学习总结(十一)QML布局_第2张图片

Anchor(锚布局)

锚布局可以指定一个元素与其他元素的关系来确定其在界面中的位置,但只允许对一个item的邻居和直接父元素使用anchor定义。
每一个item 都可以被认为具有 7 条隐藏的“anchor lines(锚线)":left、 horizontalCenter、 right、 top、 verticalCenter、baseline、以及bottom。其中baseline是指的文本所在的线,如果item没有文字的话baseline和top的位置是相同的。
PySide2学习总结(十一)QML布局_第3张图片
除此之外,Anchor系统还提供了margins 和offsets。margins 是指一个item和外部元素之间所留有的空间,而offsets 则可以通过使用 center anchor lines来进行布局。
PySide2学习总结(十一)QML布局_第4张图片

编程示例

在main.qml中编辑代码如下:

import QtQuick 2.7
import QtQuick.Controls 2.3
import QtQuick.Controls 1.4 as Controls1
import QtQuick.Layouts 1.1


ApplicationWindow {
    id: _window

    // 窗口标题设置
    title: "Test App"
    width: 400
    height: 400

    // Window默认不可见,需要进行设置为可见
    visible: true

    menuBar: MenuBar {
        Menu {
            title: "File"
            Action {
            text: "New"
            shortcut: "Ctrl+N"
            }
            Action {
                text: "Open"
                shortcut: "Ctrl+O"
            }
        }
        Menu {
            title: "Help"
            Action {
                text: "About App"
                shortcut: "F1"
            }
        }
    }

    header: ToolBar {
        // 横向
        RowLayout {
            ToolButton {
                // 设置提示文字
                ToolTip.visible: hovered
                ToolTip.text: qsTr("Create new File")
                // 设置命令图标
                icon.name: "New"
                icon.source: "../img/new.png"
            }
            ToolButton {
                ToolTip.visible: hovered
                ToolTip.text: qsTr("Open File")
                icon.name: "Open"
                icon.source: "../img/open.png"
            }
        }
    }

    Rectangle{
        id: rec001
        height: 80
        width: 80
        color: "yellow"
        //锚定位在父元素的中间
        anchors.centerIn: parent
    }
    Rectangle{
        id: rec010
        height: 80
        width: 80
        color: "red"
        // right与rec001的left对齐
        anchors.right: rec001.left
        // 右侧外边距
        anchors.rightMargin: 40
        // verticalCenter与rec001的对齐
        anchors.verticalCenter: rec001.verticalCenter
        // verticalCenter偏移量
        anchors.verticalCenterOffset: 0
    }

    Rectangle{
        id: rec011
        height: 80
        width: 80
        color: "green"
        anchors.left: rec001.right
        anchors.leftMargin: 40
        anchors.verticalCenter: rec001.verticalCenter
        anchors.verticalCenterOffset: 0
    }
    Rectangle{
        id: rec100
        height: 80
        width: 80
        color: "cyan"
        anchors.bottomMargin: 40
        anchors.horizontalCenter: rec001.horizontalCenter
        anchors.horizontalCenterOffset: 0
    }
    Rectangle{
        id: rec101
        height: 80
        width: 80
        color: "blue"
        anchors.top: rec001.bottom
        anchors.topMargin: 40
        anchors.horizontalCenter: rec001.horizontalCenter
        anchors.horizontalCenterOffset: 0
    }

}

运行效果如图:
PySide2学习总结(十一)QML布局_第5张图片

注意

  1. 水平方向的的锚线与垂直方向的锚线之间不能设置对齐,比如:

anchors.horizontalCenter: rec001.verticalCenter

会出现报错如下:
在这里插入图片描述

  1. 在设置边距时,可以选择为leftMargin, topMargin等一一赋值,也可以直接使用margins为所有边缘赋值,但后者优先级低于前者。

SplitView

SplitView用于提供带切分条的布局。
在main.qml中编辑代码如下:

import QtQuick 2.7
import QtQuick.Controls 2.3
import QtQuick.Controls 1.4 as Controls1
import QtQuick.Layouts 1.1


ApplicationWindow {
    id: _window

    // 窗口标题设置
    title: "Test App"
    width: 400
    height: 400

    // Window默认不可见,需要进行设置为可见
    visible: true

    menuBar: MenuBar {
        Menu {
            title: "File"
            Action {
            text: "New"
            shortcut: "Ctrl+N"
            }
            Action {
                text: "Open"
                shortcut: "Ctrl+O"
            }
        }
        Menu {
            title: "Help"
            Action {
                text: "About App"
                shortcut: "F1"
            }
        }
    }

    header: ToolBar {
        // 横向
        RowLayout {
            ToolButton {
                // 设置提示文字
                ToolTip.visible: hovered
                ToolTip.text: qsTr("Create new File")
                // 设置命令图标
                icon.name: "New"
                icon.source: "../img/new.png"
            }
            ToolButton {
                ToolTip.visible: hovered
                ToolTip.text: qsTr("Open File")
                icon.name: "Open"
                icon.source: "../img/open.png"
            }
        }
    }

    Controls1.SplitView{
        anchors.fill:parent;
        orientation: Qt.Horizontal;
        Rectangle{
            id:rect1;
            width:100;
            color:"red";
        }
        Rectangle{
            id:rect2;
            Layout.fillWidth: true;
            Layout.minimumWidth: 50;
            color:"blue";
        }
        Rectangle{
            id:rect3;
            width:100;
            color:"green";
        }
    }

}

运行效果如图:
PySide2学习总结(十一)QML布局_第6张图片

你可能感兴趣的:(Python,PySide2学习总结)