Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >17.QT-事件处理分析、事件过滤器、拖放事件

17.QT-事件处理分析、事件过滤器、拖放事件

作者头像
诺谦
发布于 2018-05-28 07:47:22
发布于 2018-05-28 07:47:22
1.6K00
代码可运行
举报
文章被收录于专栏:Linux驱动Linux驱动
运行总次数:0
代码可运行

Qt事件处理介绍

  • Qt平台会将系统产生的消息转换为Qt事件
  • Qt事件是一个QEvent的对象
  • Qt事件用来描述程序内部或外部发生的动作
  • 任意的QObject对象都具备事件处理的能力

Qt常见的事件继承图如下:

  • QInputEvent:用户输入事件
  • QDropEvent:用户拖放事件
  • QPaintEvent:描述操作系统绘制GUI动作的事件
  • QCloseEvent:用户关闭窗口事件
  • QTimerEvent:计时器事件

事件处理方式顺序

1.Qt事件产生后立即被分发到QWidget对象

2.QWidget中的event(QEvent*)进行事件处理

3.event()根据事件类型调用不同的事件处理函数

4.在事件处理函数中发送Qt中预定义的信号

5.调用信号关联的槽函数

以按钮点击为例,如下图所示:

QPushButton事件处理总结

1.当点击按钮后,将会触发鼠标事件

2.调用event(QEvent*)成员函数

3.调用mouseReleaseEvent(QMouseEvent*)成员函数

4.调用click()成员函数

5.触发信号SIGNAL(clicked());

同样,当用户点击窗口的关闭按钮时,也会触发closeEvent()事件函数,该函数需要重写,才能实现

参考示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 void MainWindow::closeEvent(QCloseEvent *event)
{
     if (maybeSave())                        //如果还有需要保存的数据
    {
         writeSettings();
         event->accept();
    } 
     else                                    //取消关闭窗口
    {
         event->ignore();
    }
 }

类似的还有keyEvent()获取键盘事件函数, keyReleaseEvent()键盘按下事件函数,enterEvent光标进入组件事件函数, leaveEvent光标离开组件事件函数等等。

其中QCloseEvent继承与QEvent,在QEvent中常用成员函数有

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void  accept ();    //接收者处理当前事件

void  ignore ();    //接收者忽略当前事件,忽略后,事件可能传递给父组件

bool isAccepted();  //判断当前事件是否被处理过 

当使用ignore()处理事件时,该事件可能会传递给其父组件对象继续处理

步骤如下:

  • 写两个类: QMyWidget、QMyLineEdit(QMyLineEdit是QMyWidget的类成员)
  • 通过QMyLineEdit来重写LineEdit的keyReleaseEvent()键盘按下事件函数
  • 通过QMyWidget来重写QWidget的keyReleaseEvent()键盘按下事件函数
  • 然后通过ignore()处理QMyLineEdit的keyReleaseEvent()事件函数
  • 判断是否会继续执行QMyWidget父组件的keyReleaseEvent()事件函数

QLineEdit.h如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#ifndef QMYLINEEDIT_H
#define QMYLINEEDIT_H

#include <QLineEdit>
#include <QtGui>

class QMyLineEdit : public QLineEdit
{
    Q_OBJECT

public:
    explicit QMyLineEdit(QWidget *parent = 0);

    void  keyReleaseEvent( QKeyEvent * event );
};

#endif // QMYLINEEDIT_H

QLineEdit.cpp如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include "QMyLineEdit.h"

QMyLineEdit::QMyLineEdit(QWidget *parent) :
    QLineEdit(parent)
{

}

void  QMyLineEdit::keyReleaseEvent( QKeyEvent * event )
{
    qDebug()<<"QMyLineEdit::keyReleaseEvent";
    qDebug()<<"key value:"<< event->key();      
    event->ignore();                           //忽略当前事件
}

QMyWidget.h如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#ifndef QMYWIDGET_H
#define QMYWIDGET_H

#include "QMyLineEdit.h"
#include <QWidget>

class QMyWidget : public QWidget
{
    Q_OBJECT
    QMyLineEdit line;

public:
    explicit QMyWidget(QWidget *parent = 0);
    void   keyReleaseEvent( QKeyEvent * event );

};

