QT的事件机制

这篇具有很好参考价值的文章主要介绍了QT的事件机制。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

QT的事件机制


1、QT的事件机制。

事件(event)是由系统或者 Qt 本身在不同的时刻发出的。当用户按下鼠标、敲下键盘,或者是窗口需要重新绘制的时候,都会发出一个相应的事件。一些事件是****用户操作做出响应时发出,如键盘事件等;另一些事件则是由系统自动发出,如计时器事件。

在前面我们也曾经简单提到,Qt 程序需要在main()函数创建一个QApplication对象,然后调用它的exec()函数。这个函数就是开始 Qt 的事件循环。在执行exec()函数之后,程序将进入事件循环来监听应用程序的事件。当事件发生时,Qt 将创建一个事件对象。Qt 中所有事件类都继承于QEvent。在事件对象创建完毕后,Qt 将这个事件对象传递给QObject的event()函数。event()函数并不直接处理事件,而是按照事件对象的类型分派给特定的事件处理函数(event handler)。

2、QT事件的整体流程。

如图所示:
QT的事件机制,QT,qt,C++
app.exe()--------->事件过滤器----->事件分发器-----------------》事件处理函数

下面依次从下往上介绍。

1、事件处理函数。

1、鼠标按下与鼠标释放事件。

提升一个按钮。重写鼠标按下与鼠标释放事件。
mybutton.h

#include <QWidget>
#include <QPushButton>
#include <QMouseEvent>
#include <QEvent>
class MyButton : public QPushButton
{
    Q_OBJECT
public:
    explicit MyButton(QWidget *parent = nullptr);
    //鼠标点击事件
    void mousePressEvent(QMouseEvent *ev);
    //鼠标释放事件
    void mouseReleaseEvent(QMouseEvent *ev);
signals:
};

mybutton.cpp

#include "mybutton.h"
#include <QDebug>

MyButton::MyButton(QWidget *parent)
    : QPushButton{parent}
{

}

void MyButton::mousePressEvent(QMouseEvent *ev)
{
    qDebug() << "鼠标按下" ;
}
void MyButton::mouseReleaseEvent(QMouseEvent *ev)
{
    qDebug() << "鼠标抬起" ;
}

结果如下:
QT的事件机制,QT,qt,C++
注意:按钮是提升自定义mybutton类。而mybutton又是继承于QPushButton

2、事件的接收与忽略(accept()和ignore()函数)。

mybutton.h

#include <QWidget>
#include <QPushButton>
#include <QMouseEvent>
#include <QEvent>

class MyButton : public QPushButton
{
    Q_OBJECT
public:
    explicit MyButton(QWidget *parent = nullptr);
    //鼠标点击事件
    void mousePressEvent(QMouseEvent *ev);

signals:

};

mybutton.cpp

#include "mybutton.h"
#include <QDebug>

MyButton::MyButton(QWidget *parent)
    : QPushButton{parent}
{

}

void MyButton::mousePressEvent(QMouseEvent *ev)
{
    if(ev->button() == Qt::LeftButton)
    {
        qDebug() << "MyButton鼠标按下的是左键";
        ev->accept(); // accept 事件不会再往下传递
    }
    else // 鼠标的右键按下与鼠标的中间按键往下传递
    {
        qDebug() << "MyButton鼠标其他键按下";
        QPushButton::mousePressEvent(ev);
    }
}

myWidget.h

#include <QWidget>\
class MyWidget : public QWidget
{
    Q_OBJECT

public:
    MyWidget(QWidget *parent = nullptr);
    ~MyWidget();
    //鼠标点击事件
    void mousePressEvent(QMouseEvent *ev);
private:
    Ui::MyWidget *ui;
};

myWidget.cpp

#include "mywidget.h"
#include "ui_mywidget.h"

MyWidget::MyWidget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::MyWidget)
{
    ui->setupUi(this);
}

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

