博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Qt原理分析(六):Qt中的事件处理
阅读量:4112 次
发布时间:2019-05-25

本文共 3350 字,大约阅读时间需要 11 分钟。

Qt中的事件处理

图形界面应用程序的消息处理模型

在这里插入图片描述

问题:操作系统发送的消息如何转变为Qt信号的?

Qt事件

Qt平台将系统产生的消息转换为Qt事件

  • Qt事件是一个QEvent的对象

  • Qt事件用于描述程序内部或外部发生的动作

  • 任意的QObject对象都具备事件处理的能力

在这里插入图片描述

GUI应用程序的事件处理方式

  1. Qt事件产生后立即被分发到QWidget对象
  2. QWidget中的event(QEvent*) 进行事件处理
  3. event() 根据事件类型调用不同的事件处理函数
  4. 在事件处理函数中发送Qt中预定义的信号
  5. 调用信号关联的槽函数

情景分析:按钮点击

在这里插入图片描述

  1. OS接收到鼠标事件
  2. Qt接收到鼠标事件后调用event(QEvent*) 成员函数
  3. 调用mouseReleseEvent(QMouseEvent*) 成员函数
  4. 调用click() 成员函数
  5. 触发信号SIGNAL(clicked())

示例代码:自定义事件处理函数

//QMyPushButton.htypedef void (QButtonListener)(QObject*, QMouseEvent*);class QMyPushButton : public QPushButton{
Q_OBJECTprotected: QButtonListener* m_listener; void mouseReleaseEvent(QMouseEvent *e);public: explicit QMyPushButton(QWidget* parent = 0, QButtonListener* listener = 0); signals: public slots: };//QMyPushButton.cppQMyPushButton::QMyPushButton(QWidget* parent, QButtonListener* listener) : QPushButton(parent){
m_listener = listener;}void QMyPushButton::mouseReleaseEvent(QMouseEvent *e){
if( m_listener != NULL ) {
m_listener(this, e); e->accept(); setDown(false); } else {
QPushButton::mouseReleaseEvent(e); }}//QWidget.hclass Widget : public QWidget{
Q_OBJECT QMyPushButton myButton;protected slots: void onMyButtonClicked();public: Widget(QWidget *parent = 0); ~Widget();};//QWidget.cppvoid onMyButtonMouseRelease(QObject* sender, QMouseEvent* e){
qDebug() << "onMyButtonMouseRelease(QObject* sender, QMouseEvent* e)";}Widget::Widget(QWidget *parent) : QWidget(parent), myButton(this, onMyButtonMouseRelease){
myButton.setText("QMyPushButton"); connect(&myButton, SIGNAL(clicked()), this, SLOT(onMyButtonClicked()));}void Widget::onMyButtonClicked(){
qDebug() << "onMyButtonClicked()";}

现象:当点击按钮时,有以下输出:

onMyButtonMouseRelease(QObject* sender, QMouseEvent* e)

问题:我们在自定义事件后,槽函数就不再被执行了,为什么呢?

事件(QEvent)和信号(SIGNAL)不同

  • 事件由具体对象进行处理
  • 信号由具体对象主动产生
  • 改写事件处理函数可能导致程序行为发生改变
  • 信号是否存在对应的槽函数不会改变程序行为
  • 一般而言,信号在具体的事件处理函数中产生。

问题:自定义事件后还能继续父组件的事件吗?

在这里插入图片描述

QEvent中的关键成员函数

  • void ignore()
  • 接收者忽略当前事件,事件可能传递给父组件
  • void accept()
  • 接收者期望处理当前事件
  • bool isAccepted()
  • 判断当前事件是否被处理

示例代码:事件处理的顺序

//MyLineEdit.hclass MyLineEdit : public QLineEdit{
Q_OBJECTpublic: explicit MyLineEdit(QWidget *parent = 0); bool event(QEvent* e); void keyPressEvent(QKeyEvent* e);signals: public slots: };//MyLineEdit.cppMyLineEdit::MyLineEdit(QWidget *parent) : QLineEdit(parent){
}bool MyLineEdit::event(QEvent* e){
if( e->type() == QEvent::KeyPress ) {
qDebug() << "MyLineEdit::event"; } return QLineEdit::event(e);}void MyLineEdit::keyPressEvent(QKeyEvent* e){
qDebug() << "MyLineEdit::keyPressEvent"; QLineEdit::keyPressEvent(e); e->ignore();}//Widget.hclass Widget : public QWidget{
Q_OBJECT MyLineEdit myLineEdit;public: Widget(QWidget* parent = 0); bool event(QEvent* e); void keyPressEvent(QKeyEvent* e); ~Widget();};//Widget.cppWidget::Widget(QWidget *parent) : QWidget(parent), myLineEdit(this){
}bool Widget::event(QEvent* e){
if( e->type() == QEvent::KeyPress ) {
qDebug() << "Widget::event"; } return QWidget::event(e);}void Widget::keyPressEvent(QKeyEvent* e){
qDebug() << "Widget::keyPressEvent"; QWidget::keyPressEvent(e);}

输出结果:

MyLineEdit::event
MyLineEdit::keyPressEvent
Widget::event
Widget::keyPressEvent

转载地址:http://phhsi.baihongyu.com/

你可能感兴趣的文章
管理用户状态——Cookie与Session
查看>>
Spring MVC中使用Thymeleaf模板引擎
查看>>
PHP 7 的五大新特性
查看>>
深入了解php底层机制
查看>>
PHP中的stdClass 【转】
查看>>
XHProf-php轻量级的性能分析工具
查看>>
OpenCV gpu模块样例注释:video_reader.cpp
查看>>
【增强学习在无人驾驶中的应用】
查看>>
OpenCV meanshift目标跟踪总结
查看>>
就在昨天,全球 42 亿 IPv4 地址宣告耗尽!
查看>>
听说玩这些游戏能提升编程能力?
查看>>
如果你还不了解 RTC,那我强烈建议你看看这个!
查看>>
沙雕程序员在无聊的时候,都搞出了哪些好玩的小玩意...
查看>>
Mysql复制表以及复制数据库
查看>>
Kafka
查看>>
9.1 为我们的角色划分权限
查看>>
维吉尼亚之加解密及破解
查看>>
TCP/IP协议三次握手与四次握手流程解析
查看>>
PHP 扩展开发 : 编写一个hello world !
查看>>
inet_ntoa、 inet_aton、inet_addr
查看>>