#endif // QMYWIDGET_H

QMyWidget.cpp如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include "QMyWidget.h"

QMyWidget::QMyWidget(QWidget *parent) :
    QWidget(parent),
    line(this)
{
}

void  QMyWidget::keyReleaseEvent( QKeyEvent * event )
{
    qDebug()<<"QMyWidget::keyReleaseEvent";
    qDebug()<<"key value:"<< event->key();

    QWidget::keyPressEvent(event);
}

main()函数如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int main(int argc, char *argv[])
{
        QApplication a(argc, argv);

        QMyWidget w;

        w.show();

        return a.exec();
}

效果如下:

可以看到成员调用了event->ignore()函数忽略事件后,同样也会继续进入QMyWidget类处理事件 

Qt中的事件过滤器

  • 事件过滤器可以对需要的组件接收到的事件进行过滤,以及监控
  • 任意的QObject对象都可以作为事件过滤器使用
  • 事件过滤器的实现,需要重写eventFilter()函数
  • 组件要想被监控,则需要通过installEventFilter()安装事件过滤器
  • 事件过滤器能够决定是否将事件转发给组件对象,如下图所示:

eventFilter函数体如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
bool QObject::eventFilter ( QObject * watched, QEvent * event );
       // watched:代表被监控的组件  event:代表要转发的事件
       //返回true,表示该事件也被过滤掉(处理),无需再转发了
       //返回false,则正常转发给watched

参考示例-实现文本框只允许输入数字:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class MainWindow : public QMainWindow
 {
 public:
     MainWindow();

 protected:
     bool eventFilter(QObject *obj, QEvent *ev);

 private:
     QTextEdit *textEdit;
 };


 MainWindow::MainWindow()
 {
     textEdit = new QTextEdit;
     setCentralWidget(textEdit);
     textEdit->setAttribute(Qt::WA_InputMethodEnabled, false);     //禁止中文输入法
     textEdit->installEventFilter(this);
 }

 bool MainWindow::eventFilter(QObject *obj, QEvent *event)
 {
      if (obj == textEdit)
     {
         if (event->type() == QEvent::KeyPress)
         {
             QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
             qDebug() << "Ate key press" << keyEvent->key();
             switch(keyEvent->key())         //只接受0~9数字
             {
                case Qt::Key_0:
                case Qt::Key_1:
                case Qt::Key_2:
                case Qt::Key_3:
                case Qt::Key_4:
                case Qt::Key_5:
                case Qt::Key_6:
                case Qt::Key_7:
                case Qt::Key_8:
                case Qt::Key_9:
                    return false;
                default:
                    return true;
            }
         }
         else
         {
             return false;
         }
     }
     else
     {
       return QMainWindow::eventFilter(obj, event);
     }
 }

用户拖放事件

每个QWidget对象都能处理拖放事件

常用的拖放事件相关函数有:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void  dragEnterEvent ( QDragEnterEvent * event );  //拖事件处理函数
void dropEvent ( QDropEvent * event ) ;           //放事件处理函数 

拖放事件所处理的数据是QMimeData类

MIME类型常用处理函数如下所示:

拖放事件的步骤如下:

1.在构造函数里通过setAcceptDrops(true)函数,让该组件能接受拖放事件

2.重写dragEnterEvent(QDragEnterEvent* event)函数并判断MIME类型

  如果是期待的类型,则调用event ->acceptProposedAction();

  否则调用 : event ->ignore();

3.重写dropEvent()函数并判断MIME类型

  如果是期待的类型,则获取MIME数据并处理.

  否则调用 : event ->ignore();

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 class MainWindow : public QMainWindow
 {
private:
    QTextEdit *textEdit;
    void dragEnterEvent(QDragEnterEvent *event);
    void dropEvent(QDropEvent *event);

public:
    MainWindow();
 };

 MainWindow::MainWindow()
 {
     textEdit = new QTextEdit;
     setCentralWidget(textEdit);
     textEdit->setAttribute(Qt::WA_InputMethodEnabled, false) ;
     textEdit->installEventFilter(this);
     this->setAcceptDrops(true);
 }

