一 基本概念
1.我们需要子类中重写了事件函数,以便让这些子类按照我们的需要完成某些功能,就像下面的代码:
void MyLabel::mousePressEvent(QMouseEvent * event)
{
if(event->button() == Qt::LeftButton) {
// do something
} else {
QLabel::mousePressEvent(event);
}
}
代码解释:
检测按下鼠标事件,如果按下的是左键,做我们家自己的处理工作;如果不是左键,调用父类的函数。调用父类的函数,是把事件向上传递给父类去响应,也就是说,我们在子类中“忽略”了这个事件。
2.Qt事件传递过程
Qt的事件传递可以看作链状:如果子类没有处理这个事件,就会继续向其他类传递。
但是,Qt的事件对象都有一个accept()函数和ignore()函数。
accept()函数用来告诉Qt,事件处理函数“接收”了这个事件,不要再传递;ignore()函数通知Qt,事件处理函数“忽略”了这个事件,需要继续传递,寻找另外的接受者。isAccepted()函数可以用于查询某个事件是否已被接收。
3.
在实际的应用中,accept()和ignore()函数使用频率比较低。如果希望忽略事件,只要调用父类的响应函数即可。
原因是:Qt中的事件大部分是protected的,因此,重写的函数必定存在着其父类中的响应函数。
在子类中使用ignore的话,我们无法确认父类中的这个处理函数没有操作,如果我们在子类中直接忽略事件,Qt不会再去寻找其他的接受者,那么父类的操作也就不能进行,这可能会有潜在的危险。
二.代码
1.不使用ignore和accept函数
mousePressEvent的实现代码如下:
void QWidget::mousePressEvent(QMouseEvent *event)
{
event->ignore();
if ((windowType() == Qt::Popup)) {
event->accept();
QWidget* w;
while ((w = qApp->activePopupWidget()) && w != this){
w->close();
if (qApp->activePopupWidget() == w) // widget does not want to dissappear
w->hide(); // hide at least
}
if (!rect().contains(event->pos())){
close();
}
}
}
第一条语句
event->ignore();
如果所有子类都没有覆盖mousePressEvent函数,这个事件会在这里被忽略掉,这暗示着这个组件不关心这个事件,这个事件就可能被传递给其父组件。
2.使用ignore和accpet函数
在窗口关闭的时候,我们必须使用accept()和ignore()函数。如果你在窗口关闭时需要有个询问对话框,那么代码就必须为以下方式
void MainWindow::closeEvent(QCloseEvent * event)
{
if(continueToClose()) {
event->accept();
} else {
event->ignore();
}
}
bool MainWindow::continueToClose()
{
if(QMessageBox::question(this,
tr("Quit"),
tr("Are you sure to quit this application?"),
QMessageBox::Yes | QMessageBox::No,
QMessageBox::No)
== QMessageBox::Yes {
return true;
} else {
return false;
}
}