类似于qq,当窗口移动到桌面上边缘时,鼠标离开窗口,窗口将会自动向上隐藏,当鼠标回到靠边的位置,窗口又显示出来。
- 先看效果图:
代码如下 :
- widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
enum HIDEPOSATION//隐藏位置
{
HP_None = 0,
HP_Top = 1,
HP_Left = 2,
HP_Right = 3
};
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
bool isWindowInScreen(QPoint pos);
void hideWindow();
void showWindow();
protected:
void mousePressEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
void enterEvent(QEvent *event) override;
void leaveEvent(QEvent *event) override;
private:
int m_screenWidth;
bool m_isLMousePress;
QPoint m_relativePos;
HIDEPOSATION m_hp;
};
#endif // WIDGET_H
- widget.cpp
#include "widget.h"
#include <QMouseEvent>
#include <QPropertyAnimation>
#include <QApplication>
#include <QScreen>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, m_isLMousePress(false)
, m_relativePos(0,0)
{
//获取桌面宽度
QRect rect = QGuiApplication::primaryScreen()->geometry();
m_screenWidth = rect.width();
setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
resize(450,650);
}
//判断当前鼠标位置,并根据位置确定信息
bool Widget::isWindowInScreen(QPoint pos)
{
if(pos.x()<5){
m_hp = HP_Left;
return false;
}
else if(pos.x()>m_screenWidth-5){
m_hp = HP_Right;
return false;
}
else if(pos.y()<5){
m_hp = HP_Top;
return false;
}
else{
m_hp = HP_None;
return true;
}
}
//隐藏窗口的动画
void Widget::hideWindow()
{
QPropertyAnimation * animation = new QPropertyAnimation(this, "geometry");
animation->setStartValue(QRect(x(),y(),width(),height()));
if(m_hp == HP_Top)
animation->setEndValue(QRect(x(),2-height(),width(),height()));
else if(m_hp == HP_Left)
animation->setEndValue(QRect(2-width(),y(),width(),height()));
else if(m_hp == HP_Right)
animation->setEndValue(QRect(m_screenWidth-2,y(),width(),height()));
animation->setDuration(250);
animation->start();
}
//显示窗口的动画
void Widget::showWindow()
{
QPropertyAnimation * animation = new QPropertyAnimation(this, "geometry");
animation->setStartValue(QRect(x(),y(),width(),height()));
if(m_hp == HP_Top)
animation->setEndValue(QRect(x(),0,width(),height()));
else if(m_hp == HP_Left)
animation->setEndValue(QRect(0,y(),width(),height()));
else if(m_hp == HP_Right)
animation->setEndValue(QRect(m_screenWidth-width(),y(),width(),height()));
animation->setDuration(250);
animation->start();
}
void Widget::mousePressEvent(QMouseEvent *event)
{
if(event->button() == Qt::LeftButton)
{
m_isLMousePress = true;
m_relativePos = event->globalPos() - pos();//记录相对位置
}
}
void Widget::mouseReleaseEvent(QMouseEvent *event)
{
Q_UNUSED(event)
m_isLMousePress = false;
}
void Widget::mouseMoveEvent(QMouseEvent *event)
{
if(m_isLMousePress && isWindowInScreen(event->globalPos()))
move(event->globalPos()-m_relativePos);//实现无边框移动
else if(m_isLMousePress && !isWindowInScreen(event->globalPos()))
{
//特殊位置,移动规则不同
int x = event->globalPos().x();
int y = event->globalPos().y();
if(m_hp == HP_Top)//比如当前鼠标位置为屏幕最上面时,将纵坐标拉至鼠标处,此后只改变横坐标
move(x-m_relativePos.x(),y);
else if(m_hp == HP_Left)
move(x,y-m_relativePos.y());
else if(m_hp == HP_Right)
move(x-width(),y-m_relativePos.y());
}
}
void Widget::enterEvent(QEvent *event)
{
Q_UNUSED(event)
if(m_hp != HP_None)
showWindow();
}
void Widget::leaveEvent(QEvent *event)
{
Q_UNUSED(event)
if(m_hp != HP_None)
hideWindow();
}