void MainWindow::dragEnterEvent(QDragEnterEvent *event)
{
      if(event->mimeData()->hasUrls())      //判断拖的类型
      {
            event->acceptProposedAction();
      }
      else
      {
            event->ignore();
      }
}

void MainWindow::dropEvent(QDropEvent *event)
{
    if(event->mimeData()->hasUrls())        //判断放的类型
    {
        textEdit->clear();
        QList<QUrl> List = event->mimeData()->urls();

        for(int i=0;i<List.length();i++)
        {
            textEdit->insertPlainText(List[i].toLocalFile()+"\n");
        }
    }
    else
    {
          event->ignore();
    }
}

效果:

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-05-05 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Qt开源作品6-通用视频控件
在之前做的视频监控系统中,根据不同的用户需要,做了好多种视频监控内核,有ffmpeg内核的,有vlc内核的,有mpv内核的,还有海康sdk内核的,为了做成通用的功能,不同内核很方便的切换,比如pro直接改一个DEFINE的变量名,所以需要将各种内核的使用方法做成一样的接口,这样看起来就很整齐,所以后面特意提炼了一个通用的视频控件,该控件没有具体的视频播放控制功能,需要根据不同的内核去调用具体的方法实现,后面还需要增加大华sdk或者其他第三方厂家的协议的时候,直接套用这个通用视频控件即可。
feiyangqingyun
2020/05/11
7610
Qt开源作品6-通用视频控件
一个简单的图片浏览器
❝实现拖拽图片到窗口显示,如果图片过大会出现滚动条,让看图片更方便。 ❞ 实现 使用QLabel显示图片。 使用QScrollArea实现图片过大时的滚动视图。 拖拽图片到窗口重写dragEnter
Qt君
2020/07/16
6060
Qt官方示例-拖动图标
  在使用拖放的许多情况下,用户开始从特定的窗口小部件拖放,并将有效负载拖放到另一个窗口小部件上。在此示例中,我们将QLabel子类化以创建用作拖动源的标签,并将其放置在同时充当容器和放置站点的QWidget中。
Qt君
2023/03/17
1.7K0
Qt官方示例-拖动图标
【QT】事件分发器 & 事件过滤器
在 Qt 中,事件分发器(Event Dispatcher) 是一个核心概念,用于处理 GUI 应用程序中的事件。事件分发器负责将事件从⼀个对象传递到另⼀个对象,直到事件被处理或被取消。每个继承自 QObject 类或 QObject 类本身都可以在本类中重写 bool event(QEvent *e) 函数,来实现相关事件的捕获和拦截。
YoungMLet
2024/07/27
5090
【QT】事件分发器 & 事件过滤器
19.QT-事件发送函数sendEvent()、postEvent()
Qt发送事件分为两种 -阻塞型事件发送 需要重写接收对象的event()事件处理函数 当事件发送后,将会立即进入event()事件处理函数进行事件处理 通过sendEvent()静态函数实现阻塞发送: bool QApplication::sendEvent ( QObject * receiver, QEvent * event ) ; // receiver:接收对象, event :要发送的event类型(比如:鼠标双击) //当有事件发送,将会
诺谦
2018/05/28
3.3K0
Qt5实战第十篇:Qt5事件处理详解
Qt5事件处理机制是Qt框架的核心之一,它允许应用程序响应用户的交互动作,如鼠标点击、键盘输入等。事件处理在Qt中是通过事件对象、事件源、事件目标以及事件处理函数来实现的。了解并掌握Qt5的事件处理机制,对于开发高效、响应迅速的GUI应用程序至关重要。
china马斯克
2025/01/03
2500
Qt项目之虚拟键盘V1.1
不知道上次有没有小伙伴用我的思路自己去实现一遍虚拟键盘,上次的版本存在一些的缺陷,我并不是在点击输入文本框时显示键盘的,而是通过鼠标的点击事件显示键盘的。因为当时那版的功能我没有在网上查到怎么去实现,但这次则实现了点击文本框显示键盘的功能,还添加了切换字母大小写功能、可通过鼠标移动虚拟键盘的功能。这些都是在网上找的,然后我拼起来的。来个图片预览。
用户5908113
2019/09/30
2K0
Qt项目之虚拟键盘V1.1
Qt键盘事件(一)——检测按键输入
本节Jungle实现一个简单的功能:键盘按下某个键,Qt界面上显示出Jungle按下的是哪个键。
用户6557940
2022/07/24
3.2K0
Qt键盘事件(一)——检测按键输入
【QT】Qt事件
事件是应用程序内外部产生的事情以及动作的统称,常见的所有事件例如鼠标事件QMouseEvent,键盘事件QKeyEvent等等都是继承自QEvent
s-little-monster
2024/11/06
2130
【QT】Qt事件
Qt学习之路_6(Qt局域网聊天软件)
http://www.cnblogs.com/tornadomeet/archive/2012/07/04/2576355.html
bear_fish
2018/09/20
3.4K0
Qt学习之路_6(Qt局域网聊天软件)
[QT]屏蔽Tab键切换控件焦点
原文链接:https://blog.csdn.net/humanking7/article/details/80654775
祥知道
2020/03/10
1.9K0
QT应用编程:基于QMediaPlayer开发音视频播放器
QMediaPlayer是Qt提供的一个跨平台媒体播放器类,它没有自带解码库,而是对平台相关的播放器框架做了封装,提供了平台无关的API。所以使用QMediaPlayer播放视频,需要提前安装解码库。 在win系统下可以下载K-Lite_Codec_Pack或者LAVFilters解码库安装。
DS小龙哥
2022/01/07
3.5K0
QT应用编程:基于QMediaPlayer开发音视频播放器
Qt官方示例-拖放机器人
  Graphics View提供了QGraphicsScene类,用于管理从QGraphicsItem类派生的大量定制2D图形项目,并与之交互;还提供了QGraphicsView小部件,用于可视化项目,并支持缩放和旋转。
