addSubWindow QMdiArea

Пытаемся разобраться как красиво располагать окна (QMdiSubWindow) на QMdiArea.

Что главное надо уяснить сначала : иерархия создаваемых виджетов такова :


"" widget :  "logDlg"
"  " size :  QSize(446, 451)  sizeHint :  QSize(314, 304)
"  " layout :  "logDlg_QMdiSubWindow_layout"  size :  QSize(446, 451)  sizeHint :  QSize(314, 304)
"    " widget :  "QMdiSubWindow_logDlg"
"      " size :  QSize(1658, 959)  sizeHint :  QSize(-1, -1)
"      " widget :  "mdiArea_viewport"
"        " size :  QSize(1658, 959)  sizeHint :  QSize(1120, 856)
"        " widget :  "mdiArea"
"          " size :  QSize(1680, 981)  sizeHint :  QSize(1142, 722)
"          " layout :  "Window1_verticalLayout"  size :  QSize(1680, 981)  sizeHint :  QSize(1142, 722)
"            " widget :  "Window1_cntW"
"              " size :  QSize(1680, 1021)  sizeHint :  QSize(1142, 762)
"              " layout :  "_layout"  size :  QSize(1680, 1021)  sizeHint :  QSize(1142, 762)
"                " widget :  "Window1"

Как вы думаете , что это за код ниже ? (из исходников Qt 4.8.1 QtSources):

QMdiSubWindow *QMdiArea::addSubWindow(QWidget *widget, Qt::WindowFlags windowFlags)
{
    if (!widget) {
        qWarning("QMdiArea::addSubWindow: null pointer to widget");
        return 0;
    }

    Q_D(QMdiArea);
    // QWidget::setParent clears focusWidget so store it
    QWidget *childFocus = widget->focusWidget();
    QMdiSubWindow *child = qobject_cast(widget);

    // Widget is already a QMdiSubWindow
    if (child) {
        if (d->childWindows.indexOf(child) != -1) {
            qWarning("QMdiArea::addSubWindow: window is already added");
            return child;
        }
        child->setParent(viewport(), windowFlags ? windowFlags : child->windowFlags());
    // Create a QMdiSubWindow
    } else {
        child = new QMdiSubWindow(viewport(), windowFlags);
        child->setAttribute(Qt::WA_DeleteOnClose);
        child->setWidget(widget);
        Q_ASSERT(child->testAttribute(Qt::WA_DeleteOnClose));
    }

    if (childFocus)
        childFocus->setFocus();
    
    d->appendChild(child);
    return child;
}

void QMdiAreaPrivate::appendChild(QMdiSubWindow *child)
{
    Q_Q(QMdiArea);
    Q_ASSERT(child && childWindows.indexOf(child) == -1);

    if (child->parent() != viewport)
        child->setParent(viewport, child->windowFlags());
    childWindows.append(QPointer(child));

    if (!child->testAttribute(Qt::WA_Resized) && q->isVisible()) 
    {
        QSize newSize(child->sizeHint().boundedTo(viewport->size()));
        child->resize(newSize.expandedTo(qSmartMinSize(child)));
    }

    if (!placer)
        placer = new MinOverlapPlacer;
    place(placer, child);

    if (hbarpolicy != Qt::ScrollBarAlwaysOff)
        child->setOption(QMdiSubWindow::AllowOutsideAreaHorizontally, true);
    else
        child->setOption(QMdiSubWindow::AllowOutsideAreaHorizontally, false);

    if (vbarpolicy != Qt::ScrollBarAlwaysOff)
        child->setOption(QMdiSubWindow::AllowOutsideAreaVertically, true);
    else
        child->setOption(QMdiSubWindow::AllowOutsideAreaVertically, false);

    internalRaise(child);
    indicesToActivatedChildren.prepend(childWindows.size() - 1);
    Q_ASSERT(indicesToActivatedChildren.size() == childWindows.size());

#ifndef QT_NO_TABBAR
    if (tabBar) 
    {
        tabBar->addTab(child->windowIcon(), tabTextFor(child));
        updateTabBarGeometry();
        if (childWindows.count() == 1 && !(options & QMdiArea::DontMaximizeSubWindowOnActivation))
            showActiveWindowMaximized = true;
    }
#endif

    if (!(child->windowFlags() & Qt::SubWindow))
        child->setWindowFlags(Qt::SubWindow);
    child->installEventFilter(q);

    QObject::connect(child, SIGNAL(aboutToActivate()), q, SLOT(_q_deactivateAllWindows()));
    QObject::connect(child, SIGNAL(windowStateChanged(Qt::WindowStates,Qt::WindowStates)),
                     q, SLOT(_q_processWindowStateChanged(Qt::WindowStates,Qt::WindowStates)));
}
Q_GUI_EXPORT QSize qSmartMinSize(const QWidget *w)
{
    return qSmartMinSize(w->sizeHint(), w->minimumSizeHint(),
                            w->minimumSize(), w->maximumSize(),
                            w->sizePolicy());
}
Q_GUI_EXPORT QSize qSmartMinSize(const QSize &sizeHint, const QSize &minSizeHint,
                                 const QSize &minSize, const QSize &maxSize,
                                 const QSizePolicy &sizePolicy)
{
    QSize s(0, 0);

    if (sizePolicy.horizontalPolicy() != QSizePolicy::Ignored) {
        if (sizePolicy.horizontalPolicy() & QSizePolicy::ShrinkFlag)
            s.setWidth(minSizeHint.width());
        else
            s.setWidth(qMax(sizeHint.width(), minSizeHint.width()));
    }

    if (sizePolicy.verticalPolicy() != QSizePolicy::Ignored) {
        if (sizePolicy.verticalPolicy() & QSizePolicy::ShrinkFlag) {
            s.setHeight(minSizeHint.height());
        } else {
            s.setHeight(qMax(sizeHint.height(), minSizeHint.height()));
        }
    }

    s = s.boundedTo(maxSize);
    if (minSize.width() > 0)
        s.setWidth(minSize.width());
    if (minSize.height() > 0)
        s.setHeight(minSize.height());

    return s.expandedTo(QSize(0,0));
}
inline QSize QSize::boundedTo(const QSize & otherSize) const
{
    return QSize(qMin(wd,otherSize.wd), qMin(ht,otherSize.ht));
}
inline QSize QSize::expandedTo(const QSize & otherSize) const
{
    return QSize(qMax(wd,otherSize.wd), qMax(ht,otherSize.ht));
}

Это часть кода исходников , которая объясняет работу функции addSubWindow .
addSubWindow добавляет ваше окно QMdiSubWindow к QMdiArea.

Чтобы понять , какие параметры надо выставить для вашего окна , надо разобрать , что addSubWindow делает.