Qt提供5种级别事件处理与事件过滤方法
1. 重新实现特殊的事件处理器
以QLabel为例,QLabel类中可以重写的虚函数有如下11个函数。如果期望的事件在如下10个中,就可以继承QLabel重写如下的函数。
virtual void changeEvent(QEvent *ev) override
virtual void contextMenuEvent(QContextMenuEvent *ev) override
virtual void focusInEvent(QFocusEvent *ev) override
virtual bool focusNextPrevChild(bool next) override
virtual void focusOutEvent(QFocusEvent *ev) override
virtual void keyPressEvent(QKeyEvent *ev) override
virtual void mouseMoveEvent(QMouseEvent *ev) override
virtual void mousePressEvent(QMouseEvent *ev) override
virtual void mouseReleaseEvent(QMouseEvent *ev) override
virtual void paintEvent(QPaintEvent *) override
Example:
class MyLabel : public QLabel
{
public:
MyLabel(){}
~MyLabel(){}
protected:
void changeEvent(QEvent *event)
{
Q_UNUSED(event)
/* do some thing */
}
void contextMenuEvent(QContextMenuEvent *ev){}
void focusInEvent(QFocusEvent *ev){}
bool focusNextPrevChild(bool next){}
void focusOutEvent(QFocusEvent *ev){}
void keyPressEvent(QKeyEvent *ev) {}
void mouseMoveEvent(QMouseEvent *ev) {}
void mousePressEvent(QMouseEvent *ev) {}
void mouseReleaseEvent(QMouseEvent *ev) {}
void paintEvent(QPaintEvent *ev) {}
}
2. 重新实现QObject::event()
以QLabel为例,如果QLabel类中上述的10个事件不是自己想要的。可以继承QLabel重写event(QEvent* event)函数。
virtual bool event(QEvent *e) override
Example:
class MyLabel : public QLabel
{
public:
MyLabel(){}
~MyLabel(){}
protected:
void event(QEvent *event)
{
if(QEvent::HoverEnter == event->type())
{
/* do some thing */
}
}
}
3. 在QObject中安装事件过滤器
以上都是采用重写的方式实现对特定控件事件的捕获,如果不想重写的话可以采用这种,先在控件上installEventFilter(),然后在使用该控件的类中重写eventFilter()函数;
Example:
class MainWindow : public QMainWindow
{
public:
MainWindow()
{
m_label = new QLabel;
m_label->installEventFilter(this);/* 此处只是示例 */
}
~MainWindow();
protected:
void eventFilter(QObject *target, QEvent* event)
{
if(m_lable == qobject_cast<QLabel*>(target) && event == QEvent::move)
{/* 其实可以先判断事件类型,再判断目标 */
QToolTip::showText(QCursor::pos(),“label”);
}
}
}
private:
QLabel* m_label;
}
4. 在QApplication对象中安装事件过滤器
给QApplication安装事件过滤器,如果qApp(唯一的QApplication对象)安装了事件过滤器,程序中所有对象的事件都要送到eventFilter()函数中。qApp->installEventFilter(this);之后每个事件都会到不同控件对象的eventFilter()函数中,然后在每个控件的eventFilter()函数中处理就可以了。不要重写QApplication类。
5. 子类化QApplication并重新实现notify()
QApplication类notify函数继承自[virtual] bool QCoreApplication::notify(QObject *receiver, QEvent *event)
Qt调用QApplication::nofity()来发送事件。重写这个函数是在其他事件过滤器处理事件前得到所有事件的唯一方法。通常事件过滤器是最有用的,因为在同一时间,可以有任意数量的事件过滤器,但是notify()函数只有一个。
本文根据《C++ GUI Qt4 编程》(第二版) Chapter 7所摘片段总结一下,后两条没用过,不是很了解。第五条看assitant说明用的时候需要注意一些事项,后续补充吧。