要想实现该功能,我们需要考虑一下几个问题。
1、如何获取鼠标的移动,点击,释放
通过实现一下几个事件来获取窗体的事件
void mouseMoveEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
2、如何判断鼠标是否移动到窗体的边界
一个窗体的结构大概如下图所示
上左 上 上右
左 中 右
下左 下 下右
那么我们用数字来表示如下
11 12 13
21 22 23
31 32 33
那么我们就得到鼠标在除了22的位置就到达了窗体的边界
上代码:
enum {
TOPLEFT = 11,
TOP = 12,
TOPRIGHT = 13,
LEFT = 21,
CENTER = 22,
RIGHT = 23,
BUTTOMLEFT = 31,
BUTTOM = 32,
BUTTOMRIGHT = 33
};
#define FRAMESHAPE 10
public:
void mouseMoveEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
int CalCursorCol(QPoint pt); //计算鼠标X的位置
int CalCursorPos(QPoint pt, int colPos); //计算鼠标的位置
void setCursorShape(int CalPos); //设置鼠标对应位置的形状
private:
int m_iCalCursorPos;
bool m_bLeftPress;
QRect m_rtPreGeometry;
QPoint m_ptViewMousePos;
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget),
m_bLeftPress(false)
{
ui->setupUi(this);
this->setWindowFlags(Qt::FramelessWindowHint); //取消窗体的标题栏
setMouseTracking(true); //MouseMoveEvent为了不太耗资源在默认状态下是要鼠标按下才能捕捉到,要想鼠标不按下时的移动也能捕捉到设置为true
}
Widget::~Widget()
{
delete ui;
}
void Widget::mouseMoveEvent(QMouseEvent *event)
{
//窗体不是最大的话就改变鼠标的形状
if(Qt::WindowMaximized != windowState())
{
setCursorShape(CalCursorPos(event->pos(),CalCursorCol(event->pos())));
}
//获取当前的点,这个点是全局的
QPoint ptCurrentPos = QCursor::pos();
//计算出移动的位置,当前点 - 鼠标左键按下的点
QPoint ptMoveSize = ptCurrentPos - m_ptViewMousePos;
QRect rtTempGeometry = m_rtPreGeometry;
if(m_bLeftPress)
{
switch(m_iCalCursorPos)
{
case TOPLEFT:
rtTempGeometry.setTopLeft(m_rtPreGeometry.topLeft()+ptMoveSize);
break;
case TOP:
rtTempGeometry.setTop(m_rtPreGeometry.top()+ptMoveSize.y());
break;
case TOPRIGHT:
rtTempGeometry.setTopRight(m_rtPreGeometry.topRight()+ptMoveSize);
break;
case LEFT:
rtTempGeometry.setLeft(m_rtPreGeometry.left()+ptMoveSize.x());
break;
case RIGHT:
rtTempGeometry.setRight(m_rtPreGeometry.right()+ptMoveSize.x());
break;
case BUTTOMLEFT:
rtTempGeometry.setBottomLeft(m_rtPreGeometry.bottomLeft()+ptMoveSize);
break;
case BUTTOM:
rtTempGeometry.setBottom(m_rtPreGeometry.bottom()+ptMoveSize.y());
break;
case BUTTOMRIGHT:
rtTempGeometry.setBottomRight(m_rtPreGeometry.bottomRight()+ptMoveSize);
break;
default:
break;
}
//移动窗体,如果比最小窗体大,就移动
if(rtTempGeometry.width() >= 200 && rtTempGeometry.height() >= 300)
setGeometry(rtTempGeometry);
}
}
void Widget::mousePressEvent(QMouseEvent *event)
{
m_iCalCursorPos = CalCursorPos(event->pos(),CalCursorCol(event->pos()));
if (event->button() == Qt::LeftButton /*&& Qt::WindowMaximized != windowState()*/)
{
if(m_iCalCursorPos != CENTER)
{
m_bLeftPress = true;
}
}
m_rtPreGeometry = geometry();
m_ptViewMousePos = event->globalPos();
}
void Widget::mouseReleaseEvent(QMouseEvent *event)
{
m_bLeftPress = false;
QApplication::restoreOverrideCursor();
}
int Widget::CalCursorCol(QPoint pt)
{
return (pt.x() < FRAMESHAPE ? 1 : ((pt.x() > this->width() - FRAMESHAPE) ? 3 : 2));
}
int Widget::CalCursorPos(QPoint pt, int colPos)
{
return ((pt.y() < FRAMESHAPE ? 10 : ((pt.y() > this->height() - FRAMESHAPE) ? 30 : 20)) + colPos);
}
void Widget::setCursorShape(int CalPos)
{
Qt::CursorShape cursor;
switch(CalPos)
{
case TOPLEFT:
case BUTTOMRIGHT:
cursor = Qt::SizeFDiagCursor;
break;
case TOPRIGHT:
case BUTTOMLEFT:
cursor = Qt::SizeBDiagCursor;
break;
case TOP:
case BUTTOM:
cursor = Qt::SizeVerCursor;
break;
case LEFT:
case RIGHT:
cursor = Qt::SizeHorCursor;
break;
default:
cursor = Qt::ArrowCursor;
break;
}
setCursor(cursor);
}