消息基础
一、各种消息机制
1.头文件
#ifndef MYWIDGET_H #define MYWIDGET_H #include <QWidget> #include<QPushButton> #include<QLineEdit> class MyWidget : public QWidget { Q_OBJECT public: explicit MyWidget(QWidget *parent = nullptr); bool event(QEvent *event); //鼠标消息 void mousePressEvent(QMouseEvent *); void mouseReleaseEvent(QMouseEvent *); void mouseMoveEvent(QMouseEvent *); //建议不要用,会调用两次mousePressEvent // void mouseDoubleClickEvent(QMouseEvent *); //键盘消息 void keyPressEvent(QKeyEvent *); void keyReleaseEvent(QKeyEvent *); void closeEvent(QCloseEvent *event); //void showEvent(QShowEvent*); // void hideEvent(QHideEvent *); void paintEvent(QPaintEvent*); QPushButton *button; QLineEdit *edit; signals: public slots: void slotButtonClicked(); public slots: }; #endif // MYWIDGET_H
#include "mywidget.h" #include<QApplication> #include<QDebug> #include<QWidget> #include<QEvent> #include<QKeyEvent> #include<QMouseEvent> #include<QVBoxLayout> #include<QPainter> MyWidget::MyWidget(QWidget *parent) : QWidget(parent) { //考虑事件处理哪个窗口,鼠标是鼠标在哪个窗口上哪个窗口处理 //用按钮接受键盘,需要为其设置一个焦点,焦点处理 // QVBoxLayout* lay = new QVBoxLayout(this); QVBoxLayout*lay =new QVBoxLayout(); this->setLayout(lay); #if 0 QPushButton* button2; lay->addWidget(button = new QPushButton("OK", this)); lay->addWidget(button2 = new QPushButton("Button2")); button->setDefault(true); // �� � �不需要按下,mouseMove就能得到调用 this->setMouseTracking(true); connect(button2, SIGNAL(clicked()), this, SLOT(slotButtonClicked())); connect(button, SIGNAL(clicked()), this, SLOT(slotButtonClicked())); #endif //按回车表示输入结束 lay->addWidget(edit=new QLineEdit()); connect(edit,SIGNAL(returnPressed()),this,SLOT(slotButtonClicked())); } void MyWidget::closeEvent(QCloseEvent *event) { qDebug()<<"closeEvent"; } void MyWidget::paintEvent(QPaintEvent *) { QPainter p(this); p.drawLine(QPoint(0,0),QPoint(100,100)); } void MyWidget::slotButtonClicked() { // QPushButton* button = ( QPushButton*)sender(); // qDebug() << button->text(); QLineEdit* button = ( QLineEdit*)sender(); qDebug() << button->text(); } /*任何消息都是QApplication先得到->具体应该处理的窗口:event()->event()根据消息类型来调用具体的虚函数*/ /*用户能做的 * 1)可以重载具体的虚函数,来实现对消息的响应 * 2)可以重载event函数,用来处理或者截取消息 */ /*截取消息*/ bool MyWidget::event(QEvent *ev)//任何消息都经过这 { if(ev->type()==QEvent::MouseButtonPress) return true; return QWidget::event(ev); } void MyWidget::mousePressEvent(QMouseEvent *ev) { #if 0 QPoint pt=ev->pos(); qDebug()<<pt; if(ev->button()==Qt::LeftButton) { } if(ev->modifiers()==Qt::ShiftModifier)//伴随键,按下鼠标和shift { qDebug()<<"shift press"; } #endif if(ev->button() == Qt::LeftButton) { if(ev->modifiers() == Qt::ControlModifier) { // handle with Control; return; } // handle2 without control; } else { } } void MyWidget::mouseReleaseEvent(QMouseEvent *) { } void MyWidget::mouseMoveEvent(QMouseEvent *) { static int i=0; qDebug()<<"mouse move"<<i++;//的首先鼠标按下去之后,鼠标移动才会输出 } void MyWidget::keyPressEvent(QKeyEvent *ev) { ev->modifiers(); int key=ev->key(); qDebug()<<key; char a=key; qDebug()<<(char)a;//字母输出的都是大写 } void MyWidget::keyReleaseEvent(QKeyEvent *) {} int main(int argc, char* argv[]) { QApplication app(argc, argv); MyWidget w; w.show(); return app.exec(); }
二、消息过滤器
可以派生一个application类
MyApplication.h
#ifndef MYAPPLICATION_H #define MYAPPLICATION_H #include <QApplication> class MyApplication : public QApplication { Q_OBJECT public: MyApplication(int argc, char*argv[]):QApplication(argc, argv) {} bool notify(QObject *, QEvent *); signals: public slots: }; #endif // MYAPPLICATION_H
//MyWidget.h
#ifndef MYWIDGET_H #define MYWIDGET_H #include <QWidget> #include <QPushButton> class MyWidget : public QWidget { Q_OBJECT public: explicit MyWidget(QWidget *parent = 0); QPushButton* _button; bool eventFilter(QObject *, QEvent *); bool event(QEvent *); signals: public slots: }; #endif // MYWIDGET_H
MyApplication.cpp
#include "MyApplication.h" #include <QEvent> #include <QDebug> bool MyApplication::notify(QObject *o, QEvent *e) { if(this->topLevelWidgets().count()>0) { QWidget* mainWnd = this->topLevelWidgets().at(0); if(o==(QObject*)mainWnd && e->type() == QEvent::MouseButtonPress) { // do ... qDebug() << "mainwnd is clicked"; } } return QApplication::notify(o, e); }
MyWidget.cpp
#include "MyWidget.h" #include <QPushButton> #include <QEvent> #include "MyApplication.h" #include <QDebug> #include <QApplication> MyWidget::MyWidget(QWidget *parent) : QWidget(parent) { QPushButton* button; button = new QPushButton("This button", this); connect(button, SIGNAL(clicked()), this, SLOT(close())); _button = button; /* button给自己安装了一个消息过滤器,那么经过button的消息,都先要调用它的过滤器的eventFilter函数 */ button->installEventFilter(this); } bool MyWidget::eventFilter(QObject *o, QEvent *e) { #if 0 if(o == (QObject*)_button &&( e->type() == QEvent::MouseButtonRelease || e->type() == QEvent::MouseButtonDblClick || e->type() == QEvent::MouseButtonPress)) { return true; } #endif return QWidget::eventFilter(o, e); } bool MyWidget::event(QEvent *e) { if(e->type() == QEvent::User) { qDebug() << "User event is comming"; } return QWidget::event(e); } int main(int argc, char* argv[]) { MyApplication app(argc, argv); MyWidget w; w.show(); // 发送一个Event给MyWidget qDebug() << "begin send"; app.postEvent(&w, new QEvent(QEvent::User));//自己定义消息事件 qDebug() << "end send"; // app.sendEvent(&w, ) return app.exec(); }