類似於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();
}