主要参考了https://blog.csdn.net/qq_16952303/article/details/51974502?locationNum=8&fps=1,但原文章在某些情况下,鼠标形状不刷新,改进了一版。
MyResizeWidget.h
#ifndef MYRESIZEWIDGET_H
#define MYRESIZEWIDGET_H
#include <QtGui>
#define EDGE_MARGIN 8
namespace Ui {
class MyResizeWidget;
}
class MyResizeWidget : public QWidget
{
Q_OBJECT
public:
explicit MyResizeWidget(QWidget *parent = 0);
protected:
virtual void mouseMoveEvent(QMouseEvent * event);
virtual void mousePressEvent(QMouseEvent * event);
virtual void mouseReleaseEvent(QMouseEvent * event);
virtual void enterEvent(QEvent * event);
virtual void leaveEvent(QEvent * event);
private:
QPoint dragPosition; //鼠标拖动的位置
enum {nodir,
top = 0x01,
bottom = 0x02,
left = 0x04,
right = 0x08,
topLeft = 0x01 | 0x04,
topRight = 0x01 | 0x08,
bottomLeft = 0x02 | 0x04,
bottomRight = 0x02 | 0x08
} resizeDir; //更改尺寸的方向
private:
void testEdge(QMouseEvent *event); //检测鼠标是否接近窗口边缘
};
#endif // SEARCHWIDGET_H
MyResizeWidget.cpp
#include "MyResizeWidget.h"
#define min(a,b) ((a)<(b)? (a) :(b))
#define max(a,b) ((a)>(b)? (a) :(b))
MyResizeWidget::MyResizeWidget(QWidget *parent)
: QWidget(parent)
{
resizeDir = nodir; //初始化检测方向为无
setWindowFlags(Qt::FramelessWindowHint); //设置无边框
setMouseTracking(true); //开启鼠标追踪
setMinimumSize(90, 200);
}
void MyResizeWidget::mousePressEvent(QMouseEvent * event)
{
if (event->button() == Qt::LeftButton) //每当按下鼠标左键就记录一下位置
{
dragPosition = event->globalPos() - frameGeometry().topLeft(); //获得鼠标按键位置相对窗口左上面的位置
}
}
void MyResizeWidget::testEdge(QMouseEvent *event)
{
int diffLeft = event->globalPos().x() - frameGeometry().left(); //计算鼠标距离窗口上下左右有多少距离
int diffRight = event->globalPos().x() - frameGeometry().right();
int diffTop = event->globalPos().y() - frameGeometry().top();
int diffBottom = event->globalPos().y() - frameGeometry().bottom();
Qt::CursorShape cursorShape;
if(diffTop < EDGE_MARGIN && diffTop>=0){ //根据 边缘距离 分类改变尺寸的方向
if(diffLeft < EDGE_MARGIN && diffLeft>=0){
resizeDir = topLeft;
cursorShape = Qt::SizeFDiagCursor;
}
else if(diffRight > -EDGE_MARGIN && diffRight<=0){
resizeDir = topRight;
cursorShape = Qt::SizeBDiagCursor;
}
else{
resizeDir = top;
cursorShape = Qt::SizeVerCursor;
}
}
else if(abs(diffBottom) < EDGE_MARGIN && diffBottom<=0){
if(diffLeft < EDGE_MARGIN && diffLeft>=0){
resizeDir = bottomLeft;
cursorShape = Qt::SizeBDiagCursor;
}
else if(diffRight > -EDGE_MARGIN && diffRight<=0){
resizeDir = bottomRight;
cursorShape = Qt::SizeFDiagCursor;
}
else{
resizeDir = bottom;
cursorShape = Qt::SizeVerCursor;
}
}
else if(abs(diffLeft) < EDGE_MARGIN){
resizeDir = left;
cursorShape = Qt::SizeHorCursor;
}
else if(abs(diffRight) < EDGE_MARGIN){
resizeDir = right;
cursorShape = Qt::SizeHorCursor;
}
else{
resizeDir = nodir;
cursorShape = Qt::ArrowCursor;
}
QApplication::setOverrideCursor(cursorShape);
}
void MyResizeWidget::mouseMoveEvent(QMouseEvent * event)
{
if (event->buttons() & Qt::LeftButton){ //如果左键是按下的
if(resizeDir == nodir){ //如果鼠标不是放在边缘那么说明这是在拖动窗口
move(event->globalPos() - dragPosition);
}
else{
int ptop,pbottom,pleft,pright; //窗口上下左右的值
ptop = frameGeometry().top();
pbottom = frameGeometry().bottom();
pleft = frameGeometry().left();
pright = frameGeometry().right();
if(resizeDir & top){ //检测更改尺寸方向中包含的上下左右分量
if(height() == minimumHeight()){
ptop = min(event->globalY(),ptop);
}
else if(height() == maximumHeight()){
ptop = max(event->globalY(),ptop);
}
else{
ptop = event->globalY();
}
}
else if(resizeDir & bottom){
if(height() == minimumHeight()){
pbottom = max(event->globalY(),ptop);
}
else if(height() == maximumHeight()){
pbottom = min(event->globalY(),ptop);
}
else{
pbottom = event->globalY();
}
}
if(resizeDir & left){ //检测左右分量
if(width() == minimumWidth()){
pleft = min(event->globalX(),pleft);
}
else if(width() == maximumWidth()){
pleft = max(event->globalX(),pleft);
}
else{
pleft = event->globalX();
}
}
else if(resizeDir & right){
if(width() == minimumWidth()){
pright = max(event->globalX(),pright);
}
else if(width() == maximumWidth()){
pright = min(event->globalX(),pright);
}
else{
pright = event->globalX();
}
}
setGeometry(QRect(QPoint(pleft,ptop),QPoint(pright,pbottom)));
}
}
else testEdge(event); //当不拖动窗口、不改变窗口大小尺寸的时候 检测鼠标边缘
}
void MyResizeWidget::mouseReleaseEvent(QMouseEvent *event)
{
if(resizeDir != nodir){ //还原鼠标样式
testEdge(event);
}
}
void MyResizeWidget::enterEvent(QEvent * event)
{
QWidget::enterEvent(event);
}
void MyResizeWidget::leaveEvent(QEvent * event)
{
QApplication::setOverrideCursor(Qt::IBeamCursor);
QWidget::leaveEvent(event);
}