Qt實現貼邊隱藏

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章