(十三)事件分发器——event()函数,事件过滤

事件分发器——event()函数

事件过滤

事件进入窗口之前被拦截 eventFilter

#include "mywidget.h"
#include "ui_mywidget.h"
#include <QDebug>

MyWidget::MyWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MyWidget)
{
    ui->setupUi(this);
    // 给MyLabel 安装事件过滤器
    // 参数 谁来过滤label 的事件
    ui->mylabel->installEventFilter(this);
    ui->label_2->installEventFilter(this);
}

MyWidget::~MyWidget()
{
    delete ui;
}

void MyWidget::mousePressEvent(QMouseEvent *)
{
    qDebug() << "+++++++++++++";
}

bool MyWidget::eventFilter(QObject *obj, QEvent *e)
{
    // 判断对象
    if (obj == ui->mylabel) {
        // 过滤事件
        if (e->type() == QEvent::MouseMove)
        {
            ui->mylabel->setText("++++++++++");
            return true;
        }
    }
    if (obj == ui->label_2) {
        if (e->type() == QEvent::MouseMove)
        {
            ui->label_2->setText("**********");
            return true;
        }
    }
    // 执行默认处理
    return QWidget::eventFilter(obj,e);
}

mywidget.cpp

#include "mylabel.h"
#include <QMouseEvent>
#include <QTimerEvent>
#include <QTimer>
#include <QEvent>

// QWidget 默认是不追踪鼠标事件的
MyLabel::MyLabel(QWidget *parent) : QLabel(parent)
{
    // 设置窗口追踪鼠标键
    this->setMouseTracking(true);

    // 启动定时器
    // 参数 1: 触发定时器的时间, 单位: ms
    // 参数2: 使用默认值
    // 返回值: 定时器ID
    id = startTimer(2000);
    id1 = startTimer(3000);

    // 第二种定时器用法
//    QTimer * timer = new QTimer(this);
//    timer->start(100);
//    connect(timer, &QTimer::timeout, this, [=]()
//    {
//        static int number = 0;
//        this->setText(QString::number(number++));
//    });

}

// 进入还是离开边界的一瞬间来完成的
// 鼠标进入
void MyLabel::enterEvent(QEvent *)
{
    setText("你不要在我身上乱摸!!!!");
}

// 鼠标离开
void MyLabel::leaveEvent(QEvent *)
{
    setText("终于离开了...");
}

void MyLabel::mousePressEvent(QMouseEvent *ev)
{
    // 字符串拼接 QString().arg()
    // %1, %2, %3 -- 占位符
    QString btn;
    if(ev->button() == Qt::LeftButton)
    {
        btn = "LeftButton";
    }
    else if(ev->button() == Qt::RightButton)
    {
        btn = "RightButton";
    }
    else if(ev->button() == Qt::MidButton)
    {
        btn = "MidButton";
    }
    QString str = QString("MousePree[%3]:(%1, %2)").arg(ev->x()).arg(ev->y()).arg(btn);

    setText(str);
}

void MyLabel::mouseReleaseEvent(QMouseEvent *ev)
{
    QString btn;
    if(ev->button() == Qt::LeftButton)
    {
        btn = "LeftButton";
    }
    else if(ev->button() == Qt::RightButton)
    {
        btn = "RightButton";
    }
    else if(ev->button() == Qt::MidButton)
    {
        btn = "MidButton";
    }
    QString str = QString("MouseRelease[%3]:(%1, %2)").arg(ev->x()).arg(ev->y()).arg(btn);

    setText(str);
}

void MyLabel::mouseMoveEvent(QMouseEvent *ev)
{
    QString btn;
    if(ev->buttons() & (Qt::LeftButton | Qt::RightButton))
    {
        btn = "LeftButton";
    }
    else if(ev->buttons() & Qt::RightButton)
    {
        btn = "RightButton";
    }
    else if(ev->buttons() & Qt::MidButton)
    {
        btn = "MidButton";
    }
    QString str = QString("MouseMove[%3]:(%1, %2)").arg(ev->x()).arg(ev->y()).arg(btn);

    setText(str);
}

