QML实现类似游戏小地图(包括可拉伸的矩形(鼠标拉伸和滚轮缩放),和对应变换的显示区域)

  小声bb
         这只是一个初期的demo,起一个抛砖引玉的作用,所以如果大家有什么好的建议可以留言博主,当然如果有什么问题,请联系博主的QQ:995187021。如果这篇文章对你有一点点帮助,麻烦您点一个赞,让我知道自己不是在做无用功,让卑微的博主找到一丢丢的存在感,谢谢。如果有什么好的萝卜坑推荐的话,也是感谢至极。 

效果


说明
       思路,首先是根据flickable的显示属性,可以将要显示的区域局部显示,并且可以设置显示区域的位置和大小 ,那就需要一个Handle来动态的改变这个显示区域的属性,这个handle得具有哪些属性呢?1.大小可拉伸,即四个点加上四个边可以拉升改变这个handle,并且大小必须有限定。2.可拖动,在一个区域内要能够拖动。3.鼠标滚轮能控制放大缩小,但不能超过固定区域。

         显示,显示区域的大小与flickable对应的比例,与handle大小和handle的限定区域对应的比例一致,并且坐标也应该对应成比例。

代码
StretchableRec.qml(可拉伸的矩形(handle))

import QtQuick 2.0
 
Rectangle{
    id:root
    color: "transparent"
    border.color: "#cc661a"
    border.width: 1
    property int  smallBoxHeight : 8    //小方框的高
    property int smallBoxWidth: 6       //小方框的宽
    property int startY:0               //拉伸时鼠标的起始y坐标
    property int startX: 0              //拉伸时鼠标的起始x坐标
    property int parentData1: 0         //用来自由存储信息
    property int parentData2: 0
    property bool isPressed: false      //小方框是否被点击
    property int maxX:0                 //方框x的最大值
    property int maxY: 0                //方框y的最大值
    property int scrollNum:0            //鼠标滚轮的弧度
    Drag.active: dragMouse.drag.active  //可以拖动
 
    Rectangle{                  //左上小方框
        z:2
        id:leftTopRec
        color: "#303030"
        height:smallBoxHeight
        width: smallBoxWidth
        anchors.left: parent.left
        anchors.top: parent.top

        MouseArea{                      //左上小方框的鼠标区域
            id:leftTopMouse
            anchors.fill: parent
            cursorShape: Qt.SizeFDiagCursor
            onPressed: {                //点击后记录 鼠标被点击  鼠标起始坐标 根矩形的宽  根矩形的高
                isPressed=true
                startX=mouse.x
                startY=mouse.y
                parentData1=root.x+root.width
                parentData2=root.y+root.height
            }
            onPositionChanged: {        //鼠标移动
                if(isPressed){          //只能是在鼠标按下后拉伸
                    if(root.y+(mouse.y-startY)>=0&&root.height-(mouse.y-startY)>smallBoxHeight){ //限制拉伸极限
                        root.y=root.y+(mouse.y-startY)
                        root.height=root.height-(mouse.y-startY)
                    }else{
                        if(root.y+(mouse.y-startY)<0){
                            root.y=0
                            root.height=parentData2
                        }
                        if(root.height-(mouse.y-startY)                         {
                            root.y=parentData2-smallBoxHeight
                            root.height=smallBoxHeight
                        }
                    }
                    if(root.x+(mouse.x-startX)>=0&&root.width-(mouse.x-startX)>smallBoxWidth){
                        root.x=root.x+(mouse.x-startX)
                        root.width=root.width-(mouse.x-startX)
                    }else{
                        if(root.x+(mouse.x-startX)<0){
                            root.x=0
                            root.width=parentData1
                        }
                        if(root.width-(mouse.x-startX)                         {
                            root.x=parentData1-smallBoxWidth
                            root.width=smallBoxWidth
                        }
                    }
                }
            }
            onReleased: {       //鼠标放下后将按下置为false
                isPressed=false
            }
        }
    }
    Rectangle{              //右上小矩形
        z:2
        id:rightTopRec
        color: "#303030"
        height: smallBoxHeight
        width: smallBoxWidth
        anchors.right: parent.right
        anchors.top: parent.top

        MouseArea{          //右上矩形鼠标
            id:rightTopMouse
            anchors.fill: parent
            cursorShape: Qt.SizeBDiagCursor
            onPressed: {
                isPressed=true
                startX=mouse.x
                startY=mouse.y
                // parentData1=root.x+root.width
                parentData2=root.y+root.height
            }
            onPositionChanged: {
                if(isPressed){
                    if(root.y+(mouse.y-startY)>=0&&root.height-(mouse.y-startY)>smallBoxHeight){
                        root.y=root.y+(mouse.y-startY)
                        root.height=root.height-(mouse.y-startY)
                    }else{
                        if(root.y+(mouse.y-startY)<0){
                            root.y=0
                            root.height=parentData2
                        }
                        if(root.height-(mouse.y-startY)                         {
                            root.y=parentData2-smallBoxHeight
                            root.height=smallBoxHeight
                        }
                    }
                    if(root.width+root.x+mouse.x-startXsmallBoxWidth){
                        root.width=root.width+mouse.x-startX
                    }else{
                        if(root.width+root.x+mouse.x-startX>maxX)
                        {
                            root.width=maxX-root.x
                        }
                        if(root.width+mouse.x-startX                         {
                            root.width=smallBoxWidth
                        }
                    }
                }
            }
            onReleased: {
                isPressed=false
            }
        }
    }
    Rectangle{             //左下矩形
        z:2
        id:leftBottomRec
        color: "#303030"
        height: smallBoxHeight
        width: smallBoxWidth
        anchors.left: parent.left
        anchors.bottom: parent.bottom

        MouseArea{              //左下矩形的鼠标区域
            id:leftBottomMouse
            anchors.fill: parent
            cursorShape: Qt.SizeBDiagCursor
            onPressed: {
                isPressed=true
                startX=mouse.x
                startY=mouse.y
                parentData1=root.x+root.width
                //parentData2=root.y+root.height
            }
            onPositionChanged: {
                if(isPressed){
                    if(root.x+(mouse.x-startX)>=0&&root.width-(mouse.x-startX)>smallBoxWidth){
                        root.x=root.x+(mouse.x-startX)
                        root.width=root.width-(mouse.x-startX)
                    }else{
                        if(root.x+(mouse.x-startX)<0){
                            root.x=0
                            root.width=parentData1
                        }
                        if(root.width-(mouse.x-startX)                         {
                            root.x=parentData1-smallBoxWidth
                            root.width=smallBoxWidth
                        }
                    }
                    if(root.height+root.y+mouse.y-startYsmallBoxHeight){
                        root.height=root.height+mouse.y-startY
                    }else{
                        if(root.height+root.y+mouse.y-startY>maxY)
                        {
                            root.height=maxY-root.y
                        }
                        if(root.height+mouse.y-startY                         {
                            root.height=smallBoxHeight
                        }
                    }
                }
            }
 
            onReleased: {
                isPressed=false
            }
        }
    }
    Rectangle{
        z:2
        id:rightBottomRec
        color: "#303030"
        height:smallBoxHeight
        width:smallBoxWidth
        anchors.right: parent.right
        anchors.bottom: parent.bottom

        MouseArea{
            id:rightBottomMouse
            anchors.fill: parent
            cursorShape: Qt.SizeFDiagCursor
            onPressed: {
                isPressed=true
                startX=mouse.x
                startY=mouse.y
                //parentData1=root.x+root.width
                //parentData2=root.y+root.height
            }
            onPositionChanged: {
                if(isPressed){
                    if(root.width+root.x+mouse.x-startXsmallBoxWidth){
                        root.width=root.width+mouse.x-startX
                    }else{
                        if(root.width+root.x+mouse.x-startX>maxX)
                        {
                            root.width=maxX-root.x
                        }
                        if(root.width+mouse.x-startX                         {
                            root.width=smallBoxWidth
                        }
                    }
                    if(root.height+root.y+mouse.y-startYsmallBoxHeight){
                        root.height=root.height+mouse.y-startY
                    }else{
                        if(root.height+root.y+mouse.y-startY>maxY)
                        {
                            root.height=maxY-root.y
                        }
                        if(root.height+mouse.y-startY                         {
                            root.height=smallBoxHeight
                        }
                    }
                }
            }
            onReleased: {
                isPressed=false
            }
        }
    }
    Rectangle{
        z:2
        id:topRec
        color: "#303030"
        height:smallBoxHeight
        width:smallBoxWidth
        x:(parent.width-topRec.width)/2
        MouseArea{
            id:topMouse
            anchors.fill: parent
            hoverEnabled: true
            cursorShape:Qt.SizeVerCursor
            onPressed: {
                isPressed=true
                //startPoint.x=mouse.x
                startY=mouse.y
                parentData1=root.y+root.height
            }
            onPositionChanged: {
                if(isPressed){
                    if(root.y+(mouse.y-startY)>=0&&root.height-(mouse.y-startY)>smallBoxHeight){
                        root.y=root.y+(mouse.y-startY)
                        root.height=root.height-(mouse.y-startY)
                    }else{
                        if(root.y+(mouse.y-startY)<0){
                            root.y=0
                            root.height=parentData1
                        }
                        if(root.height-(mouse.y-startY)                         {
                            root.y=parentData1-smallBoxHeight
                            root.height=smallBoxHeight
                        }
                    }
                }
            }
            onReleased: {
                isPressed=false
            }
        }
    }
    Rectangle{
        z:2
        id:rightRec
        color: "#303030"
        height:smallBoxHeight
        width:smallBoxWidth
        y:(parent.height-topRec.height)/2
        anchors.right: parent.right
        MouseArea{
            id:rightMouse
            anchors.fill: parent
            hoverEnabled: true
            cursorShape:Qt.SizeHorCursor
            onPressed: {
                isPressed=true
                startX=mouse.x
                // parentData1=root.y+root.height
            }
            onPositionChanged: {
                if(isPressed){
                    if(root.width+root.x+mouse.x-startXsmallBoxWidth){
                        root.width=root.width+mouse.x-startX
                    }else{
                        if(root.width+root.x+mouse.x-startX>maxX)
                        {
                            root.width=maxX-root.x
                        }
                        if(root.width+mouse.x-startX                         {
                            root.width=smallBoxWidth
                        }
                    }
                }
            }
            onReleased: {
                isPressed=false
            }
        }
    }
    Rectangle{
        z:2
        id:bottomRec
        color: "#303030"
        height:smallBoxHeight
        width:smallBoxWidth
        x:(parent.width-topRec.width)/2
        anchors.bottom: parent.bottom

        MouseArea{
            id:bottomMouse
            anchors.fill: parent
            hoverEnabled: true
            cursorShape:Qt.SizeVerCursor
            onPressed: {
                isPressed=true
                startY=mouse.y
                // parentData1=root.y+root.height
            }
            onPositionChanged: {
                if(isPressed){
                    if(root.height+root.y+mouse.y-startYsmallBoxHeight){
                        root.height=root.height+mouse.y-startY
                    }else{
                        if(root.height+root.y+mouse.y-startY>maxY)
                        {
                            root.height=maxY-root.y
                        }
                        if(root.height+mouse.y-startY                         {
                            root.height=smallBoxHeight
                        }
                    }
                }
            }
            onReleased: {
                isPressed=false
            }
        }
    }
    Rectangle{
        z:2
        id:leftRec
        color: "#303030"
        height:smallBoxHeight
        width:smallBoxWidth
        y:(parent.height-topRec.height)/2
        anchors.left: parent.left

        MouseArea{
            id:leftMouse
            anchors.fill: parent
            hoverEnabled: true
            cursorShape:Qt.SizeHorCursor
            onPressed: {
                isPressed=true
                startX=mouse.x
                parentData1=root.x+root.width
            }
            onPositionChanged: {
                if(isPressed){
                    if(root.x+(mouse.x-startX)>=0&&root.width-(mouse.x-startX)>smallBoxWidth){
                        root.x=root.x+(mouse.x-startX)
                        root.width=root.width-(mouse.x-startX)
                    }else{
                        if(root.x+(mouse.x-startX)<0){
                            root.x=0
                            root.width=parentData1
                        }
                        if(root.width-(mouse.x-startX)                         {
                            root.x=parentData1-smallBoxWidth
                            root.width=smallBoxWidth
                        }
                    }
                }
            }
            onReleased: {
                isPressed=false
            }
        }
    }
    Rectangle{              //拖动事件,鼠标触发区域
        id:dragArea
        anchors.fill: parent
        color: "#cc661a"
        opacity: 0.2            //透明度0.2
        MouseArea{              //鼠标区域
            id:dragMouse
            anchors.fill: parent
            cursorShape:Qt.SizeAllCursor    //鼠标样式
            drag.target: root
            drag.minimumX: 0                //拖动区域限制
            drag.minimumY: 0
            drag.maximumX:maxX-root.width
            drag.maximumY: maxY-root.height
            onWheel: {                      //接收到滚轮事件
                scrollNum=wheel.angleDelta.y / 120      //接收滚轮滚动的大小
 
                if(scrollNum>0){                    //判断滚动的方向
                    if(root.x>=5)
                    {
                        root.x-=wheel.angleDelta.y /120*5
                    }else if(0                         root.x=0
                    }
 
                    if(root.y>=5)
                    {
                        root.y-=wheel.angleDelta.y /120*5
                    }else if(0                         root.y=0
                    }
                    if(root.width<=maxX-root.x-10)
                    {
                        root.width+=wheel.angleDelta.y /120*5*2
                    }else if(maxX-root.x-10                     {
                        root.width=maxX-root.x
                    }
                    if(root.height<=maxY-root.y-10)
                    {
                        root.height+=wheel.angleDelta.y /120*5*2
                    }else if(maxY-root.y-10<=root.height                     {
                        root.height=maxY-root.y
                    }
                }else
                {
                    if(root.width>smallBoxWidth*3){ //限制最小的宽度不小于三个小矩形的宽
                        root.width+=wheel.angleDelta.y /120 *5*2
                        root.x-=wheel.angleDelta.y /120 *5
                    }
                    if(root.height>smallBoxHeight*3){   //限制最小的高度不小于三个小矩形的高
                        root.height+= wheel.angleDelta.y /120*5*2
                        root.y-=wheel.angleDelta.y /120 *5
                    }
                }
            }
        }
    }
}
main.qml

import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
 
ApplicationWindow {
    visible: true
    width: 680
    height: 600
    title: qsTr("闻天语")
 
 
    Rectangle{
        id:container
        height: 200
        width: 200
        border.color:"#008792"
        border.width:1
        x:420
        y:400
        StretchableRec{ //自定义的可拉伸的矩形
                 id:testRec1
                 height: 50
                 width: 50
                 x:20
                 y:20
                 maxY: parent.height
                 maxX: parent.width
        }
}
   Flickable {
       id:flick
        width: 400; height: 400
        clip: true
        interactive:false //flickable不可拂动(如果不加这句,点击flickable任意位置content会回到(0,0)坐标)
        Rectangle{          //需要显示的内容
                id:myContent
                height:(200/testRec1.height)*flick.height
                width: (200/testRec1.width)*flick.width
                Image {         //这里我们显示一张图片
                    id: img
                    source: "qrc:/pic/pic.jpg"
                    anchors.fill:parent
                }
        }
        contentX: (myContent.width/200)*testRec1.x      //使显示区域的坐标与拖动handle在对应框中的坐标相对应
        contentY:(myContent.height/200)*testRec1.y
    }
}
CSDN下载:https://download.csdn.net/download/weixin_40912639/10828745
--------------------- 
作者:闻天语~ 
来源:CSDN 
原文:https://blog.csdn.net/weixin_40912639/article/details/84801458 
版权声明:本文为博主原创文章,转载请附上博文链接!

你可能感兴趣的:(《Qt》)