Qt:让QML中的控件自动缩放

来源:互联网 发布:淘宝女高中生帆布书包 编辑:程序博客网 时间:2024/05/06 03:30

为了让QML开发的程序适应更多的设备,我们可能需要去缩放Item,但是手动缩放开发太耗时还容易出错,所以我封装了一下


效果是根据开发时的x、y、width、height自动缩放的扩展


效果(3个效果是参数不同组合的结果):

正常情况下


拉宽


拉长


拉大



AutoResize.qml代码:

import QtQuick 2.4Item {    property var targetItem: parent    property bool fixedAspectRatio: true // Else zoom from width and height    property bool accordingToX: true // Else according to center    property var targetItemGeometry    property var childrenItemGeometry    property bool isBegin: false    function begin() {        targetItemGeometry = new Object;        targetItemGeometry["width"] = targetItem.width;        targetItemGeometry["height"] = targetItem.height;        var children = targetItem.children;        var data = new Array;        for(var index = 1; index < children.length; index++)        {            var currentItem = children[index];            var buf = new Object;            buf["item"] = currentItem;            buf["x"] = currentItem.x;            buf["y"] = currentItem.y;            buf["centerX"] = currentItem.x + (currentItem.width / 2);            buf["centerY"] = currentItem.y + (currentItem.height / 2);            buf["width"] = currentItem.width;            buf["height"] = currentItem.height;            data.push(buf);        }        childrenItemGeometry = data;        isBegin = true;    }    function resize() {        if(isBegin)        {            var horizontalRatio, verticalRatio;            horizontalRatio = targetItem.width / targetItemGeometry["width"];            verticalRatio = targetItem.height / targetItemGeometry["height"];            for(var index = 0; index < childrenItemGeometry.length; index++)            {                if(fixedAspectRatio)                {                    if(horizontalRatio > verticalRatio)                    {                        childrenItemGeometry[index]["item"].width  = childrenItemGeometry[index]["width"] * verticalRatio;                        childrenItemGeometry[index]["item"].height = childrenItemGeometry[index]["height"] * verticalRatio;                    }                    else                    {                        childrenItemGeometry[index]["item"].width  = childrenItemGeometry[index]["width"] * horizontalRatio;                        childrenItemGeometry[index]["item"].height = childrenItemGeometry[index]["height"] * horizontalRatio;                    }                }                else                {                    childrenItemGeometry[index]["item"].width  = childrenItemGeometry[index]["width"] * horizontalRatio;                    childrenItemGeometry[index]["item"].height = childrenItemGeometry[index]["height"] * verticalRatio;                }                if(accordingToX)                {                    childrenItemGeometry[index]["item"].x = childrenItemGeometry[index]["x"] * horizontalRatio;                    childrenItemGeometry[index]["item"].y = childrenItemGeometry[index]["y"] * verticalRatio;                }                else                {                    childrenItemGeometry[index]["item"].x = childrenItemGeometry[index]["centerX"] * horizontalRatio - (childrenItemGeometry[index]["item"].width / 2);                    childrenItemGeometry[index]["item"].y = childrenItemGeometry[index]["centerY"] * verticalRatio - (childrenItemGeometry[index]["item"].height / 2);                }            }        }    }    Component.onCompleted: {        begin();    }    Component {        id: connections        Connections {            target: targetItem            onWidthChanged: {                resize();            }            onHeightChanged:            {                resize();            }        }    }    Loader {        Component.onCompleted: {            sourceComponent = connections;        }    }}


使用:

 Rectangle {        width: parent.width / 2        height: parent.height / 2        color: "#00000000"        AutoResize {            fixedAspectRatio: true            accordingToX: true        }        Rectangle {            x: 15            y: 10            width: 80            height: 200            color: "#ff0000"        }        Rectangle {            x: 15            y: 210            width: 200            height: 80            color: "#00ff00"        }        Rectangle {            x: 124            y: 43            width: 247            height: 20            color: "#0000ff"        }        Rectangle {            x: 242            y: 140            width: 150            height: 150            color: "#000000"        }    }


只要把AutoResize直接以实例化出来就可以了

注意:AutoResize建议放在第一个子控件的位置,不然可能会报错而且需要手动初始化


参数说明:

fixedAspectRatio:固定长宽比,否则根据父对象长宽比缩放,默认true

accordingToX:根据X轴调整位置,否则根据中心点调整位置,默认true


示例下载地址:

https://github.com/188080501/AutoResizeDemo

0 0