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();
 }

参考

  • https://bugreports.qt.nokia.com/browse/QTBUG-19592

  • https://bugreports.qt.nokia.com/browse/QTBUG-22817

  • https://bugreports.qt.nokia.com/browse/QTBUG-7902

  • http://codereview.qt-project.org/9288

你可能感兴趣的:(c,qt,menu,Signal,2010)