void MyWidget::mousePressEvent(QMouseEvent *ev)
{
    if(ev->button() == Qt::LeftButton)
    {
        qDebug() << "MyWidget鼠标左键按下";
    }else {
        qDebug() << "MyWidget鼠标其他键按下";
    }
}

在myWidget类与mybutton类都有重写鼠标事件。
现在accept()函数
当鼠标的左键按下时的打印:
QT的事件机制,QT,qt,C++
对鼠标的左键按下不在往下发所以myWidget收不到
当鼠标的右键按下时的打印:
QT的事件机制,QT,qt,C++
对鼠标的右键按下往下发所以myWidget能收到

当代码把accept()函数改成ignore()函数。鼠标左键按下事件继续往下传递。传递给了父组件mywidget

void MyButton::mousePressEvent(QMouseEvent *ev)
{
    if(ev->button() == Qt::LeftButton)
    {
        qDebug() << "MyWidget鼠标左键按下";

        ev->ignore(); //忽略,事件继续往下传递,给谁传递?
        //事件传递给了父组件,不是给父类(基类)
    }
    else // 鼠标的右键按下与鼠标的中间按键往下传递
    {
        qDebug() << "MyButton鼠标其他键按下";
        QPushButton::mousePressEvent(ev);
    }
}

以上就是事件的接收与忽略。就是accept()函数与ignore()函数。

2.事件的分发enevt()

1、事件分发的dome。

函数原型: bool event(QEvent *ev)
event()函数主要用于事件的分发。所以,如果你希望在事件分发之前做一些操作,就可以重写这个event()函数了。
myWidget.h

#include <QWidget>
class MyWidget : public QWidget
{
    Q_OBJECT

public:
    MyWidget(QWidget *parent = nullptr);
    ~MyWidget();
    bool event(QEvent *ev);     // 重写event事件
    void keyPressEvent(QKeyEvent *event); //键盘按下事件
    void keyReleaseEvent(QKeyEvent *event);
private:
    Ui::MyWidget *ui;
};

myWidget.cpp

#include "mywidget.h"
#include "ui_mywidget.h"

MyWidget::MyWidget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::MyWidget)
{
    ui->setupUi(this);
}

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

bool MyWidget::event(QEvent *e)
{
    if(e->type() == QEvent::KeyPress) /* 按键按下的分发 */
    {
        /* 类型转换 */
        QKeyEvent *env = static_cast<QKeyEvent *>(e);
        if(env->key() == Qt::Key_0)
        {
            qDebug() << "event Qt::Key_0";
            return QWidget::event(e); /* 只处理按键0 */
        }
        return true; /* 其他按键不分发下去 */
    } else {
        return QWidget::event(e); /* 其他的事件都分发下去 */
    }
}

void MyWidget::keyPressEvent(QKeyEvent *event) //键盘按下事件
{
    switch(event->key()) {
    case Qt::Key_0:
        qDebug() <<"Qt::Key_0";
        break;
    case Qt::Key_1:
        qDebug() <<"Qt::Key_1";
        break;
    }
}

void MyWidget::keyReleaseEvent(QKeyEvent *event)
{
    qDebug() <<"MyWidget::keyReleaseEvent";
}

总结:当按下按键0按下才处理。其他按键不起作用。
按键0按下的结果:
QT的事件机制,QT,qt,C++
其他按键按下不起作用。只打印按键释放。因为如上return QWidget::event(e); /* 其他的事件都分发下去 */
按键是否是可以打印的。如果改成return true; 就不会打印按键释放。

2、enevt事件的缺点。

QT的事件机制,QT,qt,C++
从而引出事件过滤器。
QT的事件机制,QT,qt,C++
QT的事件机制,QT,qt,C++

3、事件的过滤器。

函数原型如下:virtual bool QObject::eventFilter ( QObject * watched, QEvent * event )
watched:过滤哪个控件 event:过滤哪个事件。

