QT基础(二)----鼠标、键盘事件处理机制、信息拦截机制

原文地址::http://blog.csdn.net/qianqin_2014/article/details/51234752


相关文章

1、Qt中的键盘事件,以及焦点的设置(比较详细)----http://www.cnblogs.com/findumars/p/6006070.html

2、QT5的软键盘输入法实现----http://blog.csdn.net/tracing/article/details/50617571



一 鼠标事件处理机制 QEvent


新建文件或项目----其它选项----空项目----输入项目名称-----在 .pro文件中添加代码 QT += widgets gui----添加新文件----C++ Class-----输入类名mouseWidget---- 继承自QWidget
.pro文件
[cpp]  view plain  copy
  1. HEADERS += \  
  2.     mousewidget.h  
  3.   
  4. SOURCES += \  
  5.     mousewidget.cpp  
  6.   
  7. QT += widgets gui  

头文件mousewidget.h
[cpp]  view plain  copy
  1. #ifndef MOUSEWIDGET_H  
  2. #define MOUSEWIDGET_H  
  3.   
  4. #include <QWidget>  
  5. #include<QEvent>  
  6. #include<QMouseEvent>  
  7.   
  8. class mouseWidget : public QWidget  
  9. {  
  10.     Q_OBJECT  
  11. public:  
  12.     explicit mouseWidget(QWidget *parent = 0);  
  13.   
  14.     //消息处理函数是一个虚函数,当我们的类需要进行消息处理时,需要重载该虚函数才能为自己所用  
  15.     //所有窗口都可以用到Event函数,因为所有的消息传递过程都需要讲过该Event  
  16.     bool event(QEvent *);  
  17.   
  18. signals:  
  19.   
  20. public slots:  
  21. };  
  22.   
  23. #endif // MOUSEWIDGET_H  

源文件mousewidget.cpp

[cpp]  view plain  copy
  1. #include "mousewidget.h"  
  2. #include<QApplication>  
  3. #include<QDebug>  
  4.   
  5. mouseWidget::mouseWidget(QWidget *parent) : QWidget(parent)  
  6. {  
  7.   
  8. }  
  9.   
  10. bool mouseWidget::event(QEvent *ev)  
  11. {  
  12.     if(ev->type() == QEvent::MouseButtonPress)  
  13.     {  
  14.         //一般情况下我们部队鼠标按键直接通过QEvent函数处理,而是经过其子类QMouseEvent类来处理  
  15.         QMouseEvent *ev1 = (QMouseEvent *)ev;  
  16.         if(ev1->type() == QMouseEvent::MouseButtonPress)  
  17.         {  
  18.             qDebug()<<"mouse pressed!";  
  19.         }  
  20.     }  
  21.   
  22.     //注意,函数最后必须返回原来的event函数,即返回父类的event  
  23.     return QWidget::event(ev);  
  24. }  
  25.   
  26. int main(int argc, char *argv[])  
  27. {  
  28.     QApplication app(argc, argv);  
  29.   
  30.     mouseWidget w;  
  31.     w.show();  
  32.   
  33.     app.exec();  
  34. }  
运行结果:在输出的窗口中用鼠标任意点击,调试框会输出"mouse pressed!"
注意:重载的虚函数Event在实现时千万不要忘记返回父类的Event函数

二 事件的截断机制 eventFilter函数



头文件mousewidget.h

[cpp]  view plain  copy
  1. #ifndef MOUSEWIDGET_H  
  2. #define MOUSEWIDGET_H  
  3.   
  4. #include <QWidget>  
  5. #include<QEvent>  
  6. #include<QMouseEvent>  
  7. #include<QPushButton>  
  8.   
  9. class mouseWidget : public QWidget  
  10. {  
  11.     Q_OBJECT  
  12. public:  
  13.     explicit mouseWidget(QWidget *parent = 0);  
  14.   
  15.     QPushButton *_button;  
  16.     //重载消息过滤机制  
  17.     bool eventFilter(QObject *, QEvent *);  
  18.   
  19. signals:  
  20.   
  21. public slots:  
  22. };  
  23.   
  24. #endif // MOUSEWIDGET_H  

源文件mousewidget.cpp

