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

沙漠里de烟雨

原创分享,禁止转载

 
 
 

日志

 
 

qml下父子控件的鼠标经过处理  

2017-05-11 03:44:07|  分类: QT5.x与QML |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
由于父控件下的MouseArea下的鼠标消息会截获子控件下MouseArea的鼠标消息。所以,
如果要实现经过父子控件上方时,都会响应消息,唯一方法是只在父控件下处理MouseArea下的消息,
然后在onPositionChanged下时刻检测鼠标的位置,并计算当前的位置是否在某个子控件上,如果在的话,
发送消息给子控件,让此子控件作出相应的响应。
如此而已,所以问题就在于如何检测计算其位置问题:

import QtQuick 2.0
import QtQuick.Controls 1.4
import "."

Rectangle
{
    id: root

    width: 80
    height: 400
    color: "#00000000"

    property int gap: 5

    Wheel
    {
        id: wheel
        x: 0; y: root.gap
        xTooltip : qsTr("拖动可旋转,点N可重置正北方位")
    }

    Handle
    {
        id: handle0
        x: (root.width-handle0.width)/2
        y: (root.width-handle0.width)/2 + root.gap
        mouseHoverPic: "pic/handle_0.png"
        xTooltip : qsTr("点击可环视")
    }

    Handle
    {
        id: handle1
        x: (root.width-handle1.width)/2
        y: wheel.height+2*root.gap
        mouseHoverPic: "pic/handle_1.png"
        xTooltip : qsTr("点击可四处移动")
    }

    VSlider
    {
        id: vslider
        x: (root.width-vslider.width)/2
        y: wheel.height+handle1.height+3*root.gap
        xTooltip : qsTr("拖动该滑块或点击相应按钮可执行缩放操作")
    }

    function circleContains(x0,y0,r,x,y) //圆包含; x0,y0为中心点,r为半径;返回boolean;
    {
        return (x-x0)*(x-x0)+(y-y0)*(y-y0) <= r*r;
    }

    function mouseTest(x,y)
    {
        var mouseTarget = {};
        var x_center = root.width/2; //垂直中心线;

        if(circleContains(x_center,handle0.y+handle0.height/2, handle0.height/2,x,y))
        { //眼;
            mouseTarget["id"] = handle0;
            mouseTarget["x0"] = x_center;
            mouseTarget["y0"] = handle0.y+handle0.height/2;

//            console.log("handle0",mouseTarget["x0"],mouseTarget["y0"],x,y);

            return mouseTarget;
        }

        if(circleContains(x_center,wheel.y+wheel.height/2,wheel.height/2,x,y))
        { //圆环,这里无须判断大于内环,因为如果在内环的话,上面的判断被执行并返回;

            mouseTarget["id"] = wheel;
            mouseTarget["x0"] = x_center;
            mouseTarget["y0"] = wheel.y+wheel.height/2;

//            console.log("wheel",mouseTarget["x0"],mouseTarget["y0"],x,y);

            return mouseTarget;
        }

        if(circleContains(x_center,handle1.y+handle1.height/2, handle1.height/2,x,y))
        { //手;

            mouseTarget["id"] = handle1;
            mouseTarget["x0"] = x_center;
            mouseTarget["y0"] = handle1.y+handle1.height/2;

//            console.log("handle1",mouseTarget["x0"],mouseTarget["y0"],x,y);

            return mouseTarget;
        }

        if(circleContains(x_center,vslider.y+vslider.height/2,vslider.height/2,x,y))
        { //滑块;
            mouseTarget["id"] = vslider;
            mouseTarget["x0"] = x_center;
            mouseTarget["y0"] = vslider.y+vslider.height/2;
            return mouseTarget;
        }

        return mouseTarget;
    }

    function vectersArc(a,b) //求两向量间的夹角;
    {
        var normalized_a = a.normalized();
        var normalized_b = b.normalized();
        var cosArc = normalized_a.dotProduct(normalized_b)/1*1; //夹角余弦值;
        cosArc = Math.acos(cosArc);//弧度;
        cosArc *= 180/Math.PI;//角度;
        return cosArc;
    }

    function rotateArc(x0,y0,x1,y1,x2,y2) //旋转; x0,y0为中心点;x1,y1为原始点,x2,y2为当前点;返回旋转角度,顺时针为正,逆时针为负;
    {
        var oA = Qt.vector2d(x1-x0,y1-y0);
        var oB = Qt.vector2d(x2-x0,y2-y0);
        var cosArc = vectersArc(oA,oB);
        var oY = Qt.vector2d(0,1);

        var clockWise = vectersArc(oY,oB)<vectersArc(oY,oA);
        if(x1-x0>0 && x2-x0>0) //均在右侧;
        {
            cosArc *= clockWise ? 1 : (-1);
        }
        else if(x1-x0<0 && x2-x0<0) //均在左侧;
        {
            cosArc *= clockWise ? (-1) : 1;
        }
        else if(x1-x0>0 && x2-x0<0) //顺时针;
        {
            cosArc *= 1;
        }
        else if(x1-x0<0 && x2-x0>0) //逆时针;
        {
            cosArc *= -1;
        }

        return cosArc;
    }

    function northBtnMouseTest(x0,y0,x,y,r0,arc0)
    {
//        console.log("x0,y0,x,y = ",x0,y0,x,y);
        var delta_len = 5;
        var delta_arc = 8;
        var len = Math.sqrt((x-x0)*(x-x0)+(y-y0)*(y-y0));
        var oY_vect = Qt.vector2d(0,1);
        var oXY_vect = Qt.vector2d(x-x0,y0-y).normalized();
        var arc = vectersArc(oY_vect,oXY_vect);
//        console.log("r0,len:",r0,len);
//        console.log("arc0,arc:",arc0,arc);

        if(len>=r0-delta_len && len<=r0+delta_len)
        {
            if(arc0>=0) //顺时针时;
            {
                if(x-x0>=0)
                    arc *= 1;
                else
                    arc = 360-arc;
            }
            else //逆时针时;
            {
                if(x-x0>=0)
                    arc = arc-360;
                else
                    arc *= -1;
            }

            return (arc>=arc0-delta_arc && arc<=arc0+delta_arc);
        }

        return false;
    }

    MouseArea
    {
        id: mouseAreaId
        anchors.fill: parent
        hoverEnabled: true

        property bool bWheelHolding: false
        property point perWheelPos;
        property var perId : null;
        property bool bNorthBtnClicked: false;

        onEntered:
        {
            wheel.setMouseHover(true);
            handle0.setMouseHover(true);
            handle1.setMouseHover(true);
            vslider.setMouseHover(true);
        }

        onExited:
        {
            wheel.setMouseHover(false);
            handle0.setMouseHover(false);
            handle1.setMouseHover(false);
            vslider.setMouseHover(false);
        }

        onPositionChanged:
        {
            var target = mouseTest(mouse.x, mouse.y);

            var id = target["id"];
            var x0 = target["x0"];
            var y0 = target["y0"];
            var x = mouse.x;
            var y = mouse.y;

            if(id != perId)
            {
                if(perId!=null)
                    perId.onExit();
                if(id!=null)
                    id.onEnter();
                perId = id;
            }

            //
            if(bWheelHolding==true && (id==wheel || id==handle0))
            {
                var arc = root.rotateArc(x0,y0,perWheelPos.x,perWheelPos.y,x,y);
                arc += wheel.xArc;
                if(arc>=360) arc -= 360;
                if(arc<=-360) arc += 360;
                wheel.xArc = arc;
                perWheelPos.x = x;
                perWheelPos.y = y;
            }

            if(id == vslider)
            {
                vslider.onDrag(y0,y);
            }
        }

        onPressed:
        {
            var target = mouseTest(mouse.x, mouse.y);
            var id = target["id"];
            var x0 = target["x0"];
            var y0 = target["y0"];
            var x = mouse.x;
            var y = mouse.y;
            switch(id)
            {
            case wheel:
                wheel.onPress();
                bNorthBtnClicked = northBtnMouseTest(x0,y0,x,y,wheel.height/2,wheel.xArc);
                wheel.onPressNorthBtn(bNorthBtnClicked);
                break;
            case handle0:
                handle0.onPress(x0,y0,x,y);
                break;
            case handle1:
                handle1.onPress(x0,y0,x,y);
                break;
            case vslider:
                vslider.onPress(x0,y0,x,y);
                break;
            }
        }

        onReleased:
        {
            wheel.onRelease();
            handle0.onRelease();
            handle1.onRelease();
            vslider.onRelease();

            if(bNorthBtnClicked && !bWheelHolding)
            {
                wheel.xArc = 0;
            }

            bWheelHolding = false;
            bNorthBtnClicked = false;
        }

        onPressAndHold:
        {
            var target = mouseTest(mouse.x, mouse.y);
            var id = target["id"];
            var x0 = target["x0"];
            var y0 = target["y0"];
            var x = mouse.x;
            var y = mouse.y;
            if(id == wheel)
            {
                bWheelHolding = true;
                perWheelPos.x = x;
                perWheelPos.y = y;

                wheel.onPress();
            }
        }
    }
}
  评论这张
 
阅读(448)| 评论(0)

历史上的今天

评论

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

页脚

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