第38课 - Qt 中的事件处理(上)

1、GUI程序原理回顾 

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

2、思考 

操作系统发送的消息如何转变成Qt信号? 

3、Qt中的事件处理 

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

         - Qt事件是一个QEvent的对象 

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

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

 

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

       1. Qt事件产生后立即被分发到QWdget对象 

       2. QWidget中的event(QEvent*)进行事件处理 

       3. event()根据事件类型调用不同的事件处理函数 

       4. 在事件处理函数中发送Qt中预定义的信号 

       5. 调用信号关联的槽函数

 

场景分析:按钮点击 

QPushButton事件处理分析 

       1、接收到鼠标事件 

       2、调用event(QEvent*)成员函数 

       3、调用mouseReleaseEvent(QMouseEvent*)成员函数 

       4、调用click()成员函数 

       5. 触发信号SIGNAL(clicked()) 

4、编程实验 

自定义事件处理函数   38-1.pro 

QMyPushButton.h

#ifndef _QMYPUSHBUTTON_H_
#define _QMYPUSHBUTTON_H_

#include <QPushButton>

typedef void (QButtonListener)(QObject*, QMouseEvent*);

class QMyPushButton : public QPushButton
{
    Q_OBJECT
protected:
    QButtonListener* m_listener;

    void mouseReleaseEvent(QMouseEvent *e);
public:
    explicit QMyPushButton(QWidget* parent = 0, QButtonListener* listener = 0);
    
signals:
    
public slots:
    
};

#endif // _QMYPUSHBUTTON_H_

QMyPushButton.cpp

#include "QMyPushButton.h"
#include <QMouseEvent>

QMyPushButton::QMyPushButton(QWidget* parent, QButtonListener* listener) : QPushButton(parent)
{
    m_listener = listener;
}

void QMyPushButton::mouseReleaseEvent(QMouseEvent *e)//重写事件处理函数,事件分配后会被调用 
{
    if( m_listener != NULL )
    {
        m_listener(this, e);//调用成员指针所指向的函数onMyButtonMouseRelease,没有预定义的信号

        e->accept();//标记当前事件已经被处理

        setDown(false);//更新UI,按钮弹起
    }
    else
    {
        QPushButton::mouseReleaseEvent(e);
    }
}

Widget.h

#ifndef _WIDGET_H_
#define _WIDGET_H_

#include <QtGui/QWidget>
#include "QMyPushButton.h"

class Widget : public QWidget
{
    Q_OBJECT
    
    QMyPushButton myButton;
protected slots:
    void onMyButtonClicked();
public:
    Widget(QWidget *parent = 0);
    ~Widget();
};

#endif // _WIDGET_H_

Widget.cpp

#include "Widget.h"
#include <QDebug>

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


Widget::~Widget()
{
    
}

main.cpp

#include <QtGui/QApplication>
#include "Widget.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    
    return a.exec();
}

5、Qt中的事件处理 

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

     -事件由具体对象进行处理 

     -信号由具体对象主动产生 

     -改写事件处理函数可能导致程序行为发生改变

     -信号是否存在对应的槽函数不会改变程序行为

     -一般而言,信号在具体的事件处理函数中产生 

6、文本编辑器中的关闭操作 

7、编程实验 

文本编辑器的关闭操作    NotePad.pro 

发现QMainWindow和QWidget中没有信号可以解决当前问题

可以考虑重写事件处理函数

找到了void Widget::closeEvent(QcloseEvent*  event)

MainWindow.h新增

protected:
    void closeEvent(QCloseEvent* e);

MainWindowSlots.cpp新增

void MainWindow::closeEvent(QCloseEvent* e)
{
    preEditorChange();//确认是否保存

    if( !m_isTextChanged )
    {
        QMainWindow::closeEvent(e);
    }
    else
    {
        e->ignore();
    }
}

8、小结 

Qt中的事件(QEvent)和信号(SIGNAL)不同 

事件由QObject的对象进行处理 

信号由QObject对象触发 

重写事件处理函数可能改变程序行为 

信号的触发不会对程序行为造成影响 

事件处理是在实际工程开发中的应用非常普遍

猜你喜欢

转载自blog.csdn.net/qq_39654127/article/details/81536500