Qt的SIGNALs and SLOTs 机制不单单可以处理UI事件,还可以在函数级上互相触发信号,而由于SIGNALs and SLOTs 的强大功能,Qt的Event机制反而容易被人忽略。Event有更快的速度,SIGNALs and SLOTs有更高级的功能,具体怎么取舍还是要具体事情具体分析。
Qt的Event常见的使用情况有情况:
1.继承类,重写类的特定Event处理函数:如重写QTextEdit的focusInEvent和focusOutEvent
2.重写QObject::event(),能在事件到达类的特定Event处理函数前处理它。在需要改变Tab键的惯用法时这样做。也可以处理那些没有特定事件处理函数的比较少见的事件类型(例如,QEvent::HoverEnter)。我们重写event()时,必须要调用基类的event(),由基类处理我们不需要处理的那些情况。
3.给单独的QObject对象安装事件过滤器:对象用installEventFilter()注册后,所有目标对象的事件都首先到达监视对象的eventFilter()函数。如果一个对象有多个事件过滤器,过滤器按顺序激活,先到达最近安装的监视对象,最后到达最先安装的监视对象。
4.给QApplication对象安装事件过滤器,如果qApp(唯一的QApplication对象)安装了事件过滤器,程序中所有对象的每个事件在被送到任何其它事件过滤器之前都要送到eventFilter()函数中。这个方法在调试的时候非常有用,在处理禁止使能状态的控件的鼠标事件时这个方法也很常用。
5.继承QApplication,重写notify()。Qt调用QApplication::nofity()来发送事件。重写这个函数是在其他事件过滤器接收事件前得到所有事件的唯一方法。通常事件过滤器是最有用的,因为在同一时间,可以有任意数量的事件过滤器,但是notify()函数只有一个。
本质上QEvent是个类,用这个类的对象来进行回调
Events and Event Filters 可以参考Qt官方 http://qt.nokia.com/doc/4.6/eventsandfilters.html
Event的小例子
#include <QtGui>
#include<QtCore>
class FocusTextEdit :public QTextEdit{
public:
FocusTextEdit(QWidget * parent):QTextEdit(parent){}
void focusInEvent(QFocusEvent * e){
this->setText("Get Focus!");
}
void focusOutEvent(QFocusEvent * e){
this->setText("Lost Focus!");
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget *w=new QWidget;
w->setGeometry(100,100,300,100);
FocusTextEdit *fte1=new FocusTextEdit(w);
FocusTextEdit *fte2=new FocusTextEdit(w);
fte1->setGeometry(10,10,100,40);
fte2->setGeometry(110,10,100,40);
w->show();
return a.exec();
}
***********再补充一个Event的例子,在优快云上有人要透明效果的空间,我就做了一个
#include<QtGui> #include<QtCore>
//by microsky2813@hotmail.com
class MyLabel:public QLabel{
public:
MyLabel(const QString & text, QWidget * parent , Qt::WindowFlags f = 0 ):QLabel(text,parent,f){}
bool event ( QEvent * event ){
if(QEvent::MouseButtonPress==event->type()){
this->setText("clicked");
}
return QLabel::event(event);
}
};
int main(int argc, char *argv[])
{
QApplication qa(argc, argv);
QWidget *w=new QWidget;
w->setGeometry(100,100,200,140);
w->setPalette(QPalette(QColor(Qt::blue)));
QPushButton *pb=new QPushButton("Button",w);
pb->setPalette(QPalette(w->palette()));//只是改变了控件边界颜色
//继承于QWiget
pb->setGeometry(10,10,50,30);
pb->setIcon(QIcon());
QTextEdit *te=new QTextEdit(w);
te->setPalette(QPalette(w->palette()));//只是改变了控件边界颜色
//继承于QWiget
te->setGeometry(100,10,50,30);
QLabel *l=new QLabel("Hello",w);
l->setPalette(QPalette(w->palette()));//只是改变了控件边界颜色
//继承于QWiget
//对于label不改变背景色也可以
l->setGeometry(10,50,50,30);
MyLabel *ml=new MyLabel("Hello",w);
ml->setPalette(QPalette(w->palette()));//只是改变了控件边界颜色
//继承于QWiget
//可以接收单击事件了
ml->setGeometry(100,50,50,30);
w->show();
return qa.exec();
}
SIGNALs and SLOTs 机制
SIGNALs and SLOTs 是用于对象之间的事件引发,不要单单局限于UI
例子
main.h
#ifndef MAIN_H
#define MAIN_H
#include <QtGui/QApplication>
//#include "mainwindow.h"
#include<QtGui>
#include<QtCore>
class A:public QObject{
Q_OBJECT
public:
A(QObject *parent=0);
~A(){};
void a(){
emit s();
}
signals:
void s();
};
class B:public QObject{
Q_OBJECT
public:
B(QObject *parent=0);
~B(){};
public slots:
void b(){
qDebug()<<"b";
}
};
#endif // MAIN_H
main.cpp
#include "main.h"
A::A(QObject *parent):QObject(parent){}
B::B(QObject *parent):QObject(parent){}
int main(int argc, char *argv[])
{
QApplication ap(argc, argv);
QWidget mw;
A *a=new A;
B *b=new B;
QObject::connect(a,SIGNAL(s()),b,SLOT(b()));
a->a();
mw.show();
return ap.exec();
}
发现个要注意的地方:Q_OBJECT等相关的必须要放在.h里,否则会出现虚表错误的