先看QT文档对topLevelWidgets()的描述:
[static] QWidgetList QApplication::topLevelWidgets()
Returns a list of the top-level widgets (windows) in the application.
Note: Some of the top-level widgets may be hidden, for example a tooltip if no tooltip is currently shown.
Example:
void showAllHiddenTopLevelWidgets()
{
foreach (QWidget *widget, QApplication::topLevelWidgets()) {
if (widget->isHidden())
widget->show();
}
}
See also allWidgets(), QWidget::isWindow(), and QWidget::isHidden().
该方法返回应用程序中所有的top-level控件(窗口).
那么,究竟哪些控件才是top-level控件?
看代码:
QWidgetList QApplication::topLevelWidgets()
{
QWidgetList list;
QWidgetList all = allWidgets();
for (QWidgetList::ConstIterator it = all.constBegin(), cend = all.constEnd(); it != cend; ++it) {
QWidget *w = *it;
if (w->isWindow() && w->windowType() != Qt::Desktop)
list.append(w);
}
return list;
}
typedef QSet<QWidget *> QWidgetSet;
static QWidgetSet *allWidgets;
QWidgetList QApplication::allWidgets()
{
if (QWidgetPrivate::allWidgets)
return QWidgetPrivate::allWidgets->toList();
return QWidgetList();
}
显然,所谓的top-level控件,返回的就是类QWidgetPrivate的静态成员变量allWidgets中那些 “有自己的窗口而且不是桌面窗口" 的控件。
静态成员变量allWidgets里面又有哪些控件?看QWidget的构造函数:
QWidget::QWidget(QWidget *parent, Qt::WindowFlags f)
: QObject(*new QWidgetPrivate, 0), QPaintDevice()
{
QT_TRY {
d_func()->init(parent, f);
} QT_CATCH(...) {
QWidgetExceptionCleaner::cleanup(this, d_func());
QT_RETHROW;
}
}
每一个QWidget的构造都会创建一个QWidgetPrivate对象,然后调用QWidgetPrivate的init()方法:
void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f)
{
Q_Q(QWidget);
if (Q_UNLIKELY(!qobject_cast<QApplication *>(QCoreApplication::instance())))
qFatal("QWidget: Cannot create a QWidget without QApplication");
Q_ASSERT(allWidgets);
if (allWidgets)
allWidgets->insert(q);
.......
}
QWidgetPrivate直接把绑定的QWidget对象(通过Q_Q(QWidget)获取)插入到了allWidgets中。
所以,分析结果就是:
任何QWidget在创建后都会放到allWidgets,而QApplication::topLevelWidgets()返回的就是除了桌面以外所有带窗口的QWidget!!!!