[cpp]  view plain  copy
  1. #include "mousewidget.h"  
  2. #include<QApplication>  
  3. #include<QDebug>  
  4.   
  5. mouseWidget::mouseWidget(QWidget *parent) : QWidget(parent)  
  6. {  
  7.     QPushButton *button = new QPushButton("OK"this);  
  8.     _button = button;  
  9.     //将button按钮设置为该窗口的默认选中项目  
  10.     button->setDefault(this);  
  11.     //button为自己安装了一个消息过滤器,经过button的消息,都需要调用过滤器eventFilter函数  
  12.     button->installEventFilter(this);  
  13.   
  14.     connect(button, &QPushButton::clicked, [this](){  
  15.         this->close();  
  16.     });  
  17. }  
  18.   
  19. bool mouseWidget::eventFilter(QObject *o, QEvent *e)  
  20. {  
  21.     if(o == (QObject *)_button && (e->type() == QEvent::MouseButtonPress ||  
  22.                                    e->type() == QEvent::MouseButtonRelease ||  
  23.                                    e->type() == QEvent::MouseButtonDblClick))  
  24.     {  
  25.         return true;                //截断按钮的功能  
  26.     }  
  27.   
  28.     return QWidget::eventFilter(o, e);  
  29. }  
  30.   
  31. int main(int argc, char *argv[])  
  32. {  
  33.     QApplication app(argc, argv);  
  34.   
  35.     mouseWidget w;  
  36.     w.show();  
  37.   
  38.     app.exec();  
  39. }  

运行结果:未加 eventFilter函数之前,点击OK按钮,窗口就会自动关闭,当加上时间过滤函数之后,点击OK按钮便没有了反应。因为我们为按钮安装了一个消息过滤器,按钮要处理的消息首先要经过该事件过滤器,当时间过滤器返回的是 true的时候,就把按按钮将要指向的指令给拦截了。

 三 更精准的鼠标事件处理机制


头文件mouseWidget.h

[cpp]  view plain  copy
  1. #ifndef MOUSEWIDGET_H  
  2. #define MOUSEWIDGET_H  
  3.   
  4. #include <QWidget>  
  5. #include<QMouseEvent>  
  6. #include<QEvent>  
  7. #include<QDebug>  
  8.   
  9. class mouseWidget : public QWidget  
  10. {  
  11.     Q_OBJECT  
  12. public:  
  13.     explicit mouseWidget(QWidget *parent = 0);  
  14.   
  15.     //更精准的鼠标事件梳理函数  
  16.     void mouseMoveEvent(QMouseEvent *);  
  17.     void mousePressEvent(QMouseEvent *);  
  18.     void mouseReleaseEvent(QMouseEvent *);  
  19.     //不建议使用,因为该函数是调用两次mousePressEvent来说海鲜的  
  20.     void mouseDoubleClickEvent(QMouseEvent *);  
  21. signals:  
  22.   
  23. public slots:  
  24. };  
  25.   
  26. #endif // MOUSEWIDGET_H  

源文件mousewidget.cpp

[cpp]  view plain  copy
  1. #include "mousewidget.h"  
  2. #include<QApplication>  
  3.   
  4. mouseWidget::mouseWidget(QWidget *parent) : QWidget(parent)  
  5. {  
  6.     //鼠标不需要点下去,当鼠标在窗口内移动时就会打印消息  
  7.     this->setMouseTracking(true);  
  8. }  
  9.   
  10. void mouseWidget::mousePressEvent(QMouseEvent *ev)  
  11. {  
  12.     //获取鼠标点击的位置  
  13.     QPoint point = ev->pos();  
  14.     qDebug()<<point;  
  15.   
  16.     //鼠标点击时做出响应  
  17.     //特别注意QEvent::MouseButtonPress返回的类型和Qt::LeftButton返回的类型以及Qt::ShiftModifier返回类型的不同之处  
  18.     if(ev->type() == QEvent::MouseButtonPress)  
  19.     {  
  20.         if(ev->button() == Qt::LeftButton)  
  21.         {  
  22.             if(ev->modifiers() == Qt::ShiftModifier)  
  23.                 qDebug()<<"shift + LeftButton pressed!";  
  24.            else if(ev->modifiers() == Qt::ControlModifier)  
  25.                 qDebug()<<"control + LeftButton pressed!";  
  26.             else  
  27.                 qDebug()<<"LeftButton pressed!";  
  28.         }  
  29.         else  
  30.         {  
  31.             if(ev->modifiers() == Qt::ShiftModifier)  
  32.                 qDebug()<<"shift + RightButton pressed!";  
  33.             else if(ev->modifiers() == Qt::ControlModifier)  
  34.                 qDebug()<<"control + RightButton pressed!";  
  35.             else  
  36.                 qDebug()<<"RightButton pressed!";  
  37.         }  
  38.     }  
  39. }  
  40.   
  41. void mouseWidget::mouseMoveEvent(QMouseEvent *ev)  
  42. {  
  43.     //类中加了this.setMouseTracking(true);只要鼠标在窗口内移动,就会打印下列消息  
  44.     //否则只有拖着鼠标移动时才会打印消息  
  45.     qDebug()<<"mouse is moving...";  
  46. }  
  47.   
  48. void mouseWidget::mouseReleaseEvent(QMouseEvent *ev)  
  49. {  
  50.     if(ev->type() == QEvent::MouseButtonRelease)  
  51.         qDebug()<<"released!";  
  52. }  
  53.   
  54. void mouseWidget::mouseDoubleClickEvent(QMouseEvent *ev){}  
  55.   
  56. int main(int argc, char *argv[])  
  57. {  
  58.     QApplication app(argc, argv);  
  59.   
  60.     mouseWidget w;  
  61.     w.show();  
  62.   
  63.     app.exec();  
  64. }  

