注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

沙漠里de烟雨

原创分享,禁止转载

 
 
 

日志

 
 

QML 如何动态布局  

2017-05-18 02:21:18|  分类: QT5.x与QML |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
GridLayout与Flow配合使用,即可巧妙的实现水平垂直布局

为便于理解,特从工程中摘下一些代码片段,由于上下文的关系,这里便没有特意剔除一些无相关代码,相信您是可以理出头绪的……

MenuBtnContainer.qml =>

import QtQuick 2.0
import QtQuick.Layouts 1.1
import "."

GridLayout
{
    id: root
    columnSpacing: 0
    rowSpacing: 0

    flow: GridLayout.LeftToRight
    layoutDirection: Qt.LeftToRight

    //signals;
    signal showTooltip(var tip);
    signal hideTooltip();

    //private;
    property var btnArray2: [] //二维数组;第一维为flow,第二维为btn;

    Component
    {
        id: ctrlComp
        MenuBtnComp
        {//这里为自定义的控件;
            id: comp
            width: root.width
            height: root.height
            onHoveredChanged: root.panelHovered = comp.hovered
            onShowTooltip: root.showTooltip(tip);
            onHideTooltip: root.hideTooltip();
        }
    }

    Component
    {
        id: top2bottomComp
        Flow
        { //从上到下方向,即垂直布局;
            layoutDirection:Qt.LeftToRight
            flow:Flow.TopToBottom   //"vertical"
        }
    }

    Component
    {
        id: left2rightComp
        Flow
        {//从左至右方向,即水平布局
            layoutDirection:Qt.LeftToRight
            flow:Flow.LeftToRight   //"horizontal"
        }
    }

    function clear()
    {
        btnArray2 = [];
    }

    function myPrint()
    {
        for(var i=0;i<btnArray2.length;i++)
        {
            var subArray = btnArray2[i];
            for(var j=0;j<subArray.length;j++)
            {
                var sub = subArray[j];
                console.log(sub.width,sub.alignment)
            }
        }
    }

    function selfXPos(arrCount,alignment)
    {
        if(arrCount<=0)
            return 0;

        var xpos = 0;
        for(var i=0;i<arrCount-1;i++)
        {
            var subArray = btnArray2[i];
            if(subArray[0].alignment == "vertical")
            {
                xpos += subArray[0].width;
            }
            else
            {
                for(var j=0;j<subArray.length;j++)
                    xpos += subArray[j].width;
            }
        }

        //最后一个数组;
        subArray = btnArray2[arrCount-1];
        if(subArray[0].alignment=="horizontal")
        {
            for(i = 0;i<subArray.length;i++)
                xpos += subArray[i].width;
        }
        else //垂直布局的数组,只要加一次即可;
        {
            if(alignment == "horizontal")
                xpos += subArray[0].width
        }

    //    console.log(xpos)
        return xpos;
    }

    function append(btnName,btnPic,btnWidth,alignment,btnType,pressShowBk,hoverShowBk,showTooltip,tipTitle,tipText)
    {//添加控件,根据horizontal或vertical来处理
        if(!(alignment == "horizontal" || alignment == "vertical"))
            return null;

        var flow = {} //布局对象;
        var item = {}; //控件对象;
        var arrCount = btnArray2.length;
        var xpos = root.selfXPos(arrCount,alignment); //当前待插入的控件在当前面板的x位置;
        if(alignment == "horizontal")
        {
            if( (arrCount<=0) || (btnArray2[arrCount-1][0].alignment=="vertical") )
            { //如果待添加控件的前面无控件或控件布局是vertical时,新建一个新的flow;
                flow = left2rightComp.createObject(root);
                item = ctrlComp.createObject(flow,{"parent" : flow,
                                                 "btnName":btnName,
                                                 "btnPic":btnPic,
                                                 "posX":xpos,
                                                 "alignment":alignment,
                                                 "btnType":btnType,
                                                 "pressShowBk":pressShowBk,
                                                 "hoverShowBk":hoverShowBk,
                                                 "showTooltip":showTooltip,
                                                 "tipTitle":tipTitle,
                                                 "tipText":tipText});

                item.width = btnWidth
                item.height = root.height
                btnArray2[arrCount] = [item];
            }
            else
            { //待添加控件的前面已经有控件,且控件布局类型也为horizontal时,添加到原有的flow中即可;
                flow = btnArray2[arrCount-1][0].parent;
                item = ctrlComp.createObject(flow,{"parent" : flow,
                                                 "btnName":btnName,
                                                 "btnPic":btnPic,
                                                 "posX":xpos,
                                                 "alignment":alignment,
                                                 "btnType":btnType,
                                                 "pressShowBk":pressShowBk,
                                                 "hoverShowBk":hoverShowBk,
                                                 "showTooltip":showTooltip,
                                                 "tipTitle":tipTitle,
                                                 "tipText":tipText});
                item.width = btnWidth
                item.height = root.height
                btnArray2[arrCount-1].push(item);
            }
        }
        else //if(alignment == "vertical")
        {//垂直布局,说明它与其它控件垂直层叠后占一列,如果这一列中只有它一列,则它也独占一列,倘若后面添加一个垂直布局类型的控件,则与它同列;
         //当添加一"vertical"时,先判断数组中最后一个是否也是同种布局类型,若不是,则另建一列,否则,加到数组最后控件所属于的那列;

            if( (arrCount<=0) || (btnArray2[arrCount-1][0].alignment=="horizontal") )
            { //新建一列;
                flow = top2bottomComp.createObject(root);
                item = ctrlComp.createObject(flow,{"parent" : flow,
                                                 "btnName":btnName,
                                                 "btnPic":btnPic,
                                                 "posX":xpos,
                                                 "alignment":alignment,
                                                 "btnType":btnType,
                                                 "pressShowBk":pressShowBk,
                                                 "hoverShowBk":hoverShowBk,
                                                 "showTooltip":showTooltip,
                                                 "tipTitle":tipTitle,
                                                 "tipText":tipText});
                item.width = btnWidth
                item.height = root.height
                btnArray2[arrCount] = [item]
            }
            else
            { //使用原有的;
                var lastSubArr = btnArray2[arrCount-1];
                var perHeight = root.height/(lastSubArr.length+1); //求添加新的btn后重新计算,求出平均高度; //原来的个数加上新添加的一个;
                for(var i=0;i<lastSubArr.length;i++)
                { //更新高度值;
                    btnArray2[arrCount-1][i].height = perHeight;
                }

                //添加新的一行;
                flow = lastSubArr[0].parent;
                item = ctrlComp.createObject(flow,{"parent" : flow,
                                                 "btnName":btnName,
                                                 "btnPic":btnPic,
                                                 "posX":xpos,
                                                 "alignment":alignment,
                                                 "btnType":btnType,
                                                 "pressShowBk":pressShowBk,
                                                 "hoverShowBk":hoverShowBk,
                                                 "showTooltip":showTooltip,
                                                 "tipTitle":tipTitle,
                                                 "tipText":tipText});
                item.width = btnWidth
                item.height = perHeight
                btnArray2[arrCount-1].push(item)
            }
        }

      //  myPrint();

        return item;
    }
}