这个函数正如其名字显示的那样,是一个“事件过滤器”。所谓事件过滤器,可以理解成一种过滤代码。事件过滤器会检查接收到的事件。如果这个事件是我们感兴趣的类型,就进行我们自己的处理;如果不是,就继续转发。这个函数返回一个 bool 类型,如果你想将参数 event 过滤出来,比如,**不想让它继续转发,就返回 true,否则返回 false。**事件过滤器的调用时间是目标对象(也就是参数里面的watched对象)接收到事件对象之前。也就是说,如果你在事件过滤器中停止了某个事件,那么,watched对象以及以后所有的事件过滤器根本不会知道这么一个事件。
mybutton.h

#include <QPushButton>
class MyButton : public QPushButton
{
    Q_OBJECT
public:
    explicit MyButton(QWidget *parent = nullptr);
    void mouseMoveEvent(QMouseEvent *ev);
signals:

};

mybutton.cpp

#include "mybutton.h"
#include <QDebug>

MyButton::MyButton(QWidget *parent)
    : QPushButton{parent}
{

}
void MyButton::mouseMoveEvent(QMouseEvent *ev)
{
    qDebug() << "mouseMoveEvent";
    QPushButton::mousePressEvent(ev);
}

mywidget.h

#include <QWidget>
class MyWidget : public QWidget
{
    Q_OBJECT
public:
    MyWidget(QWidget *parent = nullptr);
    ~MyWidget();
    //事件过滤器
    bool eventFilter(QObject *obj, QEvent *e);
private:
    Ui::MyWidget *ui;
};

mywidget.cpp

#include "mywidget.h"
#include "ui_mywidget.h"

MyWidget::MyWidget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::MyWidget)
{
    ui->setupUi(this);
    //安装过滤器
    ui->pushButton->installEventFilter(this);
    ui->pushButton->setMouseTracking(true);/* 按钮追踪 */
}

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

bool MyWidget::eventFilter(QObject *obj, QEvent *e)
{
    if(obj == ui->pushButton)
    {
        QMouseEvent *env = static_cast<QMouseEvent *>(e);
        //判断事件

        if(e->type() == QEvent::MouseMove)
        {
            ui->pushButton->setText(QString("eventFilter:(%1, %2)").arg(env->x()).arg(env->y()));
            return true; /* 不分发 */
        }
        else
        {
            return QWidget::eventFilter(obj, e);
        }
        return true;
    }
    else
    {
        return QWidget::eventFilter(obj, e);
    }
}

如上 return true; /* 不分发 */ 所以 qDebug() << “mouseMoveEvent”;没有打印
如果设置return false; 事件不会过滤。就会打印mouseMoveEvent
总结:
QT的事件机制,QT,qt,C++

3、总结

现在我们可以总结一下 Qt 的事件处理,实际上是有五个层次:
QT的事件机制,QT,qt,C++
上面1, 2,3,点用的多。4, 5不怎么用。
事件过滤器与enevt事件,以及事件的处理函数都是虚函数继承与上层父类。我们在重写时虚函数必须继承上层父类一致。否则就不叫重写。

以上就是今天要讲的内容,QT的事件。主要理解QT从上到下的流程。文章来源地址https://www.toymoban.com/news/detail-806751.html

