Qt鼠标跟踪

本文介绍了一个通过QLabel实现鼠标进入和离开区域时显示动画的效果。作者通过重写QLabel类,设置鼠标追踪并监听鼠标移动事件,当鼠标进入区域时开始动画(切换图片),离开时停止动画。关键点在于利用两个状态变量判断是否需要改变动画状态,并注意设置setMouseTracking(true)以确保鼠标移动事件能被正确触发。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、前言

最近一个小项目需要动画交互:鼠标进入区域,显示动画(循环);鼠标离开区域,停止动画;

思路:动画采用视频播放肯定不现实,所以改为QLabel切换图片来显示动画(有足够的视频帧)。继承QLabel重写显示动画的类,在内部定义一个区域变量、一个新状态变量、一个旧状态变量;


如果进入区域,则旧变量等于新变量,新变量为true;如果离开区域,则旧变量等于新变量,新变量为false;最后如果两个状态量不同,则说明需要改变:

  • 如果旧变量为false,新变量为true,则说明刚刚进入区域,播放动画;
  • 如果旧变量为true,新变量为false,则说明刚刚离开区域,停止动画;

!!!特别注意!!!
鼠标移动事件 mouseMoveEvent 默认需要点击之后移动才触发事件,设置setMouseTracking(true)之后才可以直接移动就触发事件,且不能是QMainWindow类,要用QWidget及其子类,此设置才管用!


二、效果展示

请添加图片描述


三、详细代码

#ifndef WIDGET_H
#define WIDGET_H

#include <QLabel>
#include <QDebug>
#include <QMouseEvent>
#include <QDialog>
#include <QHBoxLayout>

class Widget : public QLabel
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    QRect annimation_rect;
    bool old_flag;
    bool new_flag;

    QDialog* dialog;
    QLabel* label;

protected:
    void mouseMoveEvent(QMouseEvent *event);

signals:
    void sig_flag(bool);
};

#endif // WIDGET_H

#include "widget.h"

Widget::Widget(QWidget* parent) : QLabel(parent)
{
    this->setMouseTracking(true);	//必须设置这个mouseMoveEvent才不用点击鼠标之后才触发

    dialog = new QDialog(this);
    dialog->resize(200,300);
    dialog->setStyleSheet("background-color: red");
    dialog->setWindowFlag(Qt::WindowStaysOnTopHint);
    dialog->setWindowFlag(Qt::FramelessWindowHint);
    QHBoxLayout* layout_dialog = new QHBoxLayout(dialog);
    layout_dialog->setMargin(0);
    layout_dialog->setSpacing(0);

    label = new QLabel(dialog);
    layout_dialog->addWidget(label);
}
Widget::~Widget()
{

}

void Widget::mouseMoveEvent(QMouseEvent *event)
{
    QPoint mousePos = event->pos();

    if(annimation_rect.contains(mousePos)) {
        old_flag = new_flag;
        new_flag = true;
    }else {
       old_flag = new_flag;
       new_flag = false;
    }

    if(old_flag != new_flag) {
        if(old_flag && !new_flag) {
            sig_flag(false);
            dialog->hide();
        }
        if(!old_flag && new_flag) {
            sig_flag(true);
            label->setText("鼠标进入动画区域");
            dialog->show();
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

贝勒里恩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值