我正在参加「掘金·启航计划」
一、前言
二、分析
要实现这样的效果,首先需要监控鼠标按下、拖动、释放事件,可以获取鼠标的当前坐标,当前控件的大小,都是最基础的功能。
这里需要分两种情况,一种是改变大小,一种是改变位置,而且相应的鼠标样式也需要改变,所以我们在鼠标没有按下之前就需要鼠标的移动和坐标信息,这时候就需要setMouseTracking(true)来开启这个功能。
在按下之前,我们动态分析需要实现的功能,改变鼠标样式并记录功能类型,在鼠标按下之后,我们就不需要再次判断,只需要按照功能类型执行相应的功能即可。
三、实现
这是头文件里需要带的数据
.h
QPoint globalPos;
QSize basicSize;
bool pressed = false;
bool canMove = false;
uchar moveType = 0;
void mousePressEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent*) override;
这是实现代码
#include <QMouseEvent>
Widget::Widget(QWidget *parent) : QWidget(parent)
{
setMouseTracking(true);
}
void Widget::mousePressEvent(QMouseEvent *event)
{
pressed = true;
globalPos = event->globalPos();
basicSize = size();
}
void Widget::mouseMoveEvent(QMouseEvent *event)
{
if(pressed){
QPoint p = event->globalPos();
if(canMove){
QSize tempSize = basicSize;
if(moveType & 1){
int width = basicSize.width() + p.x() - globalPos.x();
tempSize.setWidth(width >= 50 ? width : 50);
}
if(moveType & 2){
int height = basicSize.height() + p.y() - globalPos.y();
tempSize.setHeight(height >= 50 ? height : 50);
}
resize(tempSize);
}else{
this->move(x() - globalPos.x() + p.x(), y() - globalPos.y() + p.y());
globalPos = p;
}
}else{
moveType = 3;
moveType &= (event->pos().x() + 10 >= width() ? 255 : 254);
moveType &= (event->pos().y() + 10 >= height() ? 255 : 253);
switch (moveType) {
case 0: setCursor(Qt::ArrowCursor);break;
case 1: setCursor(Qt::SizeHorCursor);break;
case 2: setCursor(Qt::SizeVerCursor);break;
case 3: setCursor(Qt::SizeFDiagCursor);break;
default: break;
}
canMove = (moveType > 0);
}
}
void Widget::mouseReleaseEvent(QMouseEvent*)
{
pressed = false;
}