Qt事件处理(五)

  Qt处理事件的第五种方式:"继承QApplication并重新实现notify()函数"。Qt调用QApplication来发送一个事件,重新实现notify()函数是在事件过滤器得到所有事件之前获得它们的唯一方法。事件过滤器使用更为便利。因为可以同时有多个事件过滤器。而notify()函数只有一个。

  重新实现的QApplication类MyApplication的头文件myapplication.h如下:

#ifndef MYAPPLICATION_H
#define MYAPPLICATION_H

#include <QApplication>
#include <QEvent>

class MyApplication : public QApplication
{
public:
    MyApplication(int & argc, char ** argv);

public:
    bool notify(QObject *receiver, QEvent *e);
};

#endif

  myapplication.cpp文件如下:

#include "myapplication.h"
#include <QMouseEvent>

MyApplication::MyApplication(int & argc, char ** argv) : QApplication(argc, argv)
{
}

 bool MyApplication::notify(QObject *receiver, QEvent *e)
 {
     //屏蔽MouseButtonPress、MouseButtonRelease和MouseMove事件
     if (e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseButtonRelease || e->type() == QEvent::MouseMove)
     {
        return true;
     }
     return QApplication::notify(receiver, e);
 }

  mainwindow.h文件如下:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QtGui/QMainWindow>
#include <QPushButton>
#include <QMouseEvent>

class MainWindow : public QMainWindow
{
    Q_OBJECT
    
public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
protected:
    bool eventFilter(QObject *obj, QEvent *e);
private:
    QPushButton *button;
};

#endif

  mainwindow.cpp文件如下:

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    button = new QPushButton;
    this->setCentralWidget(button);
}

MainWindow::~MainWindow()
{

}

bool MainWindow::eventFilter(QObject *obj, QEvent *e)
{
    if (obj == button)         //响应button的MouseButtonPress和MouseButtonRelease事件
    {
        if (e->type() == QEvent::MouseButtonPress)
        {
            QMouseEvent *event = static_cast<QMouseEvent*> (e);
            button->setText(QString("Press: %1, %2").arg(QString::number(event->x()), QString::number(event->y())));
            return true;
        }
        else if (e->type() == QEvent::MouseButtonRelease)
        {
            QMouseEvent *event = static_cast<QMouseEvent*> (e);
            button->setText(QString("Release: %1, %2").arg(QString::number(event->x()), QString::number(event->y())));
            return true;
        }
        else
        {
            return false;
        }
    }

    return QMainWindow::eventFilter(obj, e);
}

  main.cpp文件如下:

#include <QtGui/QApplication>
#include <QtCore/QTextCodec>
#include "mainwindow.h"
#include "myapplication.h"

int main(int argc, char *argv[])
{
    MyApplication a(argc, argv);
    QTextCodec::setCodecForTr(QTextCodec::codecForName("gb18030"));
    MainWindow mainwindow;
    a.installEventFilter(&mainwindow);  //为QApplication注册过滤器
    mainwindow.setWindowTitle(QObject::tr("继承QApplication并重新实现notify()函数"));
    mainwindow.resize(400, 200);
    mainwindow.show();

    return a.exec();
}

  运行程序,可以发现button不管是点击、释放还是拖动鼠标,都不会显示任何文本。因为我们已经子类化QApplication,事件在到达QApplication的事件过滤器之前,会先到达QApplication的notify()函数,我们已经在子类化的MyApplication中屏蔽了MouseButtonPress、MouseButtonRelease事件。所以为MyApplication对象注册的事件过滤器不起作用。程序运行界面为:

             

  Qt事件系列(完)! 

QT事件处理可以分为个主要层次: 1. **用户层(User Input)**: 这是最顶层的概念,也是我们作为开发者能够直接感知的部分。包括鼠标点击、键盘输入、触摸屏手势等。用户通过各种输入设备(如鼠标、键盘、触摸屏)进行操作。 2. **事件系统(Event System)**: QT内置了一套强大的事件处理机制,用于捕获和分发从用户层传来的事件。事件系统负责将低级别的输入事件转换成QT可以直接识别和处理的形式。例如,鼠标点击会被转换成`QMouseEvent`,按键会被转换成`QKeyEvent`。 3. **事件处理器(Event Handler)**: 在这个层次,QT提供了信号和槽(Signals and Slots)机制来允许对象之间建立联系并处理事件。当事件发生时,相应的信号会被发射,接着连接到此信号的对象(槽)就会被自动调用。这是事件驱动编程的核心部分,用于实际的业务逻辑处理。 4. **GUI层(GUI Layer)**: 此层次涉及到GUI组件的创建和管理,比如窗口、按钮、标签等。这些组件通常是基于模型-视图-控制器(MVC)架构设计的,其中模型代表数据,视图则对应GUI层,而控制器则是事件处理器的一部分,它决定了如何响应用户的输入以及如何更新视图以反映最新的数据状态。 5. **底层框架层(Framework Layer)**: 这是QT内部结构的一部分,处理与底层硬件和操作系统交互的任务。在这个层次,QT负责处理渲染、输入映射和其他与底层平台相关的细节,确保用户层的输入能够在所有支持的平台上得到一致的处理。 每一层都有其独特的作用和职责,它们协同工作,共同构建出一个高效、稳定且跨平台的用户界面。理解这层之间的相互作用对于深入掌握QT事件处理机制至关重要。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值