Qt——鼠标拖动缩放窗口源码

#ifndef MOVEWIDGET_H
#define MOVEWIDGET_H

#include <QWidget>
#include <QEvent>

class MoveWidget : public QWidget
{
	Q_OBJECT

public:
	MoveWidget(QWidget *parent);
	~MoveWidget();
	void setResizable(bool bResiable);	//设置是否可以缩放
	void setMargin(const int &);		//设置鼠标距离界面边缘的范围

protected:
	virtual bool eventFilter(QObject *, QEvent *);

private:
	void changeMouseStyle(const QPoint &);
private:
	bool m_bResizable;	//界面是否可以缩放
	int m_iMarginWidth;	//鼠标位置相对于界面边缘的距离
	bool m_bPressed;	//鼠标是否按下
	QPoint m_ptPressPos;//鼠标按下时的位置
};

#endif // MOVEWIDGET_H

  

#include "MoveWidget.h"
#include <QHoverEvent>

enum MouseStyle{ NORMAL, TOP, BOTTOM, LEFT, RIGHT, TOPLEFT, BOTTOMLEFT, BOTTOMRIGHT, TOPRIGHT } mouseStyle;

MoveWidget::MoveWidget(QWidget *parent)
	: QWidget(parent)
	, m_bResizable(true)
	, m_iMarginWidth(6)
	, m_bPressed(false)
	, m_ptPressPos(0, 0)
{
	this->setWindowFlags(Qt::FramelessWindowHint | Qt::Window);
	this->setAttribute(Qt::WA_Hover);
	this->installEventFilter(this);
}

MoveWidget::~MoveWidget()
{

}

bool MoveWidget::eventFilter(QObject *, QEvent *event)
{
	switch (event->type())
	{
		//[1]鼠标在界面上移动
		case QEvent::HoverMove:
		{
			QHoverEvent *hoverEvent = dynamic_cast<QHoverEvent *>(event);
			if (!m_bPressed)
			{
				changeMouseStyle(hoverEvent->pos());
			}
			else
			{
				if (mouseStyle == NORMAL)
				{
					this->move(this->mapToGlobal(hoverEvent->pos()) - m_ptPressPos);
					return true;
				}
				QPoint ptGlobalPos = this->mapToGlobal(hoverEvent->pos());
				QPoint ptTopLeft = this->frameGeometry().topLeft();
				QPoint ptBottomRight = this->frameGeometry().bottomRight();
				switch (mouseStyle)
				{
				case TOP:
					if (ptBottomRight.y() - ptGlobalPos.y() > this->minimumHeight())
					{
						ptTopLeft.setY(ptGlobalPos.y());
					}
					else
					{
						ptTopLeft.setY(ptBottomRight.y() - this->minimumHeight());
					}
					break;
				case BOTTOM:
					if (ptGlobalPos.y() - ptTopLeft.y() > this->minimumHeight())
					{
						ptBottomRight.setY(ptGlobalPos.y());
					}
					else
					{
						ptBottomRight.setY(ptTopLeft.y() + this->minimumHeight());
					}
					break;
				case LEFT:
					if (ptBottomRight.x() - ptGlobalPos.x() > this->minimumWidth())
					{
						ptTopLeft.setX(ptGlobalPos.x());
					}
					else
					{
						ptTopLeft.setX(ptBottomRight.x() - this->minimumWidth());
					}
					break;
				case RIGHT:
					if (ptGlobalPos.x() - ptTopLeft.x() > this->minimumWidth())
					{
						ptBottomRight.setX(ptGlobalPos.x());
					}
					else
					{
						ptBottomRight.setX(ptTopLeft.x() + this->minimumWidth());
					}
					break;
				case TOPLEFT:
					if (ptBottomRight.x() - ptGlobalPos.x() > this->minimumWidth())
					{
						ptTopLeft.setX(ptGlobalPos.x());
					}
					else
					{
						ptTopLeft.setX(ptBottomRight.x() - this->minimumWidth());
					}
					if (ptBottomRight.y() - ptGlobalPos.y() > this->minimumHeight())
					{
						ptTopLeft.setY(ptGlobalPos.y());
					}
					else
					{
						ptTopLeft.setY(ptBottomRight.y() - this->minimumHeight());
					}
					break;
				case BOTTOMLEFT:
					if (ptBottomRight.x() - ptGlobalPos.x() > this->minimumWidth())
					{
						ptTopLeft.setX(ptGlobalPos.x());
					}
					else
					{
						ptTopLeft.setX(ptBottomRight.x() - this->minimumWidth());
					}
					if (ptGlobalPos.y() - ptTopLeft.y() > this->minimumHeight())
					{
						ptBottomRight.setY(ptGlobalPos.y());
					}
					else
					{
						ptBottomRight.setY(ptTopLeft.y() + this->minimumHeight());
					}
					break;
				case BOTTOMRIGHT:
					if (ptGlobalPos.x() - ptTopLeft.x() > this->minimumWidth())
					{
						ptBottomRight.setX(ptGlobalPos.x());
					}
					else
					{
						ptBottomRight.setX(ptTopLeft.x() + this->minimumWidth());
					}
					if (ptGlobalPos.y() - ptTopLeft.y() > this->minimumHeight())
					{
						ptBottomRight.setY(ptGlobalPos.y());
					}
					else
					{
						ptBottomRight.setY(ptTopLeft.y() + this->minimumHeight());
					}
					break;
				case TOPRIGHT:
					if (ptBottomRight.y() - ptGlobalPos.y() > this->minimumHeight())
					{
						ptTopLeft.setY(ptGlobalPos.y());
					}
					else
					{
						ptTopLeft.setY(ptBottomRight.y() - this->minimumHeight());
					}
					if (ptGlobalPos.x() - ptTopLeft.x() > this->minimumWidth())
					{
						ptBottomRight.setX(ptGlobalPos.x());
					}
					else
					{
						ptBottomRight.setX(ptTopLeft.x() + this->minimumWidth());
					}
					break;
				default:
					break;
				}
				this->setGeometry(QRect(ptTopLeft, ptBottomRight));
			}
			return true;
		}
		break;
		//[1]end 鼠标在界面上移动

		//[2]鼠标按下
		case QEvent::MouseButtonPress:
		{
			m_bPressed = true;
			QMouseEvent *mouseEvent = dynamic_cast<QMouseEvent *>(event);
			m_ptPressPos = mouseEvent->globalPos() - this->frameGeometry().topLeft();
		}
		break;
		//[2]end 鼠标按下

		//[3]鼠标松开
		case QEvent::MouseButtonRelease:
		{
			m_bPressed = false;
			QMouseEvent *mouseEvent = dynamic_cast<QMouseEvent *>(event);
			changeMouseStyle(mouseEvent->pos());
		}
		break;
		//[3]end 鼠标松开

		default:
		break;
	}
	return false;
}

