1、图形界面应用程序的消息处理模型
2、Qt的事件处理(操作系统发送的消息如何转变成Qt信号?)
2.1、 Qt平台将系统产生的消息转换为Qt事件(每一个系统消息对象Qt平台的一个事件)
2.1.1、 Qt事件是一个QEvent的对象
2.1.2、 Qt事件用于描述程序内部或者外部发生的动作
2.1.3、 任意的QObject对象都具备事件处理的能力
2.2、 GUI应用程序的事件处理方式
2.2.1、 Qt事件产生后立即被分发到QWidget对象
2.2.2、 QWidget中的event(QEvent*)进行事件处理
2.2.3、 event()根据事件类型调用不同的事件处理函数
2.2.4、 在事件处理函数中发送Qt中预定义的信号
2.2.5、 调用信号关联的槽函数
2.3、 情景分析:按钮点击(QPushButton事件处理分析)
2.3.1、 接收到鼠标事件(代表一个系统消息)
2.3.2、 调用event(QEvent*)成员函数
2.3.3、 调用MouseReleaseEvent(QMouseEvent*)成员函数
2.3.4、 QPushButton调用clicked()成员函数
2.3.5、 触发信号SIGNAL(clicked())
编程实践:自定义事件处理函数:
QMyPushButton.h头文件
#ifndef _QMYPUSHBUTTON_H_
#define _QMYPUSHBUTTON_H_
#include <QPushButton>
typedef void (QButtonListener)(QObject*, QMouseEvent*);//QButtonListener是一个函数类型。
class QMyPushButton : public QPushButton
{
Q_OBJECT
protected:
QButtonListener* m_listener;
void mouseReleaseEvent(QMouseEvent *e);//重写事件处理函数,
public: //第二个参数是一个函数指针。自定义事件处理。
explicit QMyPushButton(QWidget* parent = 0, QButtonListener* listener = 0); //阻止隐式类型转换。
~QMyPushButton();
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)
{
//调用自定义的事件处理函数,尽管按钮的clicked信号被连接到onMyButtonClicked槽函数,但因自定义的m_listener函数里并不触发clicked信号,从而槽函数不会被调用。
m_listener(this, e);
e->accept();//事件被接收,就不再传递到父QWidget
setDown(false);//按钮设置为”弹起“状态
}
else
{
//父类的mouseReleaseEvent会调用clicked(),并触发SIGNAL(),从而调用到连接到该信号的槽函数(本例为onMyButtonClicked())
QPushButton::mouseReleaseEvent(e); //调用父类。
}
}
QMyPushButton::~QMyPushButton()
{
}
Widget.h头文件
#ifndef _WIDGET_H_
#define _WIDGET_H_
#include <QtGui/QWidget>
#include "QMyPushButton.h"
class Widget : public QWidget
{
Q_OBJECT
QMyPushButton myButton;
public 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() << "void onMyButtonMouseRelease(QObject* sender, QMouseEvent* e)";
}
Widget::Widget(QWidget *parent)//实验二:myButton(this, 0),使用默认的事件处理函数,触发信号。
: QWidget(parent), myButton(this, onMyButtonMouseRelease)//给按钮注册对应的事件处理函数。
{
myButton.setText("myButton");
connect(&myButton, SIGNAL(clicked()), this, SLOT(onMyButtonClicked()));
}
void Widget::onMyButtonClicked() //槽函数,用于接收按钮的clicked信号。
{
qDebug() << "void Widget::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();
}
2.4、 事件(QEvent)和信号(SIGNAL)不同
2.4.1、 事件由具体对象进行处理
2.4.2、 信号由具体对象主动产生
2.4.3、 改写事件处理函数可能导致程序行为发生改变
2.4.4、 信号是否存在对应的槽函数不会改变程序的行为
2.4.5、 一般而言,信号在具体的事件处理函数中产生
3、文本编辑器的关闭操作
文本编辑器的关闭操作。
修改部分:
在头文件中添加:
protected:
void closeEvent(QCloseEvent *e);//重写关闭窗口的事件处理函数。
在实现槽函数的文件中添加:
//没有对应的信号来处理的话。
void MainWindow::closeEvent(QCloseEvent *e)//重写关闭窗口的事件处理函数。
{
preEditorChanged();
if(!m_isTextChanged)
{
QMainWindow::closeEvent(e); //如果文本没改变,则调用父类的关闭事件处理函数,
}
else
{
e->ignore(); //点击取消,就忽略这个对话框。
}
}
4、小结
4.1、 事件(QEvent)和信号(SIGNAL)不同
4.2、 事件由QObject对象进行处理
4.3、 信号由QObject对象触发
4.4、 重写事件处理函数可能改变程序行为
4.5、 信号的触发不会对程序行为造成影响
4.6、 事件处理是在实际工程开发中应用非常普遍。