《学习Qt之路2》笔记:Qt之事件的选择

Qt有很多事件,比如,键盘事件,大小改变的事件,鼠标事件,位置移动的事件等等。

怎么选择,一般有两种方法:

一、所有事件对应一个事件处理函数,在这个事件处理函数中用很大一个分支语句进行选择,如win32 API的WndProc()函数。

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,LPARAM lParam)


二、使用switch语句,选择message参数的类型进行处理

      switch( message )

     {

            case  WM_PAINT:

             //..........

             break;

            case  WM_DESTROY:

             //..........

             break;

     }


三、每一种事件对应一个事件处理函数。Qt就是使用的这么一种机制:

       mouseEvent()

       keyPressEvent()

        ..........


总结:

 Qt 的事件处理,实际上是有五个层次:
1. 重写 paintEvent()、mousePressEvent() 等事件处理函数。这是最普通、最简单的形式,同时功能也最简单。

2. 重写 event() 函数。event() 函数是所有对象的事件入口,QObject 和 QWidget中的实现,默认是把事件传递给特定的事件处理函数。

3. 在特定对象上面安装事件过滤器。该过滤器仅过滤该对象接收到的事件。

4. 在 QCoreApplication::instance() 上面安装事件过滤器。该过滤器将过滤所有对象的所有事件,因此和 notify() 函数一样强大,但是它更灵活,因为可以安装多个过滤器。全局的事件过滤器可以看到 disabled 组件上面发出的鼠标事件。全局过滤器有一个问题:只能用在主线程。

5. 重写 QCoreApplication::notify() 函数。这是最强大的,和全局事件过滤器一样提供完全控制,并且不受线程的限制。但是全局范围内只能有一个被使用(因为QCoreApplication 是单例的)。


下面是个事件先后调用顺序测试代码:

#include <QtWidgets/QApplication>
#include <QtWidgets>



class Label : public QWidget
{
public:
	Label()
	{
		installEventFilter(this);
	}

	bool eventFilter(QObject *watched, QEvent *e)
	{
		if (watched == this)
		{
			if (e->type() == QEvent::MouseButtonPress)
			{
				qDebug()<<"eventFilter";
			}
		}
		return false;
	}

protected:
	void mousePressEvent(QMouseEvent *)
	{
		qDebug()<<"mousePressEvent";
	}

	bool event(QEvent *e)
	{
		if (e->type() == QEvent::MouseButtonPress)
		{
			qDebug()<<"event";
		}
		return QWidget::event(e);
	}
};

class EvenFilter : public QObject
{
public:
	EvenFilter(QObject *watched, QObject *parent = 0)
		: QObject(parent), m_watched(watched)
	{

	}

	bool evenFilter(QObject *watched, QEvent *e)
	{
		if (watched == m_watched)
		{
			if (e->type() == QEvent::MouseButtonPress)
			{
				qDebug()<<"QApplication::eventFilter";
			}
		}
		return false;
	}

private:
	QObject *m_watched;
};


int main(int argc, char *argv[])
{
	QApplication a(argc, argv);

	Label label;
	a.installEventFilter(new EvenFilter(&label, &label));

	label.show();

	return a.exec();
}

这里在编译中可能出现    

Cannot open include file: 'GLES2/gl2.h': No such file or directory     这样的问题。
解决方法是:缺什么就在包含目录导入什么。这里就导入include/QtANGLE/GLES2即可

你可能感兴趣的:(《学习Qt之路2》笔记:Qt之事件的选择)