Qt君
2020/02/24
4.9K1
【QT】事件系统入门——QEvent 基础与示例
事件本身是 操作系统提供的 机制,Qt 也同样把操作系统事件机制进行了封装拿到了 Qt 中,但由于 事件 对应的代码编写起来不方便,因此 Qt 对于事件机制 又进行了进一步的 封装,就得到了 信号槽
IsLand1314
2025/03/14
1190
【QT】事件系统入门——QEvent 基础与示例
【QT】QT事件处理
QT中,事件作为一个对象,继承自QEvent类,常见的有键盘事件QKeyEvent、鼠标事件QMouseEvent和定时器事件QTimerEvent等。QT中,任何QObject子类示例都可以接收和处理事件。实际编程中通常实现部件的paintEvent()、mousePressEvent()等事件处理函数来处理特定部件的特定事件。
半生瓜的blog
2023/05/13
1.6K0
【QT】QT事件处理
Qt中自定义QTreeWidget实现节点拖拽复制功能[通俗易懂]
QT中在QWidget支持拖拽功能,QTreeWidget继承自QWidget,所以自然也具有节点的拖拽功能。
全栈程序员站长
2022/11/14
4.6K0
Qt中自定义QTreeWidget实现节点拖拽复制功能[通俗易懂]
Qt学习(二)------实例mynotepad制作
最近在看高老师的视频教程,自己跟着做了一个txt编辑器,功能很简单,能实现编辑,保存,撤销,复制粘贴等基础功能;关于那边有一些特效
致Great
2023/08/26
2120
Qt学习(二)------实例mynotepad制作
Qt官方示例-可拖拽本文
可对文本进行拖动到指定位置。 部分主要代码 当被鼠标拖动的对象进入其容器范围内时触发此事件 void DragWidget::dragEnterEvent(QDragEnterEvent *event
Qt君
2019/10/09
7590
其实,AI 也会糊弄你…
虽然我现在编程已经离不开 AI,但有时也会哭笑不得,因为 AI 会胡诌一个答案。特别好玩的是,当你指出回答错误的时候,AI 会继续给你一个错误的答案。
云水木石
2023/12/21
1830
其实,AI 也会糊弄你…
PyQt拖放事件(二)
在PyQt中,重新实现拖放事件处理方法,可用于处理自定义数据,或者实现一些特殊的拖放功能。
用户6021899
2019/08/14
2.9K0
相关推荐
Qt开源作品6-通用视频控件
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验