zoukankan      html  css  js  c++  java
  • 13.Quick QML-RowLayout、ColumnLayout、GridLayout布局管理器介绍、并通过GridLayout设计的简易网站导航界面

    上章我们学习了:12.Quick QML-QML 布局(Row、Column、Grid、Flow和嵌套布局) 、Repeater对象,本章我们继续来学习布局管理器

    1.RowLayout、ColumnLayout、GridLayout布局管理器介绍

    RowLayout、ColumnLayout、GridLayout布局管理器和Row、Column、Grid布局器非常相似,但是在布局管理器里就不支持使用Positioner附加属性了.
    并且在布局器的基础上,为每个item提供了下面几个附加属性:

    • Layout.minimumWidth
    • Layout.minimumHeight
    • Layout.maximumWidth
    • Layout.maximumHeight
    • Layout.preferredWidth  : 首选宽度。如果未设置,那么布局将使用隐式宽度(implicitWidth)。默认值为-1。
    • Layout.preferredHeight : 首选高度。如果未设置,那么布局将使用隐式高度。默认值为-1。
    • Layout.fillWidth :  bool类型,默认为false,如果为true,那么该item的宽度会尽可能宽(可以伸缩),如果为false,那么宽度的优先级选择为: Layout.preferredWidth > implicitWidth > Layout.minimumWidth
    • Layout.fillHeight :  和Layout.fillWidth一样,设置高度是否可以伸缩
    • Layout.alignment : 设置item在网格里的对齐方式,默认值为" Qt.AlignVCenter | Qt.AlignLeft "
    • Layout.margins : 设置item的外边距
    • Layout.leftMargin
    • Layout.rightMargin
    • Layout.topMargin
    • Layout.bottomMargin

    由于RowLayout和ColumnLayout其实本质就是单行或者单列的GridLayout.所以我们以GridLayout为例讲解.

    2. GridLayout布局管理器介绍
    它的属性如下所示:

    • rowSpacing : real,设置每行的间隔,默认值为5
    • columnSpacing : real,设置每列的间隔,默认值为5
    • rows : int,默认值为-1,用来设置网格有多少行
    • columns : int,默认值为-1,用来设置网格有多少列
    • flow : enumeration,流布局,取值有:
      • GridLayout.LeftToRight: 从左往右排列,如果剩余的宽度不足,则排下一行(默认值)
      • Flow.TopToBottom: 从上往下排列,如果剩余的宽度不足,则排下一列.
    • layoutDirection : enumeration,布局方向,取值有:
      • Qt.LeftToRight (default) : 默认方向
      • Qt.RightToLeft : 左右取反方向(比如布局顺序为123,将会变为321)

    并且GridLayout在RowLayout和ColumnLayout的附加属性基础上,还额外增加了下面几个附加属性:

    • Layout.row : 指定item在网格中的行位置。默认值为0,由布局为项目自动分配单元格。
    • Layout.column: 指定item在网格中的列位置。默认值为0,由布局为项目自动分配单元格。
    • Layout.rowSpan : 指定item在网格中的行跨度,默认值为1。
    • Layout.columnSpan : 指定item在网格中的列跨度,默认值为1。

    3.flow 和layoutDirection介绍
    flow表示每个网格的排列方向.
    layoutDirection表示布局方向,如果layoutDirection = Qt.RightToLeft,那么就会将水平方向的排列进行水平镜像.
    比如默认显示的是:

    设置layoutDirection = Qt.RightToLeft后,那么显示的将会是:

    示例代码如下所示:

    Window {
         320;
        height: 240;
        visible: true;
    
        GridLayout{
              id: grid
              rows: 3
              flow: GridLayout.LeftToRight
              layoutDirection: Qt.LeftToRight
              anchors.fill: parent
              Repeater {
                  model: 3
                  Rectangle {
                      color: "yellow"
                      Layout.alignment: Qt.AlignLeft   // 水平靠左
                      Layout.fillHeight: true       // 设置高度可伸缩
                      Layout.preferredWidth: 40
                      Layout.preferredHeight: 70
                      Text {
                          anchors.centerIn: parent
                          font.pixelSize: 14
                          text: "水平靠左"+index
                      }
                      Component.onCompleted: {
    
                          console.log(Layout.row +","+ Layout.column)
    
                      }
                  }
              }
    
              Repeater {
                  model: 3
                  Rectangle {
                      Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
                      color: "green"
                      Layout.fillHeight: true       // 设置高度可伸缩
                      Layout.preferredWidth: 40
                      Layout.preferredHeight: 70
                      Text {
                          anchors.centerIn: parent
                          font.pixelSize: 14
                          text: "水平靠右"+index
                      }
                  }
              }
        }
    
    }

    设置"flow: GridLayout.LeftToRight"、"layoutDirection: Qt.LeftToRight"的时候,效果如下所示:

    设置"flow: GridLayout.LeftToRight"、"layoutDirection: Qt.RightToLeft"的时候,效果如下所示(水平方向取反,原来的顺序是012,变成了210,并且每个item的水平对齐方向也取反了):

    设置"flow: GridLayout.TopToBottom"、"layoutDirection: Qt.LeftToRight"的时候,效果如下所示:

    设置"flow: GridLayout.TopToBottom"、"layoutDirection: Qt. RightToLeft"的时候,效果如下所示(先绘制一列"yellow"、再绘制一列"green",然后再进行水平镜像变换):

    4.Layout.rowSpan和Layout.columnSpan介绍
    用来指定item在网格中显示的行跨度和列跨度,默认值为1.
    我们以每个网格的宽高为1为例,比如当前item默认显示的区域是在(0,1)~(1,2)上:

    000
    X00
    000

    如果我们设置columnSpan=3, rowSpan=2,那么当前item显示的区域将是在(0,1)~(3,3)上面,也就是说列跨度(宽度)占了3个网格,行宽度(高度)占了2个网格,将会变为:

    000
    XXX
    XXX
    • 注意 : 使用跨度之前,必须设置Layout.fillWidthLayout.fillHeight为true

    示例如下所示:

    Window {
         320;
        height: 240;
        visible: true;
    
        GridLayout{
              id: grid
              columns: 3
              anchors.fill: parent
    
              Repeater {
                model: 3
                Rectangle {               // 显示区域
                    color: "green"
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                }
    
              }
              Rectangle {               // 显示区域
                  color: "steelblue"
                  Layout.fillWidth: true
                  Layout.fillHeight: true
                  Layout.columnSpan: 3
                  Layout.rowSpan: 2
              }
        }
    }

    效果如下所示:

    注意:

       Layout.rowSpan和Layout.columnSpan有个bug,那就是如果我们定义的某一列的所有item如果都带了相同的Layout.columnSpan值,那么是没有效果的,示例如下所示:

    GridLayout{
                  id: grid
                  columns: 4
                  anchors.fill: parent
    
                  Rectangle {
                      color: "steelblue"
                      Layout.fillWidth: true
                      Layout.fillHeight: true
                  }
                  Rectangle {
                      color: "steelblue"
                      Layout.fillWidth: true
                      Layout.fillHeight: true
                  }
                  Rectangle {               // yellow区域
                      color: "yellow"
                      Layout.fillWidth: true
                      Layout.fillHeight: true
                      Layout.columnSpan: 2
                  }
                  Rectangle {               
                      color: "steelblue"
                      Layout.fillWidth: true
                      Layout.fillHeight: true
                      Layout.columnSpan: 2
                  }
                  Rectangle {               // yellow区域
                      color: "yellow"
                      Layout.fillWidth: true
                      Layout.fillHeight: true
                      Layout.columnSpan: 2
                  }
            }

    效果如下所示:

    可以看到我们设置yellow块的是Layout.columnSpan: 2,但是显示的效果并没有跨列.这是因为我们最后一列没有放置任何东西,所以它的位置被前面3列给均匀平摊了.


    5.简易的网站导航界面设计
    接下来我们便来通过GridLayout来做一个简易的网站导航界面,并支持自适应界面.当我们点击其中的某个按钮,就会打开浏览器跳到对应的网站上.
    界面如下所示:

     效果如下所示(支持自适应):

    下载链接: https://download.csdn.net/download/qq_37997682/16796542

    首先创建BoxButton组件:

    import QtQuick 2.14
    import QtQuick.Controls 2.0
    
    Button {
        id: btn
        property var backColor: "#7BCBEB"       
        property var iconUrl: ""                
        property var textSize: 12              
        property var openUrl: ""               
    
        text: "button"
        implicitWidth: 60
        implicitHeight: 60
        hoverEnabled: true
        contentItem: Label {                    // 设置文本,文本位于左下角
            id: btnForeground
            text: parent.text
            font.family: "Microsoft Yahei"
            font.pixelSize: textSize
            color: "#FFFFFF"
            horizontalAlignment: Text.AlignLeft
            verticalAlignment: Text.AlignBottom
        }
        background: Rectangle {              
            id: btnBack
            color: backColor
            border.color: backColor
            border. 2
    
        }
    
        Image{                              // 设置图标,图标位于右上角
            source: iconUrl
            anchors.right: parent.right
            anchors.top: parent.top
            smooth: true
            anchors.rightMargin: parent.width * 0.01
            anchors.topMargin: parent.height * 0.03
            fillMode: Image.PreserveAspectFit
            height: parent.height * 0.4
             parent.width * 0.8
            mipmap: true
        }
    
        onDownChanged: {
            btnBack.color = down ? Qt.lighter(backColor, 0.9) : backColor    
            btnBack.border.color = backColor
        }
        onHoveredChanged: {
            btnBack.color = hovered ? Qt.lighter(backColor, 1.09) : backColor 
            btnBack.border.color = hovered ? Qt.lighter(backColor, 1.24) : backColor
    
        }
    
        onClicked: {
            if (openUrl.length > 0) {
                Qt.openUrlExternally(openUrl);
            }
    
        }
    }

    然后在main.cpp来生成组件:

    import QtQuick 2.14
    import QtQuick.Window 2.0
    import QtQuick.Layouts 1.14
    Window {
         800;
        height: 520;
        visible: true;
        color: "#506168"
    
        property var btnTextSize: Math.min(grid.height,grid.width) * 0.04
    
        function boxButtonInit(item,color,text,icon,url) {
            item.Layout.fillWidth = true
            item.Layout.fillHeight = true
            item.backColor = color
            item.text = text
            item.iconUrl = icon
            item.openUrl = url
    
        }
    
        GridLayout {
              id: grid
              columns: 4
              anchors.fill: parent
              anchors.margins: 15
              rowSpacing: 8
              columnSpacing: 8
              BoxButton {
                  textSize : btnTextSize
                  Component.onCompleted: boxButtonInit(this,
                                                       "#297FEC",
                                                       "号码归属地",
                                                       "qrc:/phone.png",
                                                       "https://www.ip138.com/sj/");
              }
              BoxButton {
                  textSize : btnTextSize
                  Component.onCompleted: boxButtonInit(this,
                                                       "#5B39B4",
                                                       "在线翻译",
                                                       "qrc:/translate.png",
                                                       "https://fanyi.baidu.com/");
              }
              BoxButton {
                  textSize : btnTextSize
                  Component.onCompleted: boxButtonInit(this,
                                                       "#00991A",
                                                       "百度一下",
                                                       "qrc:/baidu.png",
                                                       "https://www.baidu.com/");
              }
              BoxButton {
                  textSize : btnTextSize
                  Component.onCompleted: boxButtonInit(this,
                                                       "#C4204C",
                                                       "Google",
                                                       "qrc:/google.png",
                                                       "https://www.google.cn/");
              }
              BoxButton {
                  Layout.columnSpan: 2
                  textSize : btnTextSize
                  Component.onCompleted: boxButtonInit(this,
                                                       "#D74E2C",
                                                       "淘宝购物",
                                                       "qrc:/tb.png",
                                                       "https://www.taobao.com/");
    
              }
              BoxButton {
                  Layout.columnSpan: 2
                  Layout.rowSpan: 2
                  textSize : btnTextSize
                  Component.onCompleted: boxButtonInit(this,
                                                       "#297FEC",
                                                       "爱奇艺",
                                                       "qrc:/aiyiqi.png",
                                                       "https://www.iqiyi.com/");
              }
    
              BoxButton {
                  textSize : btnTextSize
                  Component.onCompleted: boxButtonInit(this,
                                                       "#4CC8EF",
                                                       "新浪微博",
                                                       "qrc:/weibo.png",
                                                       "https://weibo.com/");
              }
              BoxButton {
                  textSize : btnTextSize
                  Component.onCompleted: boxButtonInit(this,
                                                       "#2B965E",
                                                       "京东商城",
                                                       "qrc:/jd.png",
                                                       "https://www.jd.com/");
              }
        }
    
        Component.onCompleted: {
            x = Screen.desktopAvailableWidth / 2 - width / 2
            y = Screen.desktopAvailableHeight / 2 - height / 2
        }
    
    }

     


    人间有真情,人间有真爱。

    如果您喜欢这里,感觉对你有帮助,并且有多余的软妹币的话,不妨投个食吧,赞赏的时候,留下美句和你的博客地址哦~   戳这里看谁投食了


查看全文
  • 相关阅读:
    Mysql基本操作、C++Mysql简单应用、PythonMysql简单应用
    Mysql安装步骤
    MVC EF 移除建表时自动加上s的复数形式
    MVC autofac 属性注入
    layui table默认选中指定行
    js slice 假分页
    sql 根据身份证号码计算年龄
    pointer-events: none
    /Date(1555554794000)/ 转换为日期格式
    sql 查询字段如果为null 则返回0的写法
  • 原文地址:https://www.cnblogs.com/lifexy/p/14686618.html
  • Copyright © 2011-2022 走看看