首页 > 其他分享 >在屏幕上绘制四条动态线

在屏幕上绘制四条动态线

时间:2023-07-20 19:13:42浏览次数:32  
标签:count mousePos 鼠标 index 四条 points bNearTheLine 屏幕 绘制

具体要求:

触发状态:【左键保持按下,并移动鼠标】

要求:将线条从屏幕四周将线拉出来,且同样要求能够进行隐藏,线与线之间有距离限制。

结构框架:重写鼠标点击事件与,鼠标移动事件(鼠标移动事件中若用到event()->pos()这个会将一开始的鼠标位置传入,后面会持续刷新坐标)。通过鼠标移动事件触发拖拽线条功能函数,并通过update()触发重写的重绘事件。

思路:来说说拖拽线条功能函数的实现,在功能类中设置四个点QPointF[4]用于保存上下左右四条线(下标与方向对应,一开始初始化为(0,0)。其中0,1下标对应的点若纵坐标为0则代表隐藏,2,3下标对应的点若横坐标为0则代表隐藏)。为了方便我们一次只能选中一根线(对这根线进行操作时,不能影响其他线的位置)。我当时写法是在主体中直接判断何时拉线何时隐藏。然而这样很麻烦,因为鼠标移动事件是不停的会触发的。有时候根本无需这样的判断,而且直接放在主体中,还会影响到其他线(这里当时思考不清晰)。那么如何保证我们在拉动一条线时不影响其他线呢,我们在类中定义一个标志位,用于判断当前是否有线被拖动,若没有,我们通过鼠标的位置来找到合适的线,若有我们则直接跳过通过鼠标位置找合适的线的判断,直接更新QPointF中的对应坐标(这样线的移动比通过鼠标位置来判断更流畅)。松开鼠标时才会将这个标志位置false。(m_bNearTheLine)也就是说当按住鼠标进行拖拽时,每次执行鼠标移动函数中的此函数时,都会跳过判断选取合适线的if(!m_bNearTheLine)语句。直接移动相对应的线。

最终思路:随着移动事件点击的按下,直接通过for循环将移动鼠标事件的位置与QPointF进行判断,若有符合移动条件的点,则将count计数加一。循环结束后,若是count==1则将m_bNearTheLine置true,若是count>1则将m_bNearTheLine置false,若是count==0则继续判断点否在边上,若是,则count=1,且更新index。且将m_bNearTheLine设置为true.之后通过此标识位与index进入下面的更新坐标的if语句。

主要代码:

const double mLineDis = 45;       //两线相隔35不可移动
    qreal distance = 15;             //10px开始拖动
    double respondlen = 20;           //点击处距离线条15像素进行响应。

    int count = 0;   //计算被选中的条数,只能为1
    static int index = 0;   //被选中的线

    if (!m_bNearTheLine) {  //随着点击的按下,直接进行条件判断      初始化中为flase, 鼠标左键松开后也为false.
        for (int i = 0; i < sizeof(m_points) / sizeof(m_points[0]); i++) {     //m_points也就是上面的QPointF[4]对应的变量,下标对应上下左右
            if (i < 2) {
                if (m_points[i].y() != 0 && fabs(mousePos.y() - m_points[i].y()) < respondlen) {
                    count++;
                    index = i;
                }
            }
            else {
                if (m_points[i].x() != 0 && fabs(mousePos.x() - m_points[i].x()) < respondlen) {
                    count++;
                    index = i;
                }
            }
        }

        if (count == 0) {
            if (mousePos.y() < distance && m_points[0].y() == 0) {
                count = 1;
                index = 0;
                m_bNearTheLine = true;
            }
            else if ((mousePos.y() > (m_newPaintRect.height() - distance)) && m_points[1].y() == 0) {
                count = 1;
                index = 1;
                m_bNearTheLine = true;
            }
            else if ((mousePos.x() < distance) && m_points[2].x() == 0) {
                count = 1;
                index = 2;
                m_bNearTheLine = true;
            }
            else if ((mousePos.x() > (m_newPaintRect.width() - distance)) && m_points[3].x() == 0) {
                count = 1;
                index = 3;
                m_bNearTheLine = true;
            }
        }
        else if (count == 1) {
            m_bNearTheLine = true;
        }
        else {
            m_bNearTheLine = false;
        }
    }

    if (m_bNearTheLine) {   //线条正在拖拽中

        bool isMoving = true;   //是否更新线条
            //index就是此刻要移动的线
        if (index == 0) {      //上线
            if (m_points[1].y()) {
                if (mousePos.y() >= m_points[1].y() - mLineDis)
                    isMoving = false;
            }
            else {
                if (mousePos.y() >= m_newPaintRect.height() - mLineDis)
                    isMoving = false;
            }

            if (isMoving) {   
                m_points[0].setY(mousePos.y());
                if (mousePos.y() < distance) //追加这个是由于要实现隐藏功能
                    m_points[0].setY(0);
            }
        }

        if (index == 1) {      //下线
            if (m_points[0].y()) {
                if (mousePos.y() <= m_points[0].y() + mLineDis)
                    isMoving = false;
            }
            else {
                if (mousePos.y() <= mLineDis)
                    isMoving = false;
            }

            if (isMoving) {
                m_points[1].setY(mousePos.y());
                if (mousePos.y() > m_newPaintRect.height() - distance)
                    m_points[1].setY(0);
            }
        }

        if (index == 2) {      //左线
            if (m_points[3].x()) {
                if (mousePos.x() >= m_points[3].x() - mLineDis)
                    isMoving = false;
            }
            else {
                if (mousePos.x() >= m_newPaintRect.width() - mLineDis)
                    isMoving = false;
            }

            if (isMoving) {
                m_points[2].setX(mousePos.x());
                if (mousePos.x() < distance)
                    m_points[2].setX(0);
            }
        }

        if (index == 3) {      //右线
            if (m_points[2].x()) {
                if (mousePos.x() <= m_points[2].x() + mLineDis)
                    isMoving = false;
            }
            else {
                if (mousePos.x() <= mLineDis)
                    isMoving = false;
            }

            if (isMoving) {
                m_points[3].setX(mousePos.x());
                if (mousePos.x() > m_newPaintRect.width() - distance)
                    m_points[3].setX(0);
            }
        }
    }

 

