QT 鼠标移动 旋转矩形

1. 鼠标移动矩形:

在鼠标移动函数中 mouseMoveEvent 中

获得鼠标移动的位置. 

 

在  绘图 函数 paintEvent中

根据获得到的位置为左上角顶点画矩形.

 

2. 鼠标移动矩形

在鼠标移动函数中 mouseMoveEvent 中

获得鼠标移动的位置 移动点C.  

根据矩形起始点B 和宽高计算中心点A, 

由3点 获得 向量 AB 和 AC 

根据向量叉乘获得,鼠标移动方向. 正为顺时针,负逆时针

根据余弦公式 获得夹角cos值.

根据反函数获得角度值  角度 = acos(cos值) * 180 / 3.1415926

将 C的值 复制给 B 替换

 

在  绘图 函数 paintEvent中

使用  translate : 绕那个点旋转
使用 rotate: 旋转多少度 

函数 进行对矩形的旋转

 

目前这份代码只能通过左上角的点来进行 移动旋转

#pragma once
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QMenu>

class Widget : public QWidget
{
    Q_OBJECT
public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
    void init(); 
protected:
    void paintEvent(QPaintEvent *event);  //绘图事件
    void mouseReleaseEvent(QMouseEvent *event);//鼠标释放事件
    void mousePressEvent(QMouseEvent *event);//鼠标单击事件
    void mouseMoveEvent(QMouseEvent *event);//鼠标移动事件
    
private:

    struct Point
    {
        int x;
        int y;
        Point()
        {
            x = 0;
            y = 0;
        }
    };


    Point start;

    // 是否修改样式 与 是否计算角度
    int judgeValue;

    // 鼠标样式
    int m_mouse_style; 

    // 旋转角度值
    double RotateAngle;

    // 形状宽高, 正方形
    int width;

    /// 当前鼠标左键还是右键, false 右键
    bool keyValue;

};

 

#include "a.h"
#include <QMouseEvent>
#include <QPainter>
#include <QPaintEvent>
#include <QPen>
#include <math.h>


Widget::Widget(QWidget *parent) :
    QWidget(parent)
{
    
    setMouseTracking(true);
    init(); 
    width = 220;
    RotateAngle = 0;
    keyValue = false;
}
Widget::~Widget()
{
    
}
void Widget::init() 
{
    judgeValue = 0;  
    m_mouse_style = 0;    

    start.x = 100;
    start.y = 100;
}

void Widget::mouseMoveEvent(QMouseEvent *event) 
{
    judgeValue = 0; 
    
    if (fabs(event->pos().x() - start.x) <= 5 && fabs(event->pos().y() - start.y) <= 5) 
    {
        judgeValue = judgeValue + 1;
    }
    
    if (judgeValue != 0)
    {
        setCursor(Qt::CrossCursor);          
    }
    else
    {
        setCursor(Qt::ArrowCursor);        
    }

    if (m_mouse_style == 1 && keyValue)
    {  
        //改变点的位置
        
        Point stop;
        stop.x = event->pos().x();
        stop.y = event->pos().y();

        Point center;
        center.x = start.x + width / 2;
        center.y = start.y + width / 2;

        // 向量
        // 中心点和起始点向量
        Point cstart;
        cstart.x = start.x - center.x;
        cstart.y = start.y - center.y;

        // 中心点和结束点的向量
        Point cstop;
        cstop.x = stop.x - center.x;
        cstop.y = stop.y - center.y;

        // 计算叉乘,逆时针还是顺时针旋转
        int dircet = (cstart.x * cstop.y) - (cstart.y * cstop.x);

        /// 求夹角
        double lengthCstart = sqrt(pow(center.x - start.x, 2) +
            pow(center.y - start.y, 2));
        double lengthCstop = sqrt(pow(center.x - stop.x, 2) +
            pow(center.y - stop.y, 2));
        double lengthStartStop = sqrt(pow(start.x - stop.x, 2) +
            pow(start.y - stop.y, 2));

        //  方法1 余弦定理求出旋转角
        double cosr = (pow(lengthCstart, 2) + pow(lengthCstop, 2) - pow(lengthStartStop, 2)) /
            (2 * lengthCstart * lengthCstop);                 

        /// 方法2 使用向量计算
        //double cosr = (cstart.x* cstop.x + cstart.y * cstop.y) / (sqrt(pow(cstop.x, 2) + pow(cstop.y, 2)) * sqrt(pow(cstart.x, 2) + pow(cstart.y, 2)));
        
        double angle = acos(cosr) * 180 / 3.1415926;
        

        if (dircet < 0)
        {    
            RotateAngle -= angle;
        }
        else
        {
            RotateAngle += angle;
        }    
        
        /// 修改起始点
        start.x = stop.x;
        start.y = stop.y;

        
    }
    else if (m_mouse_style == 1 && !keyValue)
    {
        start.x = event->pos().x();
        start.y = event->pos().y();
    }

    update();
}
void Widget::mousePressEvent(QMouseEvent *event) 
{

    if (event->button() == Qt::LeftButton || event->button() == Qt::RightButton)
    {  
        
        if (fabs(event->pos().x() - start.x) <= 5 && fabs(event->pos().y() - start.y) <= 5) 
        {
            m_mouse_style = 1;
            setCursor(Qt::CrossCursor);
        }

        if (event->button() != Qt::LeftButton)
        {
            keyValue = false;
        }
        else
        {
            keyValue = true;
        }
        
    }
    else 
    {
        setCursor(Qt::ArrowCursor);
    }
}
void Widget::mouseReleaseEvent(QMouseEvent *event) 
{
    
    m_mouse_style = 0;
    setCursor(Qt::ArrowCursor);
    update();
}

void Widget::paintEvent(QPaintEvent *event)
{    
    QPainter painters(this);

    // 画操作点
    QPen pen; 
    pen.setColor(Qt::red); 
    pen.setWidth(5);  
    painters.setPen(pen);    
     painters.drawPoint(start.x, start.y);
     
    /// 画线
    QPen pen1; 
    pen1.setWidth(2);
    pen1.setColor(Qt::blue);
    painters.setPen(pen1);
    
    int cx = start.x + width/2;
    int cy = start.y + width / 2;
    
    /// 画一个中心点
    painters.drawPoint(cx, cy);

    QRect rotatedRect(-width / 2, -width / 2, width, width);
    painters.save();
    painters.translate(QPoint(cx, cy));        
    painters.rotate(RotateAngle);
    painters.drawRoundRect(rotatedRect, 50, 50);        
    painters.restore();        
    

}
 

 

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值