// 每触发一次定时器, 进入该函数中
void MyLabel::timerEvent(QTimerEvent *e)
{
    QString str;
    if(e->timerId() == id)
    {
        static int num = -100;
        str = QString("%1: %2").arg("Time out: ").arg(num++);
        if(num >= 100)
        {
            // 关闭定时器
            killTimer(id);
        }

    }
    else if(e->timerId() == id1)
    {
        static int num1 = 10000;
        str = QString("%1: %2").arg("Time out: ").arg(num1++);
        if(num1 >= 10000+1000)
        {
            // 关闭定时器
            killTimer(id1);
        }
    }

    setText(str);
}

bool MyLabel::event(QEvent *e)
{
    // 返回值
    // true -- 代表事件被处理了,不再继续下发,停止了
    // false -- 事件没有被处理,会继续向下分发
    // 大概的处理步骤
//    switch(e->type()){
//        case QEvent::MouseMove:
//            mouseMoveEvent(e);
//            break;
//        case QEvent::Timer:
//            timerEvent(e);
//            break;
//    }

    // 过滤定时器事件
    if (e->type() == QEvent::Timer) {
        return true;// return false,将事件抛给父类
    }
//    else if (e->type() == QEvent::MouseMove) {
//        return true;
//    }
    else if (e->type() == QEvent::MouseButtonPress) {
        return false;
    }
    // 让父类执行默认的处理
    return QLabel::event(e);
}

mylabel.cpp

#ifndef MYWIDGET_H
#define MYWIDGET_H

#include <QWidget>

namespace Ui {
class MyWidget;
}

class MyWidget : public QWidget
{
    Q_OBJECT

public:
    explicit MyWidget(QWidget *parent = nullptr);
    ~MyWidget();
    void mousePressEvent(QMouseEvent *);
    bool eventFilter(QObject *obj, QEvent *e);
private:
    Ui::MyWidget *ui;
};

#endif // MYWIDGET_H

mywidget.h

#ifndef MYLABEL_H
#define MYLABEL_H

#include <QWidget>
#include <QLabel>

class MyLabel : public QLabel
{
    Q_OBJECT
public:
    explicit MyLabel(QWidget *parent = nullptr);
    void enterEvent(QEvent *);
    void leaveEvent(QEvent *);
    void mousePressEvent(QMouseEvent *ev);
    void mouseReleaseEvent(QMouseEvent *ev);
    void mouseMoveEvent(QMouseEvent *ev);
    void timerEvent(QTimerEvent *e);
    bool event(QEvent *e);
private:
    int id;
    int id1;
signals:

public slots:
};

#endif // MYLABEL_H

mylabel.h

原文地址:https://www.cnblogs.com/xiangtingshen/p/10765753.html

时间: 2024-08-04 23:08:03

(十三)事件分发器——event()函数,事件过滤的相关文章

MySQL事件调度器Event Scheduler

我们都知道windows的计划任务和linux的crontab都是用来实现一些周期性的任务和固定时间须要运行的任务. 在mysql5.1之前我们完毕数据库的周期性操作都必须借助这些操作系统实现. 在mysql5.1及其之后的版本号添加了计划任务的功能(mysql事件调度器Event Scheduler). 事件调度器是定时触发运行的.在这个角度上也能够称作是"暂时的触发器". 触发器仅仅是针对某个表产生的事件运行一些语句.而事件调度器则是在某一个(间 隔)时间运行一些语句.事件是由一个

MySQL计划任务(事件调度器)(Event Scheduler)[转]

原文链接: http://www.cnblogs.com/c840136/articles/2388512.html MySQL5.1.x版本中引入了一项新特性EVENT,顾名思义就是事件.定时任务机制,在指定的时间单元内执行特定的任务,因此今后一些对数据定时性操作不再依赖外部程序,而直接使用数据库本身提供的功能. 要查看当前是否已开启事件调度器,可执行如下SQL: SHOW VARIABLES LIKE 'event_scheduler'; 或 SELECT @@event_scheduler

