简单无边框窗口复习QT事件

通过一个简单的无边框事件来复习下相关事件

该窗口可以点击鼠标右键按下后退出:

鼠标可以拖动窗口:

鼠标移动到窗口边缘,鼠标形状发生改变:

鼠标可以拉动缩放窗口:

1、去掉窗口自带标题栏

首先去掉窗口自带的标题栏,在构造函数中调用相关函数如下:

//去掉窗口自带的标题栏
setWindowFlag(Qt::FramelessWindowHint);

2、实现鼠标右键按下退出

然后重写鼠标按下事件,右键按下时,窗口关闭:

void mousePressEvent(QMouseEvent* ev) override
    {
        switch (ev->button()) {
        case Qt::RightButton:
            //如果按下了右键,那么窗口关闭
            close();
            break;
        default:
            break;
        }
    }

3.然后实现拖动窗口

首先在鼠标按下事件中,我们要记录鼠标在窗口中按下的一个相对位置,然后记录一下鼠标是左键按下的,这个位置的作用就是为了保持窗口跟着鼠标移动的过程中,鼠标和窗口始终保持着按下时的那个相对位置。

重写鼠标按下事件:

void mousePressEvent(QMouseEvent* ev) override
    {
        switch (ev->button()) {
        case Qt::RightButton:
            //如果按下了右键,那么窗口关闭
            close();
            break;
        case Qt::LeftButton:
            //pos()方法就是获取鼠标按下时在窗口里面的相对位置
            mouse_offset=ev->pos();
            left_button_pressed=true;
            break;
        default:
            break;
        }
    }

然后我们对窗口进行一个分区:

显然,鼠标只有在中间区域按下,而且还是左键按下,然后移动鼠标,窗口才会跟着移动

我们先定义一个枚举来表示这些区域,然后用一个成员变量来记录鼠标所在区域

enum Position
{
    NONE,
    TOP,
    BOTTOM,
    LEFT,
    RIGHT,
    TOP_LEFT,
    TOP_RIGHT,
    BOTTOM_LEFT,
    BOTTOM_RIGHT,
    CENTER
};

然后我们重写鼠标移动事件:

void mouseMoveEvent(QMouseEvent* ev)override
    {
        //鼠标左键按下,且鼠标按下时鼠标所在的区域为中间
        if(left_button_pressed&& mouse_location==Position::CENTER)
        {
            //窗口直接移动到鼠标在全屏的位置-按下时的相对位置处
            move(ev->globalPos()-mouse_offset);
        }
    }

然后重写鼠标释放事件,将左键是否按下这个成员变量置为false就可以了

void mouseReleaseEvent(QMouseEvent* ev) override
    {
        left_button_pressed=false;
    }

4、然后实现鼠标放到窗口边缘处时光标形状改变

 同样的,我们需要重写鼠标移动事件,鼠标移动到对应的区域时,光标就变成对应的形状,且把鼠标所在的区域置为对应的区域

由于这个鼠标光标改变只需要移动到对应区域就变化而不需要按下,所以要先设置鼠标追踪,这样鼠标移动事件的产生只需要鼠标移动就可以产生,而不是鼠标按下后再移动才产生。直接在构造函数中调用相关方法:

setMouseTracking(true);

然后我们继续重写鼠标移动事件:

获取鼠标在全屏的位置,然后获取窗口左上角和右下角在窗口的全屏位置,通过判断鼠标位置的x和y值是否在对应区域(对应区域的x和y的范围就是根据窗口的左上角和右下角这两个坐标的x,y值和padding值来决定),来设置成对应的光标形状:

void mouseMoveEvent(QMouseEvent* ev)override
    {
        //鼠标左键没有按下,仅仅只是在窗口里面移动,那么变换坐标
        if(!left_button_pressed)
        {
            //封成一个成员函数
            setCursorShape(ev->globalPos());
        }

        //鼠标左键按下,且鼠标按下时鼠标所在的区域为中间
        if(left_button_pressed&& mouse_location==Position::CENTER)
        {
            //窗口直接移动到鼠标在全屏的位置-按下时的相对位置处
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值