void MoveWidget::changeMouseStyle(const QPoint &ptMousePos)
{
	if (!m_bResizable)
	{
		setCursor(Qt::ArrowCursor);//正常样式
		mouseStyle = NORMAL;
		return;
	}
	int iPosX = ptMousePos.x();
	int iPosY = ptMousePos.y();

	int iWidth = this->width();
	int iHeight = this->height();
	if (iPosX >= iWidth - m_iMarginWidth && iPosX <= iWidth)
	{
		setCursor(Qt::SizeHorCursor);//右
		if (iPosY >= 0 && iPosY <= m_iMarginWidth)
		{
			setCursor(Qt::SizeBDiagCursor);//右上
			mouseStyle = TOPRIGHT;
			return;
		}
		if (iPosY >= iHeight - m_iMarginWidth && iPosY <= iHeight)
		{
			setCursor(Qt::SizeFDiagCursor);//右下
			mouseStyle = BOTTOMRIGHT;
			return;
		}
		mouseStyle = RIGHT;
		return;
	}

	if (iPosX >= 0 && iPosX <= m_iMarginWidth)
	{
		setCursor(Qt::SizeHorCursor);//左
		if (iPosY >= 0 && iPosY <= m_iMarginWidth)
		{
			setCursor(Qt::SizeFDiagCursor);//左上
			mouseStyle = TOPLEFT;
			return;
		}
		if (iPosY >= iHeight - m_iMarginWidth && iPosY <= iHeight)
		{
			setCursor(Qt::SizeBDiagCursor);//左下
			mouseStyle = BOTTOMLEFT;
			return;
		}
		mouseStyle = LEFT;
		return;
	}

	if (iPosY >= 0 && iPosY <= m_iMarginWidth)
	{
		setCursor(Qt::SizeVerCursor);//上
		mouseStyle = TOP;
		return;
	}
	if (iPosY >= iHeight - m_iMarginWidth && iPosY <= iHeight)
	{
		setCursor(Qt::SizeVerCursor);//下
		mouseStyle = BOTTOM;
		return;
	}
	setCursor(Qt::ArrowCursor);//正常样式
	mouseStyle = NORMAL;
	return;
}

void MoveWidget::setResizable(bool bResiable)
{
	m_bResizable = bResiable;
}

void MoveWidget::setMargin(const int &iWidth)
{
	m_iMarginWidth = iWidth;
}

  

posted @ 2016-01-02 17:11  去冰三分糖  阅读(514)  评论(0编辑  收藏  举报