MySQL事件调度器event的使用

Q:假设,有一个需求,希望在某一个时刻系统调用一个begin end执行一下:十分钟以后执行一下begin end.亦或有一个需求,每个多长时间周期性执行begin end.那么这个时候该怎么办呢? A: 在Linux里面可以使用at.crontab来实现上面的需求:MySQL里面也有这样的方法,就是event对象. 也被称为MySQL事件调度器(Event Scheduler),可以在某一个时间点执行一个SQL语句或一个语句块(BEGIN ... END):或者每隔固定间隔重复执行.类似于Li

Android事件分发详解(四)——事件传递基础示例

MainActivity如下: package com.cn; import android.app.Activity; import android.os.Bundle; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnTouchListener; /** * Demo描述: * Andr

Android中的事件分发机制——ViewGroup的事件分发

综述 Android中的事件分发机制也就是View与ViewGroup的对事件的分发与处理.在ViewGroup的内部包含了许多View,而ViewGroup继承自View,所以ViewGroup本身也是一个View.对于事件可以通过ViewGroup下发到它的子View并交由子View进行处理,而ViewGroup本身也能够对事件做出处理.下面就来详细分析一下ViewGroup对时间的分发处理. MotionEvent 当手指接触到屏幕以后,所产生的一系列的事件中,都是由以下三种事件类型组成.

Android事件分发完全解析之事件从何而来

尊重原创转载请注明:From AigeStudio(http://blog.csdn.net/aigestudio)Power by Aige 侵权必究! 炮兵镇楼 上一节Android事件分发完全解析之为什么是她中我们简略地分析了事件分发机制的由来,这里要说明一点,Android(或者说任何的驱动系统)都包含大量不同类型的事件,比如按键啦.轨迹球啦.鼠标啦.触摸啦.红外线啦等等等,这里为了简化问题也为了切合实际,我们只针对触摸事件进行分析,至于其他的一些杂七杂八的事件其实都很好理解就不多说了.

Qt中事件处理的方法(三种处理方法,四种覆盖event函数,notify函数,event过滤,事件处理器。然后继续传递给父窗口。可观察QWidget::event的源码,它是虚拟保护函数,可改写)

一.Qt中事件处理的方式 1.事件处理模式一 首先是事件源产生事件,最后是事件处理器对这些事件进行处理.然而也许大家会问, Qt中有这么多类的事件,我们怎么样比较简便的处理每个事件呢?设想,如果是每个事件都对应同一个事件处理器,在该事件处理器中对不同的事件进行分类处理,这样的弊端有两点:第一,导致该事件处理器过于臃肿复杂:第二,这样不便于扩展,当系统新增加事件类型或者是我们需要使用到自定义事件时,就不得不修改Qt的源码来达到目的.所以Qt设计者的做法是针对不同类型的事件提供不同的事件处理器与之对

[DOM Event Learning] Section 4 事件分发和DOM事件流

[DOM Event Learning] Section 4 事件分发和DOM事件流 事件分发机制: event dispatch mechanism. 事件流(event flow)描述了事件对象在数据结构中是如何传播的. 传播路径 事件对象(event objects)被分发给事件目标(event target),在分发开始的时候,在实现中必须先确定事件对象的传播路径. 这个传播路径必须是一个有序的list,其中包含了事件对象必须通过的事件目标. 对于DOM的实现来说,这个传播路径必须反映这

Android事件分发机制详解:史上最全面、最易懂

前言 Android事件分发机制是每个Android开发者必须了解的基础知识 网上有大量关于Android事件分发机制的文章,但存在一些问题:内容不全.思路不清晰.无源码分析.简单问题复杂化等等 今天,我将全面总结Android的事件分发机制,我能保证这是市面上的最全面.最清晰.最易懂的 本文秉着"结论先行.详细分析在后"的原则,即先让大家感性认识,再通过理性分析从而理解问题: 所以,请各位读者先记住结论,再往下继续看分析: 文章较长,阅读需要较长时间,建议收藏等充足时间再进行阅读 目