运行结果:在窗口上移动时会不断打印mouse is moving...,用不同的鼠标点击会输出不同的结果。
注意:
  • 特别注意QEvent::MouseButtonPress返回的类型和Qt::LeftButton返回的类型以及Qt::ShiftModifier返回类型的不同之处
  • 在头文件中声明的函数,在源文件中一定要实现,不然会出现编译出错的现象!!!

四 键盘事件处理机制及其输入框enter键截取内容机制


头文件keywidgets.h

[cpp]  view plain  copy
  1. #ifndef KEYWIDGETS_H  
  2. #define KEYWIDGETS_H  
  3.   
  4. #include <QWidget>  
  5. #include<QKeyEvent>  
  6. #include<QLineEdit>  
  7.   
  8. class keywidgets : public QWidget  
  9. {  
  10.     Q_OBJECT  
  11. public:  
  12.     explicit keywidgets(QWidget *parent = 0);  
  13.   
  14.     void keyPressEvent(QKeyEvent *ev);  
  15.     void keyReleaseEvent(QKeyEvent *ev);  
  16.   
  17.     QLineEdit *edit = new QLineEdit(this);  
  18. signals:  
  19.   
  20. public slots:  
  21. };  
  22.   
  23. #endif // KEYWIDGETS_H  

源文件:

[cpp]  view plain  copy
  1. #include "keywidgets.h"  
  2. #include<QApplication>  
  3. #include<QDebug>  
  4.   
  5. keywidgets::keywidgets(QWidget *parent) : QWidget(parent)  
  6. {  
  7.     edit->setPlaceholderText("Input:");  
  8.     //截取enter  
  9.     connect(edit, &QLineEdit::returnPressed, [this](){  
  10.         qDebug()<<this->edit->text();  
  11.         edit->setText("");<span style="white-space:pre">   </span>//之后将输入框内容置为空  
  12.     });  
  13.   
  14. }  
  15.   
  16. void keywidgets::keyPressEvent(QKeyEvent *ev)  
  17. {  
  18.     //打印键值  
  19.     int n = ev->key();  
  20.     qDebug()<<n;<span style="white-space:pre">      </span>//打印按键对应的数字  
  21.     qDebug()<<(char)n;<span style="white-space:pre">        </span>//打印ASCII  
  22. }  
  23. void keywidgets::keyReleaseEvent(QKeyEvent *ev)  
  24. {}  
  25.   
  26. int main(int argc, char *argv[])  
  27. {  
  28.     QApplication app(argc, argv);  
  29.   
  30.     keywidgets w;  
  31.     w.show();  
  32.   
  33.     app.exec();  
  34. }  

五 消息处理机制与QApplication中的notify通知功能


头文件MyWidget.h

[cpp]  view plain  copy
  1. #ifndef MYWIDGET_H  
  2. #define MYWIDGET_H  
  3.   
  4. #include <QWidget>  
  5.   
  6. class MyWidget : public QWidget  
  7. {  
  8.     Q_OBJECT  
  9. public:  
  10.     explicit MyWidget(QWidget *parent = 0);  
  11.   
  12.     bool event(QEvent *);  
  13.   
  14. signals:  
  15.   
  16. public slots:  
  17.   
  18. };  
  19.   
  20. #endif // MYWIDGET_H  

头文件MyApplication.h

[cpp]  view plain  copy
  1. #ifndef MYAPPLICATION_H  
  2. #define MYAPPLICATION_H  
  3.   
  4. #include <QApplication>  
  5.   
  6. class MyApplication : public QApplication  
  7. {  
  8.     Q_OBJECT  
  9. public:  
  10.   
  11.     MyApplication(int argc, char*argv[]):QApplication(argc, argv)  
  12.     {}  
  13.     bool notify(QObject *, QEvent *);  
  14.   
  15. signals:  
  16.   
  17. public slots:  
  18.   
  19. };  
  20.   
  21. #endif // MYAPPLICATION_H  

