Qt实现贴边隐藏

类似于qq,当窗口移动到桌面上边缘时,鼠标离开窗口,窗口将会自动向上隐藏,当鼠标回到靠边的位置,窗口又显示出来。

  • 先看效果图:
    Qt实现贴边隐藏

代码如下 :
Qt实现贴边隐藏

  • 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();
}

上一篇:实验五


下一篇:【ICPC2015沈阳M】Meeting