消息基础

一、各种消息机制

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();
}

  

posted on 2017-12-29 14:02  rainbow1122  阅读(206)  评论(0编辑  收藏  举报