MenuPanelBase.qml =>


Rectangle
        {
           ....
  function addBtn(btnName,btnPic,btnWidth,alignment,btnType,pressShowBk,hoverShowBk,showTooltip,tipTitle,tipText)
   {
return    btnContainer.append(btnName,btnPic,btnWidth,alignment,btnType,pressShowBk,hoverShowBk,showTooltip,tipTitle,tipText);
    }
.....
            MenuBtnContainer
            {
                id: btnContainer
                anchors.fill: parent
                onPanelHoveredChanged:rowLayout.bPanelHovered = btnContainer.panelHovered
                onShowTooltip: root.parent.parent.showTooltip(root.index,tip);
                onHideTooltip: root.parent.parent.hideTooltip();
            }
        }


MenuPanelFactory.qml =>

Component
    {
        id: environmentComp

        MenuPanelBase
        {
            width: 185
            height: root.height
            type:"Environment"
            Component.onCompleted:
            {
                var hWidth = width/3
                var btn1 = addBtn("Time\nSlider","pic/menu/TimeSlider.png",hWidth,"horizontal","normal",true,true,true,"Time Slider","Display the times slider int the 3D Window so that you can view and modify the project's current date and time.")
                var btn2 = addBtn("Sun","pic/menu/Sun.png",hWidth,"horizontal","normal",true,true,true,"Light Source","Use the sum as a light source. the sun and moon poosition s are calculated base on time, date, and time zone.")
                var btn3 = addBtn("Shadow","pic/menu/Shadow.png",hWidth,"horizontal","normal",true,true,true,"Global Shadow","Cast a shadow from all buildings and 3D models in the 3D Window.")

            }
        }
    }
  评论这张
 
阅读(15)| 评论(0)
推荐

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017