现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

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

2015-04-22 06:03 工业·编程 ⁄ 共 4395字 ⁄ 字号 暂无评论

为了让QML开发的程序适应更多的设备,我们可能需要去缩放Item,但是手动缩放开发太耗时还容易出错,所以我封装了一下。效果是根据开发时的x、y、width、height自动缩放的扩展

AutoResize.qml代码:
import QtQuick 2.4 
 
Item { 
    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

给我留言

留言无头像?