Wiki

Расположение окон MDI

by Mark Summerfield (перевод St@VRoS)
Qt обеспечивает поддержку для MDI (Multiple Document Interface) через widget QWorkspace. Рабочее пространство обеспечивает две стратегии для расположения окон-потомков. В этой статье мы покажем Вам, как легко добавлять новые стратегии расположения в QWorkspace.

Существует две стратегии размещения окон, которые доступны в QWorkspace, - это каскадирование (cascade()) и застилание (tile()).

mdi1

Стратегия управления окнами принимает во внимание то, сколько существует окон-потомков, и пытается использовать максимум пространства с максимальной пользой.

mdi2

Мы можем легко создать наши собственные стратегии размещения окон путем порождения от класса QWorkspace. Таким образом, мы создаем две новые стратегии: вертикальное и горизонтальное размещения окон. Давайте начнем с определения нашего подкласса:

#include <qworkspace.h>
 
class Workspace : public QWorkspace
{
    Q_OBJECT
 
public:
    Workspace(QWidget *parent = 0, const char *name = 0)
        : QWorkspace(parent, name)
{}
 
public slots:
    void tileVertically();
    void tileHorizontally();
};

Реализация слотов может быть непосредственной:

void Workspace::tileVertically()
{
    QWidgetList windows = windowList();
    if (windows.count() < 2) {
        tile();
        return;
    }
    int wHeight = height() / windows.count();
    int y = 0;
    for (QWidget *widget = windows.first(); widget; widget = windows.next()) {
        widget->parentWidget()->resize(width(), wHeight);
        widget->parentWidget()->move(0, y);
        y += wHeight;
    }
}

Если существует менее двух окон-потомков, то мы вызываем обычную функцию tile(). Данное действие не имеет смысла, если нет окон либо оно одно. Мы рассчитываем высоту, которую приобретет каждое окно, и затем повторяем это по всему списку окон.

Обратите внимание, что геометрические изменения по отношению к окну MDI должны применяться к parentWidget(), а не к самому окну. Точно так же, если Вы хотите вычислить геометрию окна MDI, Вы должны использовать parentWidget(). Аналогично для перехвата событий от окна MDI Вы должны установить Ваш фильтр событий на parentWidget().

mdi3

Код для горизонтального размещения окон почти такой же :

void Workspace::tileHorizontally()
{
    QWidgetList windows = windowList();
    if (windows.count() < 2) {
        tile();
        return;
    }
    int wWidth = width() / windows.count();
    int x = 0;
    for (QWidget *widget = windows.first(); widget; widget = windows.next()) {
        widget->parentWidget()->resize(wWidth, height());
        widget->parentWidget()->move(x, 0);
        x += wWidth;
    }
}

mdi4

Вертикальное и горизонтальное управление просто для понимания и использования, но что действительно делает эти две маленькие функции интересными, так это другие возможности, которые они открывают. Например, у нас могло бы быть MDI приложение, у которого были разные типы окон, каждый со своими особенностями размещения. Для подобной ситуации мы можем создать подкласс QWorkspace , который бы проходил по списку окон, как мы делали выше, но который выяснял бы тип каждого окна (используя ::qt_cast<>), определял его величину и перемещал его соответственно.
Copyright © 2003 Trolltech Trademarks