• 【Qt】鼠标拖拽修改控件尺寸---八个方位修改


    前提
    在开发一个类似qdesiger的项目中
    使用QGraphicsProxyWidget将Qt基础控件作为item放在场景视图中显示和编辑
    创建自定义类继承QGraphicsProxyWidget,管理控件
    成员变量 有控件的xywh等,其中x、y坐标存储是基于最底层widgetitem
    坐标系 x轴以右为正方向,y轴以下为正方向
    首先鼠标悬浮在控件八个方位范围内时,显示对应的鼠标指针样式

    1.mousePress事件存储初始鼠标坐标

    void ProxyClass::mousePressEvent(QGraphicsSceneMouseEvent *event)
    
    • 1
    QPointF pos = event->pos();//Returns the mouse cursor position in item coordinates.
    _pressPos= pos;
    
    • 1
    • 2

    2.mouseMove事件

    void ProxyClass::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
    
    • 1

    检测到当前状态时调整尺寸而不是移动控件时,获取移动实时的鼠标坐标,然后与初始鼠标坐标相减得出鼠标总的移动的坐标范围值
    在这里插入图片描述

      QPointF currentPos = event->pos();
      QPointF movePoint = currentPos - _pressPos;//移动区域  h↓ y↑
    
    • 1
    • 2

    其实鼠标拖拽右、下边框比较简单,只涉及到修改控件尺寸;但是关于左、上边框不仅涉及到修改控件尺寸还涉及到控件坐标值的修改,需要注意一下。

    右下例:

       		case E_Right:
            {
                qreal w = event->pos().x();
                if (w > getItemMinSize().width())
                    setItemWidth(w);
            }
                break;
      		case E_Bottom:
            {
                qreal h = event->pos().y();
                if (h > getItemMinSize().height())
                    setItemHeight(h);
            }
                break;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    左、上例:
    得到控件高度的变化值 moveSize.y(),与原高度相减,得出此时修改后的高度值,也就是调整后的控件高度值;
    与此同时,控件的y坐标也要发生改变,原y坐标+高度变化值 defaultWidgetY() + dy,

    因为坐标系y向下为正方向,鼠标拖动上边框往下时差值为正,但是高度是应该减小的,所以此时 h是原高度-移动高度值

    		 case E_Top:
            {
                int h = getItemHeight() - moveSize.y();
                const int dy = moveSize.y();
                trySetGeometry(defaultWidgetX(), defaultWidgetY() + dy, getItemWidth(), h);
            }
                break;
    
            case E_Left:
            {
                int w = getItemWidth() - moveSize.x();
                const int dx = moveSize.x();
                trySetGeometry(defaultWidgetX() + dx, defaultWidgetY(), w, getItemHeight());
            }
                break;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    调用trySetGeometry函数具体设置控件的xywh
    :setItemSize函数中默认有resize函数设置修改控件尺寸
    :设置修改控件坐标时注意坐标系的转换,setpos(pos)的pos是基于父类图元的坐标
    目前坐标 基于默认widgetItem —[mapToScene]转换成—> 场景坐标 —[mapToParent]—>相对该图元的父类图元坐标,然后使用setpos设置修改调整后的控件坐标!
    注意:修改后的宽高不要小于控件的最小宽高值

    void ProxyClass::trySetGeometry(int x, int y, int width, int height)
    {
    
        int minw = this->minimumSize().width();//控件的最小宽高
        int minh = this->minimumSize().height();
    
        setItemSize(QSizeF(qMax(minw, width), qMax(minh, height)));//保存+设置控件尺寸  修改后的宽高不要小于控件的`最小宽高值`
        setDefaultWidgetPos(QPointF(x,y));//保存调整后的坐标
    
    	//坐标转换+设置调整后坐标
        if(getRoScene()){
            auto sc = dynamic_cast<DesignerGraphicsScene*>(getRoScene());
            auto scPos = sc->getDefaultWidgetItem()->mapToScene(QPointF(x,y));
            if(parentItem()){
                auto pPos = mapToParent(mapFromScene(scPos));
                setPos(pPos);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    3.鼠标释放后再调用修改右树属性值的函数,达到视图中的控件属性状态与右树对应属性值的实时一致。

  • 相关阅读:
    leetcode 216. 组合总和 III
    关于淘宝多个关键词权重快速提升的方法介绍
    关于VS多个dll相互依赖的问题
    云小课|云小课教您如何选择Redis实例类型
    SpringBoot + Vue 实现侧边栏目录动态展示
    1158 Telefraud Detection – PAT甲级真题
    《学术小白学习之路》论文常见方法:Doc2vec-句向量模型实现
    Mybatis基础操作
    腾讯云优惠券种类、领取方法及使用教程分享
    LCA 板子(最近公共祖先)
  • 原文地址:https://blog.csdn.net/kin_16/article/details/136261754