Qt下hide()與close()相關的bug一例

本文是 QMainWindow上下文菜單內存泄露(QTBUG) 一文 的續篇,所以你很可能需要先看上文。

前傳

問題起源於:QTBUG-7902

Qt 4.6 下,下面的小程序在顯示上下文菜單的情況下會導致程序崩潰。

#include <QApplication>
#include <QTextEdit>
#include <QTimer>

int main(int argc, char **argv)
{
  QApplication app(argc, argv);
  QTextEdit *te = new QTextEdit;
  te->show();
  te->setText("right click here now");

  QTimer ti;
  te->connect(&ti, SIGNAL(timeout()), te, SLOT(deleteLater()));
  ti.start(3000);

  return qApp->exec();
}

這個問題是由於QMenu::exec()開啓的局部事件循環造成的副作用。【至於局部事件循環可能造成的各種潛在問題,可訪問亂談Qt事件循環嵌套

2010.2.9日的 b7af368e86874d71ffc9071c9ef009814d6a3467 修復這個問題

修復

採用QMenu::popup() 取代 QMenu::exec()

這也是我們在 QMainWindow上下文菜單內存泄露(QTBUG) 一文中看到的 QMainWindow的上下文菜單之所以那麼改動的原因。

內存泄漏

當看了 b7af368e86874d71ffc9071c9ef009814d6a3467 以後,我發現這個問題遠比我想想的嚴重,除了QMainWindow之外,QTextEdit/QPlainTextEdit/QLineEdit/QMessageBox 等都會存在這個問題。

於是提交了 QTBUG-22817

如何修復?

也就是我們在 QMainWindow上下文菜單內存泄露(QTBUG) 一文提到的,只需要改動一行代碼即可:

--- a/src/widgets/widgets/qmenu.cpp
+++ b/src/widgets/widgets/qmenu.cpp
@@ -500,7 +500,7 @@ void QMenuPrivate::hideMenu(QMenu *menu, bool justRegi
     menu->blockSignals(false);
 #endif // QT_NO_EFFECTS
     if (!justRegister)
-        menu->hide();
+        menu->close();
 }

參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章