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

前提

在开发一个类似qdesiger的项目中

使用QGraphicsProxyWidget将Qt基础控件作为item放在场景视图中显示和编辑

创建自定义类继承QGraphicsProxyWidget,管理控件

成员变量 有控件的xywh等,其中x、y坐标存储是基于最底层widgetitem
坐标系 x轴以右为正方向,y轴以下为正方向

首先鼠标悬浮在控件八个方位范围内时,显示对应的鼠标指针样式

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

cpp 复制代码
void ProxyClass::mousePressEvent(QGraphicsSceneMouseEvent *event)
cpp 复制代码
QPointF pos = event->pos();//Returns the mouse cursor position in item coordinates.
_pressPos= pos;

2.mouseMove事件

cpp 复制代码
void ProxyClass::mouseMoveEvent(QGraphicsSceneMouseEvent *event)

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

cpp 复制代码
  QPointF currentPos = event->pos();
  QPointF movePoint = currentPos - _pressPos;//移动区域  h↓ y↑

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

右下例:

cpp 复制代码
   		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;

左、上例:

得到控件高度的变化值 moveSize.y(),与原高度相减,得出此时修改后的高度值,也就是调整后的控件高度值;

与此同时,控件的y坐标也要发生改变,原y坐标+高度变化值 defaultWidgetY() + dy,

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

cpp 复制代码
		 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;

调用trySetGeometry函数具体设置控件的xywh

:setItemSize函数中默认有resize函数设置修改控件尺寸

:设置修改控件坐标时注意坐标系的转换 ,setpos(pos)的pos是基于父类图元的坐标

目前坐标 基于默认widgetItem ---[mapToScene]转换成---> 场景坐标 ---[mapToParent]--->相对该图元的父类图元坐标,然后使用setpos设置修改调整后的控件坐标!
注意:修改后的宽高不要小于控件的最小宽高值

cpp 复制代码
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);
        }
    }
}

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

相关推荐
WYH2878 分钟前
C#控制台输入(Read()、ReadKey()和ReadLine())
开发语言·c#
祈祷苍天赐我java之术10 分钟前
Java 迭代器(Iterator)详解
java·开发语言
秋氘渔26 分钟前
综合案例:Python 函数知识整合 — 学生成绩管理系统
开发语言·python
我命由我1234535 分钟前
软件开发 - 避免过多的 if-else 语句(使用策略模式、使用映射表、使用枚举、使用函数式编程)
java·开发语言·javascript·设计模式·java-ee·策略模式·js
long31644 分钟前
java 策略模式 demo
java·开发语言·后端·spring·设计模式
AI 嗯啦2 小时前
SQL详细语法教程(三)mysql的函数知识
android·开发语言·数据库·python·sql·mysql
GUET_一路向前3 小时前
【C语言】解释形参void *data用法
c语言·开发语言·通用指针
skywalk81634 小时前
转换一个python项目到moonbit,碰到报错输出:编译器对workflow.mbt文件中的类方法要求不一致的类型注解,导致无法正常编译
开发语言·moonbit·trae
DavieLau5 小时前
C#项目WCF接口暴露调用及SOAP接口请求测试(Python版)
xml·服务器·开发语言·python·c#
张人玉5 小时前
C#Encoding
开发语言·c#