到了这里,关于QT的事件机制的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Qt 底层之事件驱动系统】深入理解 Qt 事件机制:主事件循环与工作线程的交互探究,包括 QML 的视角

    在探讨 Qt 的世界时,我们不仅是在讨论一种编程框架,更是在探索一种将复杂技术细节隐藏于幕后、让开发者专注于创造性工作的艺术形式。正如著名的计算机科学家 Edsger Dijkstra 所言:“简洁是复杂性的先决条件。” 在这一章节中,我们将探讨 Qt 事件机制的基础概念,这

    2024年02月22日
    浏览(52)
  • DAY4,Qt(事件处理机制的使用,Qt中实现服务器的原理)

    ---chatser.h---头文件 ---chatser.cpp---函数实现文件 ---main.cpp---测试文件 结果展示---     

    2024年02月15日
    浏览(55)
  • Qt - Qt5事件处理(鼠标事件)

    鼠标事件 ​ 鼠标事件包括鼠标的移动,鼠标键按下,松开,单击,双击等 使用鼠标事件时,加入对应头文件 常见的鼠标事件如下: QMouseEvent类包含了用于描述鼠标事件的参数。 当在一个窗口里按住鼠标按键、或移动、或释放就会产生鼠标事件QMouseEvent。 鼠标移动事件只会

    2023年04月09日
    浏览(39)
  • Qt扫盲-Qt事件系统概述

    在Qt中,事件是由抽象的QEvent类派生而来的对象,表示发生在 应用程序内部 或应用程序需要知道的 外部 活动的结果。 事件可以由QObject子类的任何实例接收和处理,一般这个事件在窗口程序里面使用非常频繁。 那事件是如何传递并处理的呢? 当事件发生时,Qt会通过构造适

    2024年02月08日
    浏览(35)
  • QT--day4(定时器事件、鼠标事件、键盘事件、绘制事件、实现画板、QT实现TCP服务器)

     QT实现tcpf服务器代码:(源文件) 头文件:

    2024年02月15日
    浏览(50)
  • Qt 事件 < 二 >鼠标键盘事件

    Qt 是一个流行的 C++ 框架,用于构建跨平台的图形用户界面应用程序。在 Qt 中,处理键盘事件和鼠标事件是常见的任务,因为用户输入在交互式应用程序中至关重要。下面是关于 Qt 键盘事件和鼠标事件的学习总结: 键盘事件 (QKeyEvent)使用入门: 事件处理函数: 键盘事件通过

    2024年01月18日
    浏览(41)
  • QT学习日记12——Qt中的鼠标事件

    学习视频链接 最新QT从入门到实战完整版|传智教育_哔哩哔哩_bilibili https://www.bilibili.com/video/BV1g4411H78N?p=31vd_source=0471cde1c644648fafd07b54e303c905 目录 一、鼠标进入和出去事件 1.1 新建 C++ 文件 1.2 编写代码 1.3 操作 1.4 运行结果 二、鼠标点击、释放和移动事件 2.1 修改代码 2.2 运行结

    2024年02月11日
    浏览(53)
  • QT笔记——QT类反射机制简单学习

    学习 QT的 类反射机制 使用Qt 反射机制的条件 1.需要继承自QObject 类 或者 它的 派生类 ,并需要在类中加入Q_OBJECT 宏 2.注册成员函数:若希望普通成员函数能够被反射,需要在函数声明之前加入Q_INVOKABLE 宏。 3.注册成员变量:若希望成员变量能被反射,需要使用Q_PROPERTY 宏。

    2024年02月09日
    浏览(120)
  • QT基础篇(11)QT5事件处理及实例

    1.鼠标事件及实例 QT5中有多种鼠标事件可以使用,常用的鼠标事件有: mousePressEvent :当鼠标按下时触发的事件。 mouseReleaseEvent :当鼠标释放时触发的事件。 mouseDoubleClickEvent :当鼠标双击时触发的事件。 mouseMoveEvent :当鼠标移动时触发的事件。 wheelEvent :当鼠标滚轮滚动时

    2024年01月19日
    浏览(42)
  • Qt键盘事件处理——如何在Qt中监听按键操作

    Qt键盘事件处理——如何在Qt中监听按键操作 在Qt中,使用键盘是很常见的操作。如何通过代码来实现键盘事件的监听和响应呢?本文将详细介绍在Qt中如何监听键盘事件,并实现一些基本的按键操作。 在Qt中,所有的键盘事件都被封装成了一个QKeyEvent对象,我们只需要在需要

    2024年02月11日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包