自定义矩形可拖动及宽度大小的改变

//头文件

#pragma once

#include <QWidget>
#include "ui_Dlg_DayTime.h"
#include <QPainter>
#include <QJsonArray>
#include <QPixmap>
#include <QMap>
#define PADDING 6
enum Direction { UP = 0, DOWN = 1, LEFT, RIGHT, LEFTTOP, LEFTBOTTOM, RIGHTBOTTOM, RIGHTTOP, NONE };
class Dlg_DayTime : public QWidget
{
    Q_OBJECT

public:
    Dlg_DayTime(QWidget *parent = Q_NULLPTR);
    ~Dlg_DayTime();

    void paintEvent(QPaintEvent *event);

    void mousePressEvent(QMouseEvent *event);

    void mouseReleaseEvent(QMouseEvent *event);

    void mouseMoveEvent(QMouseEvent *event);

    void region(const QPoint &cursorGlobalPoint);

private:
    
    Ui::Dlg_DayTime ui;
    QJsonArray m_jsonArr;
    QPoint  m_curStartPos;
    QPoint  m_curEndPos;
    QPoint  m_tempPos;
    QPoint  m_movePos;

    bool    m_isPressed;

    int        m_nIndex;  
    QMap<int, QRect> m_map;
    Direction dir;        // 窗口大小改变时,记录改变方向
    int _startX;
    
};
 

//源文件

#include "Dlg_DayTime.h"
#include <QMouseEvent>
#include <QJsonDocument>
#include <QDebug>
Dlg_DayTime::Dlg_DayTime(QWidget *parent)
    : QWidget(parent), m_isPressed(false), m_nIndex(-1), m_movePos(0, 0)
    ,_startX(0)
{
    ui.setupUi(this);
    setPalette(QPalette(Qt::gray));
    this->setMouseTracking(true);
    setAutoFillBackground(true);
    setCursor(QCursor(Qt::ArrowCursor));
}

void Dlg_DayTime::region(const QPoint &cursorGlobalPoint)
{
    int nIndex = -1;
    for (int i = 0; i < m_map.size(); i++)
    {
        QRect tempRec = m_map[i];
        if (tempRec.contains(cursorGlobalPoint))
        {
            nIndex = i;
            break;
        }

    }
    if (nIndex == -1)
    {
        dir = NONE;
        this->setCursor(QCursor(Qt::ArrowCursor));
        return;
    }
    // 获取窗体在屏幕上的位置区域,tl为topleft点,rb为rightbottom点
    QRect rect = m_map[nIndex];
    QPoint tl = rect.topLeft();//mapToGlobal(rect.topLeft());
    QPoint rb = rect.bottomRight();//mapToGlobal(rect.bottomRight());

    int x = cursorGlobalPoint.x();
    int y = cursorGlobalPoint.y();
 
    QPoint tempLeftTopPoint = QPoint(tl.x() - PADDING, 0);
    QPoint tempRightBottomPoint = QPoint(tl.x(), size().height());
    QRect leftRec = QRect(tempLeftTopPoint, tempRightBottomPoint);

    QPoint tempRightPoint = QPoint(rb.x() - PADDING, 0);
    QRect rightRec = QRect(tempRightPoint, rb);

    if (leftRec.contains(cursorGlobalPoint))
    {
        dir = LEFT;
        this->setCursor(QCursor(Qt::SizeHorCursor));
    }
    else if (rightRec.contains(cursorGlobalPoint))
    {
        dir = RIGHT;
        this->setCursor(QCursor(Qt::SizeHorCursor));
    }
    //if (x <= tl.x() + PADDING && x >= tl.x()) {
    //    // 左边
    //    dir = LEFT;
    //    this->setCursor(QCursor(Qt::SizeHorCursor));
    //}
    //else if (x <= rb.x() && x >= rb.x() - PADDING) {
    //    // 右边
    //    qDebug() << "--------right-----------"<<x;
    //    dir = RIGHT;
    //    this->setCursor(QCursor(Qt::SizeHorCursor));
    //}
    else {
        // 默认
        dir = NONE;
        this->setCursor(QCursor(Qt::ArrowCursor));
    }
}
 