标签:count,mousePos,鼠标,index,四条,points,bNearTheLine,屏幕,绘制
From: https://www.cnblogs.com/ylww/p/17569400.html

相关文章

  • 常见电脑屏幕分辨率
    1024600(常见8.9寸电脑使用)1024768(常用10.4、12.1、14.1、15寸电脑使用)4:312801024(常用14.1、15寸电脑使用)5:41600*90016:9(非主流)14401050(常用15、16.1寸电脑使用)4:316001200(常用15、16.1寸电脑使用)4:31280800(常见10.8、12.1、15.4寸电脑使用)16:101366768(常见15.2寸......
  • U3D 屏幕坐标转世界坐标
    使用函数:Camera.ScreenToWorldPoint(1)2D时( Z轴默认一直为0):Camera.main.ScreenToWorldPoint(Input.mousePosition);(2)3D时(Z轴不一定为0):Camera.main.ScreenToWorldPoint(newVector3(Input.mousePosition.x,Input.mousePosition.y,transform.position.z));注意点:由于屏......
  • m根据给定系统传递函数自动绘制系统结构图matlab仿真,包括直接型,级联型以及并联型
    1.算法仿真效果matlab2022a仿真结果如下:2.算法涉及理论知识概要在控制系统分析和设计过程中,传递函数是一个重要的概念。通过传递函数,我们可以快速地分析系统的稳定性、响应特性等。同时,根据系统传递函数自动绘制系统结构图是一项非常有价值的技术,它可以帮助工程师更好地理......
  • m根据给定系统传递函数自动绘制系统结构图matlab仿真,包括直接型,级联型以及并联型
    1.算法仿真效果matlab2022a仿真结果如下:   2.算法涉及理论知识概要         在控制系统分析和设计过程中,传递函数是一个重要的概念。通过传递函数,我们可以快速地分析系统的稳定性、响应特性等。同时,根据系统传递函数自动绘制系统结构图是一项非常有价值的技......
  • 02-流程图绘制
    title:02-流程图绘制date:2023-7-1923:08:37tags:-Flowable经典工具:FlowableEclipseDesigner但是,这是一个Eclipse插件。IDEA:IDEA默认就有一个流程图绘制工具,当在IDEA中打开一个流程图的XML文件的时候,可以选择Designer,就可以通过可视化的方式去查看这个流程......
  • 记一次<!DOCTYPE html>引起的height100%总是屏幕高度,layui弹框top值很大超出屏幕问题
    不管父元素有没有指定高度,只要有height:100%高度就是是九百多,我屏幕的高度或者浏览器可显示区域高度最先是swiper区域控制不了高度一致九百多,后来发现layui的checkboxspan文字高度也是九百多,两个地方均有height100%layuimsg无法显示,查看源代码<divclass="layui-layerlay......
  • 屏幕缩放比例原理
    情景一:基准宽度:bw=1920基准高度:bh=1080变换后宽度:tw=1920变换后高度:th=600基准比例:br= bw/bhbw/bh>tw/th表示宽度大,将高度最终显示为th(即高度直接显示,按同比例显示情况下计算宽度需要显示为多少),故高度缩放比例计算为:scaleHeight=th/bh,计算最终显示......
  • 在线CAD如何配合three.js绘制带线宽的线段
    前言1.在线CAD的产品经常会被集成到很多用户的网页系统内,前端开发人员只要会JavaScript,就可以对在线CAD进行集成和二次开发,今天这篇文章我们讲一下梦想CAD控件云图(H5方式)如何配合three.js绘制带线宽的线段。2.在这之前,如果还没有安装梦想CAD控件的朋友,可以查看快速入门,链接如......
  • android设置弹框高为屏幕宽得2/3
    Android设置弹框高为屏幕宽的2/3Android开发中,经常需要在应用中使用弹框来展示一些重要的信息或者进行用户交互。设置弹框的高度为屏幕宽的2/3是一个常见的需求。本文将介绍如何通过代码实现这一功能。获取屏幕宽度在Android中,我们可以通过以下代码来获取屏幕的宽度:DisplayMetr......
  • 牛客网-手机屏幕解锁模式
    1.题目读题[编程题]手机屏幕解锁模式  手机屏幕解锁模式现有一个3x3规格的Android智能手机锁屏程序和两个正整数m和n,请计算出使用最少m个键和最多n个键可以解锁该屏幕的所有有效模式总数。其中有效模式是指:1、每个模式必须连接至少m个键和最多n个键;2、所有的......