程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> Qt學習之路(20):事件接收與忽略

Qt學習之路(20):事件接收與忽略

編輯:關於C++

本章內容也是關於Qt事件。或許這一章不能有一個完整的例子,因為對於事件總是感覺很抽象,還是從底層上理解一下比較好的吧!

前面說到了事件的作用,下面來看看我們如何來接收事件。回憶一下前面的代碼,我們在子類中重寫了事件函數,以便讓這些子類按照我們的需要完成某些功能,就像下面的代碼:

void MyLabel::mousePressEvent(QMouseEvent * event)
{
 if(event->button() == Qt::LeftButton) {
  // do something
 } else {
  QLabel::mousePressEvent(event);
 }
}

上面的代碼和前面類似,在鼠標按下的事件中檢測,如果按下的是左鍵,做我們的處理工作,如果不是左鍵,則調用父類的函數。這在某種程度上說,是把事件向上傳遞給父類去響應,也就是說,我們在子類中“忽略”了這個事件。

我們可以把Qt的事件傳遞看成鏈狀:如果子類沒有處理這個事件,就會繼續向其他類傳遞。其實,Qt的事件對象都有一個accept()函數和 ignore()函數。正如它們的名字,前者用來告訴Qt,事件處理函數“接收”了這個事件,不要再傳遞;後者則告訴Qt,事件處理函數“忽略”了這個事件,需要繼續傳遞,尋找另外的接受者。在事件處理函數中,可以使用isAccepted()來查詢這個事件是不是已經被接收了。

事實上,我們很少使用accept()和ignore()函數,而是想上面的示例一樣,如果希望忽略事件,只要調用父類的響應函數即可。記得我們曾經說過,Qt中的事件大部分是protected的,因此,重寫的函數必定存在著其父類中的響應函數,這個方法是可行的。為什麼要這麼做呢?因為我們無法確認父類中的這個處理函數沒有操作,如果我們在子類中直接忽略事件,Qt不會再去尋找其他的接受者,那麼父類的操作也就不能進行,這可能會有潛在的危險。另外我們查看一下QWidget的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();
  }
 }
}

請注意第一條語句,如果所有子類都沒有覆蓋mousePressEvent函數,這個事件會在這裡被忽略掉,也就是停止傳播。另外也可以看到,如果你在子類直接ignore了這個事件,QWidget事件處理函數就不會被調用,那麼,後面的Popup操作或許就這麼“莫名其妙”地消失了。

不過,事情也不是絕對的。在一個情形下,我們必須使用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;
 }
}

這樣,我們經過詢問之後才能正常退出程序。

出處: http://devbean.blog.51cto.com/448512/225519

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved