头文件
#ifndef ABSTRACTMAINWINDOW_H
#define ABSTRACTMAINWINDOW_H
#include <QMainWindow>
#include <QPainter>
#include <QPaintEvent>
#include <QStyleOption>
#include <QMouseEvent>
#include <QPoint>
#include <QResizeEvent>
class AbstractMainWindow : public QMainWindow
{
Q_OBJECT
enum CursorPosition
{
None
,
TopLeft
,
Top
,
TopRight
,
Right
,
BottomRight
,
Bottom
,
BottomLeft
,
Left
};
protected:
QPoint m_startPos
;
bool m_isPressed
= false;
bool m_followMouseMove
= false;
Qt
::CursorShape m_cursorShape
= Qt
::ArrowCursor
;
CursorPosition m_cursorPosition
= None
;
bool m_cursorShapeChangable
= true;
int m_deltaLength
= 10;
protected:
AbstractMainWindow(QWidget
* parent
= nullptr);
virtual bool construct();
bool event(QEvent
*event
);
void paintEvent(QPaintEvent
* e
);
void mousePressEvent(QMouseEvent
*event
);
void mouseReleaseEvent(QMouseEvent
*event
);
void mouseMoveEvent(QMouseEvent
*event
);
void setCursorShape(Qt
::CursorShape shape
);
public:
void setFollowMouseMove(bool value
);
void setCursorShapeChangable(bool value
);
};
#endif
源文件
#include "AbstractMainWindow.h"
#include <QDebug>
AbstractMainWindow
::AbstractMainWindow(QWidget
* parent
):QMainWindow(parent
)
{
setMouseTracking(true);
}
bool AbstractMainWindow
::construct()
{
return true;
}
bool AbstractMainWindow
::event(QEvent
*event
)
{
if(event
->type() == QEvent
::HoverMove
)
{
auto topLeftGPos
= this->pos();
auto topRightGPos
= QPoint(this->geometry().right(),y());
auto bottomRightGPos
= QPoint(this->geometry().right(),this->geometry().bottom());
auto bottomLeftGPos
= QPoint(x(),this->geometry().bottom());
auto event_pos
= cursor().pos();
if((topRightGPos
.x() - m_deltaLength
<= event_pos
.x()) && (event_pos
.x() <= topRightGPos
.x() + m_deltaLength
))
{
if(m_cursorShape
== Qt
::ArrowCursor
)
{
if((topRightGPos
.y() - m_deltaLength
<= event_pos
.y()) && (event_pos
.y() <= topRightGPos
.y() + m_deltaLength
))
{
m_cursorPosition
= TopRight
;
setCursorShape(Qt
::SizeBDiagCursor
);
}
else if((bottomRightGPos
.y() - m_deltaLength
<= event_pos
.y()) && (event_pos
.y() <= bottomRightGPos
.y() + m_deltaLength
))
{
m_cursorPosition
= BottomRight
;
setCursorShape(Qt
::SizeFDiagCursor
);
}
else
{
m_cursorPosition
= Right
;
setCursorShape(Qt
::SizeHorCursor
);
}
}
}
else if((topLeftGPos
.x() - m_deltaLength
<= event_pos
.x()) && (event_pos
.x() <= topLeftGPos
.x() + m_deltaLength
))
{
if(m_cursorShape
== Qt
::ArrowCursor
)
{
if((topLeftGPos
.y() - m_deltaLength
<= event_pos
.y()) && (event_pos
.y() <= topLeftGPos
.y() + m_deltaLength
))
{
m_cursorPosition
= TopLeft
;
setCursorShape(Qt
::SizeFDiagCursor
);
}
else if((bottomLeftGPos
.y() - m_deltaLength
<= event_pos
.y()) && (event_pos
.y() <= bottomLeftGPos
.y() + m_deltaLength
))
{
m_cursorPosition
= BottomLeft
;
setCursorShape(Qt
::SizeBDiagCursor
);
}
else
{
m_cursorPosition
= Left
;
setCursorShape(Qt
::SizeHorCursor
);
}
}
}
else if((topLeftGPos
.y() - m_deltaLength
<= event_pos
.y()) && (event_pos
.y() <= topLeftGPos
.y() + m_deltaLength
))
{
if(m_cursorShape
== Qt
::ArrowCursor
)
{
m_cursorPosition
= Top
;
setCursorShape(Qt
::SizeVerCursor
);
}
}
else if((bottomLeftGPos
.y() - m_deltaLength
<= event_pos
.y()) && (event_pos
.y() <= bottomLeftGPos
.y() + m_deltaLength
))
{
if(m_cursorShape
== Qt
::ArrowCursor
)
{
m_cursorPosition
= Bottom
;
setCursorShape(Qt
::SizeVerCursor
);
}
}
else
{
m_cursorPosition
= None
;
setCursorShape(Qt
::ArrowCursor
);
}
}
return QMainWindow
::event(event
);
}
void AbstractMainWindow
::paintEvent(QPaintEvent
* e
)
{
QStyleOption opt
;
opt
.init(this);
QPainter
p(this);
style()->drawPrimitive(QStyle
::PE_Widget
, &opt
, &p
, this);
(void)e
;
}
void AbstractMainWindow
::mousePressEvent(QMouseEvent
*event
)
{
QMainWindow
::mousePressEvent(event
);
if(m_followMouseMove
)
{
if(event
->button() == Qt
::LeftButton
)
{
m_isPressed
= true;
m_startPos
= event
->globalPos();
}
}
m_cursorShape
= cursor().shape();
}
void AbstractMainWindow
::mouseReleaseEvent(QMouseEvent
*event
)
{
if(m_followMouseMove
)
m_isPressed
= false;
QMainWindow
::mouseReleaseEvent(event
);
}
void AbstractMainWindow
::mouseMoveEvent(QMouseEvent
*event
)
{
if(m_followMouseMove
)
{
if(m_isPressed
)
{
if(m_cursorShape
== Qt
::ArrowCursor
)
{
auto offset
= event
->globalPos() - m_startPos
;
m_startPos
= event
->globalPos();
move(x() + offset
.x(),y() + offset
.y());
}
else
{
auto offset
= event
->globalPos() - m_startPos
;
m_startPos
= event
->globalPos();
switch(m_cursorPosition
)
{
case TopLeft
:
{
move(x() + offset
.x(),y() + offset
.y());
resize(width() - offset
.x(),height() - offset
.y());
break;
}
case Top
:
{
move(x(),y() + offset
.y());
resize(width(),height() - offset
.y());
break;
}
case TopRight
:
{
resize(width() + offset
.x(),height() - offset
.y());
break;
}
case Right
:
{
resize(width() + offset
.x(),height());
break;
}
case BottomRight
:
{
resize(width() + offset
.x(),height() + offset
.y());
break;
}
case Bottom
:
{
resize(width(),height() + offset
.y());
break;
}
case BottomLeft
:
{
move(x() + offset
.x(),y());
resize(width() - offset
.x(),height() + offset
.y());
break;
}
case Left
:
{
move(x() + offset
.x(),y());
resize(width() - offset
.x(),height());
break;
}
default:
break;
}
}
}
}
QMainWindow
::mouseMoveEvent(event
);
}
void AbstractMainWindow
::setFollowMouseMove(bool value
)
{
m_followMouseMove
= value
;
}
void AbstractMainWindow
::setCursorShapeChangable(bool value
)
{
m_cursorShapeChangable
= value
;
}
void AbstractMainWindow
::setCursorShape(Qt
::CursorShape shape
)
{
if(m_cursorShapeChangable
)
{
setCursor(shape
);
}
}
默认是不开启通过鼠标来移动窗口的,调用setFollowMouseMove(true)即可
QWidget同理,改个类名就行