消息基础
一、各种消息机制
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();
}