Qt无边框窗口实现拖动和改变大小

主要参考了https://blog.csdn.net/qq_16952303/article/details/51974502?locationNum=8&fps=1,但原文章在某些情况下,鼠标形状不刷新,改进了一版。

MyResizeWidget.h

#ifndef MYRESIZEWIDGET_H
#define MYRESIZEWIDGET_H

#include 

#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);
}

你可能感兴趣的:(c++,#,qt,qt,窗口,拖动,移动,边框)