源文件MyWidget.cpp

[cpp]  view plain  copy
  1. #include "MyWidget.h"  
  2. #include <QPushButton>  
  3. #include <QEvent>  
  4. #include "MyApplication.h"  
  5. #include <QDebug>  
  6. #include <QApplication>  
  7. MyWidget::MyWidget(QWidget *parent) :  
  8.     QWidget(parent)  
  9. {  
  10.   
  11. }  
  12.   
  13.   
  14.   
  15. bool MyWidget::event(QEvent *e)  
  16. {  
  17.     if(e->type() == QEvent::User)  
  18.     {  
  19.         qDebug() << "User event is comming";  
  20.     }  
  21.     return QWidget::event(e);  
  22. }  
  23.   
  24.   
  25. int main(int argc, char* argv[])  
  26. {  
  27.     MyApplication app(argc, argv);  
  28.   
  29.     MyWidget w;  
  30.     w.show();  
  31.   
  32.     // 发送一个Event给MyWidget  
  33.     qDebug() << "begin send";  
  34.     //通过postEvent发送的消息需要等待处理  
  35.     app.postEvent(&w, new QEvent(QEvent::User));  
  36.     qDebug() << "end send";  
  37.     //通过sendEvent发送的消息需要及时处理,不建议使用  
  38.    // app.sendEvent(&w, )  
  39.   
  40.     return app.exec();  
  41. }  


源文件MyApplication.cpp

[cpp]  view plain  copy
  1. #include "MyApplication.h"  
  2. #include <QEvent>  
  3.   
  4. #include <QDebug>  
  5. bool MyApplication::notify(QObject *o, QEvent *e)  
  6. {  
[cpp]  view plain  copy
  1. //获取最上层窗口  
  2.     if(this->topLevelWidgets().count()>0)<span style="white-space:pre"> </span>//不加判断会造成程序崩溃,因为即使退出也会运行  
  3.     {  
  4.         QWidget* mainWnd = this->topLevelWidgets().at(0);  
  5.         if(o==(QObject*)mainWnd && e->type() == QEvent::MouseButtonPress)  
  6.         {  
  7.             // do ...  
  8.             qDebug() << "mainwnd is clicked";  
  9.         }  
  10.     }  
  11.   
  12.     return QApplication::notify(o, e);  
  13. }  

运行结果:
[cpp]  view plain  copy
  1. begin send  
  2. end send  
  3. User event is comming  
  4. mainwnd is clicked  
  5. mainwnd is clicked  
  6. mainwnd is clicked  
  7. mainwnd is clicked  

首先,打印消息处理信息
然后,点击主页面会打印mainwnd is clicked

六 窗口关闭前处理函数和重绘函数


头文件mousewidget.h

[cpp]  view plain  copy
  1. #ifndef MOUSEWIDGET_H  
  2. #define MOUSEWIDGET_H  
  3.   
  4. #include <QWidget>  
  5. #include<QEvent>  
  6. #include<QPainter>  
  7.   
  8. class mouseWidget : public QWidget  
  9. {  
  10.     Q_OBJECT  
  11. public:  
  12.     explicit mouseWidget(QWidget *parent = 0);  
  13.   
  14.     //关闭窗口前要处理的函数  
  15.     void closeEvent(QCloseEvent *e);  
  16.   
  17.     //重绘消息,当窗口需要重新画的时候进行重绘  
  18.     void paintEvent(QPaintEvent *);  
  19.   
  20. signals:  
  21.   
  22. public slots:  
  23. };  
  24.   
  25. #endif // MOUSEWIDGET_H  


源文件mousewidget.cpp

[cpp]  view plain  copy
  1. #include "mousewidget.h"  
  2. #include<QApplication>  
  3. #include<QDebug>  
  4.   
  5. mouseWidget::mouseWidget(QWidget *parent) : QWidget(parent)  
  6. {  
  7.   
  8. }  
  9.   
  10. //关闭窗口时要处理的阐述  
  11. void mouseWidget::closeEvent(QCloseEvent *e)  
  12. {  
  13.     qDebug()<<"before closeWindow, what you should do?";  
  14. }  
  15.   
  16. void mouseWidget::paintEvent(QPaintEvent *e)  
  17. {  
  18.     QPainter p(this);  
  19.     p.drawLine(QPoint(0, 0), QPoint(100, 100));  
  20. }  
  21.   
  22. int main(int argc, char *argv[])  
  23. {  
  24.     QApplication app(argc, argv);  
  25.   
  26.     mouseWidget w;  
  27.     w.show();  
  28.   
  29.     app.exec();  
  30. }  








  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值