Главная · Все классы · Основные классы · Классы по группам · Модули · Функции

Геометрия окна

QWidget обеспечивает несколько функций, позволяющих работать с геометрией окна. Некоторые из них работают только с клиентской областью окна (т.е. окном без рамки), другие включают и рамку. Различия осуществляются таким образом, чтобы покрыть наиболее используемые случаи применения прозрачности.

Помните, что украшения действуют только для виджетов верхнего уровня. Для всех виджетов-потомков геометрия области рамки совпадает с таковой у клиента.

Эта диаграмма показывает наиболее используемые функции в действии:

Диаграмма геометрии окон

Темы:

Особенности X11

В X11 окно не имеет рамки, пока оконный менеджер не украсит его. Это происходит асинхронно в какой-то момент времени после вызова QWidget::show() и первого события отрисовки окна или не происходит вообще. Помните, что X11 являются ориентированными на свободную политику (другие называют это гибкостью). Таким образом, вы не можете делать какие-либо предположения относительно безопасной отрисовки рамки в том окне, которое вы получаете. Основное правило: всегда найдётся такой пользователь, который использует менеджер окон, нарушающий вашу реализацию и который будет вам по этому поводу жаловаться.

Кроме того, инструментарий не может просто расположить окно на экране. Всё, что может сделать Qt, - послать сообщение оконному менеджеру. Оконный менеджер, являясь отдельным процессом, может подчиниться, проигнорировать или же отработать с ошибкой. Из-за частичного непонятного руководства Inter-Client Communication Conventions Manual (ICCCM), размещение окон обрабатывается по-разному в существующих оконных менеджерах.

X11 не обеспечивает никаких лёгких средств по получению размеров рамки когда окно украшено. Qt решает эту проблему эвристической обработкой и умным кодом, который работает с наиболее используемыми на сегодняшний день оконными менеджерами. Не удивляйтесь, если обнаружите однажды, что QWidget::frameGeometry() возвращает неверные результаты.

В X11 также не предусмотрен способ развёртывания окна на весь экран. QWidget::showMaximized() эмулирует эту функциональность. Его результат зависит от QWidget::frameGeometry() и возможностей оконного менеджера надлежащим образом расположить окно, и то, и другое не может быть гарантировано.

Восстановление геометрии окон

Начиная с 4.2, Qt обеспечивает функции, которые сохраняют и восстанавливают размеры и положение окон. QWidget::saveGeometry() сохраняет геометрию окна и полноэкранное или развёрнутое состояние, пока QWidget::restoreGeometry() не восстановит их. Функция восстановления также проверяет, не выходят ли окна за размеры экрана, и, если это происходит, изменяет параметры экрана, если это возможно.

Далее в этом документе описывается, как сохранить и восстановить геометрию с помощью геометрических свойств. В Windows решение данной задачи состоит в сохранении QWidget::geometry() и вызове QWidget::setGeometry() в следующей сессии перед вызовом show()(). В X11 это не будет работать, так как неотображенное окно не имеет рамки. Оконный менеджер оформит окно позже. Когда это происходит, окно сдвигается к правому нижнему углу экрана, в зависимости от оформляющей рамки. Хотя X и предоставляет способ избежать этого перемещения, наши испытания показали, что почти все оконные менеджеры не в состоянии реализовать данную возможность.

Нужно вызвать setGeometry() после show() для обхода этой проблемы. Это имеет два неудобства: на миллисекунды виджет отображается в неправильном положении (в результате эффект мерцания) и что в настоящий момент только каждый второй оконный менеджер может сделать это правильно. Более безопасное решение состоит в сохранении pos() и size() и восстановлении геометрии с помощью QWidget::resize() и move() перед вызовом show(), как показано в следующих фрагментах кода (из примера Application):

 void MainWindow::readSettings()
 {
     QSettings settings("Trolltech", "Application Example");
     QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint();
     QSize size = settings.value("size", QSize(400, 400)).toSize();
     resize(size);
     move(pos);
 }

 void MainWindow::writeSettings()
 {
     QSettings settings("Trolltech", "Application Example");
     settings.setValue("pos", pos());
     settings.setValue("size", size());
 }

Этот метод работает в Windows, Mac OS X и большинстве оконных менеджерах X11.


Copyright © 2008 Trolltech Торговые марки
Qt 4.3.5