Dlg_DayTime::~Dlg_DayTime()
{
}

void Dlg_DayTime::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setBrush(Qt::blue);

    for (int i = 0; i < m_map.size(); i++)
    {
        painter.drawRect(m_map[i]);
    }
    
    //当前画的移动的数据
    if (m_curStartPos.x() > 0)
    {
        int x = m_curStartPos.x();
        int x2 = m_movePos.x();
        if ((x > x2) || !m_isPressed)
        {
            return;
        }

        int w = x2 - x;
        int h = this->size().height();

        painter.drawRect(x, 0, w, h);
    }

    QWidget::paintEvent(event);
}

void Dlg_DayTime::mousePressEvent(QMouseEvent *event)
{
    //判断是否已画的线上
    bool isOnRect = false;
    for (int i = 0; i < m_map.size(); i++)
    {
        QRect tempRec = m_map[i];
        if (tempRec.contains(event->pos()))
        {
            isOnRect = true;
            m_nIndex = i;
            _startX = tempRec.x();
        }

    }
    
    if (isOnRect)
    {
        m_tempPos = event->pos();
        //this->region(event->pos());
    }
    else
    {
        m_curStartPos = event->pos();
    }
    m_isPressed = true;
}

void Dlg_DayTime::mouseReleaseEvent(QMouseEvent *event)
{
    if (dir != NONE) {
        this->releaseMouse();
        this->setCursor(QCursor(Qt::ArrowCursor));
    }
    m_isPressed = false;
    if (m_nIndex != -1)
    {
        m_nIndex = -1;
        return;
    }

    m_curEndPos = event->pos();
    QRect rec;
    rec.setX(m_curStartPos.x());
    rec.setY(0);
    rec.setWidth(m_curEndPos.x() - m_curStartPos.x());
    rec.setHeight(size().height());

    static int nCount = 0;
    m_map.insert(nCount++, rec);

    m_curStartPos = QPoint(0, 0);
    m_curEndPos = QPoint(0, 0);
    m_movePos = QPoint(0, 0);
    
}


void Dlg_DayTime::mouseMoveEvent(QMouseEvent *event)
{
    QPoint mousePos = event->pos();
    if (!m_isPressed)
    {
        this->region(mousePos);
    }
    if (m_nIndex != -1 && m_isPressed)  //在矩形中
    {        
        int offset = mousePos.x() - m_tempPos.x(); //鼠标偏移量
        QPoint tl = m_map[m_nIndex].topLeft();//mapToGlobal(m_map[m_nIndex].topLeft());
        QPoint rb = m_map[m_nIndex].bottomRight();//mapToGlobal(m_map[m_nIndex].bottomRight());
        int nWidth = m_map[m_nIndex].width();
        if (dir != NONE) {
            QRect rMove(tl, rb);

            switch (dir) {
            case LEFT:
            {
                QPoint tempLeft = QPoint(mousePos.x(), 0);
                rMove = QRect(tempLeft, rb);
            }
                /*if (rb.x() - mousePos.x() <= nWidth)
                {
                QPoint tempLeft = QPoint(mousePos.x(), 0);
                rMove = QRect(tempLeft, rb);
                }
                else
                {
                rMove.setX(mousePos.x());
                }*/
                break;
            case RIGHT:
            {
                QPoint rb = QPoint(mousePos.x(), size().height());
                rMove = QRect(tl, rb);
            }
                //rMove.setWidth(mousePos.x() - tl.x());
                break;
            default:
                break;
            }
            m_map[m_nIndex] = rMove;
            
        }
        else
        {
            //重新设置
            int width = m_map[m_nIndex].width();
            m_map[m_nIndex].setX(_startX + offset);
            m_map[m_nIndex].setWidth(width);
        }
        m_curStartPos = QPoint(0, 0);
        m_curEndPos = QPoint(0, 0);
        m_movePos = QPoint(0, 0);
    }
    else if (m_isPressed)  //不在矩形中
    {
        m_movePos = mousePos;
    }
    

    this->update();

}
 

效果如下所示:蓝色的宽度可变化

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值