Редактирование: Qt:Документация 4.3.2/layout

Материал из Wiki.crossplatform.ru

Перейти к: навигация, поиск
Внимание: Вы не представились системе. Ваш IP-адрес будет записан в историю изменений этой страницы.
Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.
Текущая версия Ваш текст
Строка 4: Строка 4:
Система компоновки Qt предоставляет простой и мощный способ компоновки дочерних виджетов.
Система компоновки Qt предоставляет простой и мощный способ компоновки дочерних виджетов.
-
Однажды задав логическое расположение, вы получаете следующие преимущества:
+
Однажды задав логическое располовжение, вы получаете следующие преимущества:
*Позиционирование дочерних виджетов.
*Позиционирование дочерних виджетов.
Строка 16: Строка 16:
-
Неудобство ручного кодирования компоновки заключается в том, что это неудобно при экспериментах в проектом формы: вы должны пройти сборку, связь и запуск при каждом изменении. Наше решение - это [[Qt:Документация 4.3.2/designer-manual#qt-designer | Qt Designer]]: визуальный инструмент разработки GUI, делающий экспериментирование с расположением быстрым и лёгким и генерирующий для Вас код C++.
+
Неудобство ручного кодирования компоновки заключается в том, что это неудобно при экспериментах в проектом формы: вы должны пройти сборку, связь и запуск при каждом изменении. Наше решение - это [[Qt:Документация 4.3.2/designer-manual#qt-designer | Qt Designer]]: визуальный инструмент разработки GUI, делающий экспериментирование с расположением быстрым и легким и генерирующий для Вас код C++.
Классы компоновки Qt были разработаны для ручного написания кода C++, поэтому они легки и понятны в использовании. Код, сгенерированный для форм, созданных с помощью [[Qt:Документация 4.3.2/designer-manual#qt-designer | Qt Designer]], также использует классы компоновки.
Классы компоновки Qt были разработаны для ручного написания кода C++, поэтому они легки и понятны в использовании. Код, сгенерированный для форм, созданных с помощью [[Qt:Документация 4.3.2/designer-manual#qt-designer | Qt Designer]], также использует классы компоновки.
-
Разделы:
 
-
 
-
*[[#horizontal-vertical-and-grid-layouts | Горизонтальный, вертикальный компоновщики и компоновщик с сеткой]]
 
-
*[[#adding-widgets-to-a-layout | Добавление виджетов в компоновщик]]
 
-
**[[#stretch-factors | Факторы растяжения]]
 
-
 
-
*[[#custom-widgets-in-layouts | Пользовательские виджеты в компоновщиках]]
 
-
*[[#layout-issues | Проблемы компоновки]]
 
-
*[[#manual-layout | Собственный компоновщик]]
 
-
*[[#writing-custom-layout-managers | Написание собственного менеджера компоновки]]
 
-
**[[#the-header-file | Файл заголовка (<tt>card.h</tt>)]]
 
-
**[[#the-implementation-file | Файл реализации (<tt>card.cpp</tt>)]]
 
-
**[[#further-notes | Последние замечания]]
 
-
 
-
<div id="horizontal-vertical-and-grid-layouts"></div>
 
==Горизонтальный, вертикальный компоновщики и компоновщик с сеткой==
==Горизонтальный, вертикальный компоновщики и компоновщик с сеткой==
Самый легкий способ задания правильного расположения виджетов состоит в использовании встроенных менеджеров компоновки: [[Qt:Документация 4.3.2/qhboxlayout | QHBoxLayout]], [[Qt:Документация 4.3.2/qvboxlayout | QVBoxLayout]] и [[Qt:Документация 4.3.2/qgridlayout | QGridLayout]]. Эти классы являются наследниками [[Qt:Документация 4.3.2/qlayout | QLayout]], который, в свою очередь, происходит от [[Qt:Документация 4.3.2/qobject | QObject]] (а не от [[Qt:Документация 4.3.2/qwidget | QWidget]]). Они берут на себя заботы об управлении геометрией и расположении виджетов. Для создания более сложных компоновок, вы можете помещать менеджеры компоновок друг в друга.
Самый легкий способ задания правильного расположения виджетов состоит в использовании встроенных менеджеров компоновки: [[Qt:Документация 4.3.2/qhboxlayout | QHBoxLayout]], [[Qt:Документация 4.3.2/qvboxlayout | QVBoxLayout]] и [[Qt:Документация 4.3.2/qgridlayout | QGridLayout]]. Эти классы являются наследниками [[Qt:Документация 4.3.2/qlayout | QLayout]], который, в свою очередь, происходит от [[Qt:Документация 4.3.2/qobject | QObject]] (а не от [[Qt:Документация 4.3.2/qwidget | QWidget]]). Они берут на себя заботы об управлении геометрией и расположении виджетов. Для создания более сложных компоновок, вы можете помещать менеджеры компоновок друг в друга.
Строка 62: Строка 47:
         window->setLayout(layout);
         window->setLayout(layout);
         window->show();</source>  
         window->show();</source>  
-
Код для [[Qt:Документация 4.3.2/qvboxlayout | QVBoxLayout]] идентичен, за исключением строки, в которой создаётся компоновщик. Код для [[Qt:Документация 4.3.2/qgridlayout | QGridLayout]] немного другой, так как мы должны задавать строки и столбцы, в которых располагаются дочерние виджеты:
+
Код для [[Qt:Документация 4.3.2/qvboxlayout | QVBoxLayout]] идентичен, за исключением строки, в которой создается компоновщик. Код для [[Qt:Документация 4.3.2/qgridlayout | QGridLayout]] немного другой, так как мы должны задавать строки и столбцы, в которых располагаются дочерние виджеты:
<source lang="cpp-qt">        QWidget *window = new QWidget;
<source lang="cpp-qt">        QWidget *window = new QWidget;
         QPushButton *button1 = new QPushButton("One");
         QPushButton *button1 = new QPushButton("One");
Строка 79: Строка 64:
         window->setLayout(layout);
         window->setLayout(layout);
         window->show();</source>  
         window->show();</source>  
-
Третий [[Qt:Документация 4.3.2/qpushbutton | QPushButton]] растягивается на 2 колонки. Это задается с помощью передачи 2 в качестве четвёртого аргумента в [[Qt:Документация 4.3.2/qgridlayout#addWidget | QGridLayout::addWidget]]().
+
Третий [[Qt:Документация 4.3.2/qpushbutton | QPushButton]] растягивается на 2 колонки. Это задается с помощью передаци 2 в качестве четвертого аргумента в [[Qt:Документация 4.3.2/qgridlayout#addWidget | QGridLayout::addWidget]]().
-
Если вы используете компоновщик, то, при создании дочерних виджетов, вы не должны передавать родителя в их конструктор. Компоновщик автоматически установит родителя виджетов (используя [[Qt:Документация 4.3.2/qwidget#setParent | QWidget::setParent]]()), так, чтобы они стали дочерними виджетами по отношению к виджету, на котором он (компоновщик) установлен.
+
Если вы используете компоновщик, то, при создании дочерних виджетов, вы не должны передавать родителя в их конструктор. Компоновщик автоматически установит родителя виджетов (используя [[Qt:Документация 4.3.2/qwidget#setParent | QWidget::setParent]]()), так, чтобы они стали дочерними виджемами по отношению к виджету, на котором он (компоновщик) установлен.
'''Важно:''' Компонуемые виджеты являются дочерними виджетами по отношению к виджету, на котором расположен компоновщик, а ''не'' по отношению к самому компоновщику. Виджеты могут иметь в качестве родителя другой виджет, а не компоновщик.
'''Важно:''' Компонуемые виджеты являются дочерними виджетами по отношению к виджету, на котором расположен компоновщик, а ''не'' по отношению к самому компоновщику. Виджеты могут иметь в качестве родителя другой виджет, а не компоновщик.
Вы можете вставлять компоновщики в другой компоновщик с помощью <tt>addLayout()</tt>; в этом случае внутренний компоновщик становится дочерним по отношению к внешнему. В примере [[Qt:Документация 4.3.2/layouts-basiclayouts | Basic Layouts]] используется данную особенность для создания сложного диалога.
Вы можете вставлять компоновщики в другой компоновщик с помощью <tt>addLayout()</tt>; в этом случае внутренний компоновщик становится дочерним по отношению к внешнему. В примере [[Qt:Документация 4.3.2/layouts-basiclayouts | Basic Layouts]] используется данную особенность для создания сложного диалога.
-
<div id="adding-widgets-to-a-layout"></div>
+
 
==Добавление виджетов в компоновщик==
==Добавление виджетов в компоновщик==
При добавлении виджета в компоновщик, компоновщик выполняет следующие действия:
При добавлении виджета в компоновщик, компоновщик выполняет следующие действия:
Строка 92: Строка 77:
#Все виджеты изначально размещаются на пространстве, соответствующем их [[Qt:Документация 4.3.2/qwidget#sizePolicy-prop | QWidget::sizePolicy]]().
#Все виджеты изначально размещаются на пространстве, соответствующем их [[Qt:Документация 4.3.2/qwidget#sizePolicy-prop | QWidget::sizePolicy]]().
#Если какие либо из виджетов имеют значение фактора растяжения, большее, чем ноль, то такие виджеты занимают свободное место в соответствии с их факторами растяжения (объяснение ниже).
#Если какие либо из виджетов имеют значение фактора растяжения, большее, чем ноль, то такие виджеты занимают свободное место в соответствии с их факторами растяжения (объяснение ниже).
-
#Если какие либо из виджетов имеют значение фактора растяжения, равное нулю, то эти виджеты получают дополнительное место только в том случае, если на дополнительное место не претендуют другие виджеты. Дополнительное место сперва отдаётся тем из этих виджетов, у которых политика размера содержит [[Qt:Документация 4.3.2/qsizepolicy#Policy-enum | Expanding]].
+
#Если какие либо из виджетов имеют значение фактора растяжения, равное нулю, то эти виджеты получают дополнительное место только в том случае, если на дополнительное место не претендуют другие виджеты. Дополнительное место сперва отдается тем из этих виджетов, у которых политика размера содержит [[Qt:Документация 4.3.2/qsizepolicy#Policy-enum | Expanding]].
#Любые виджеты, которые занимают меньше места, чем того требует их минимальный размер (или минимального места при отсутствии заданного минимального размера) располагаются на минимальном требуемом пространстве. (Виджеты не имеют минимального размера или предпочтения минимального размере, если задан их фактор растяжения.)
#Любые виджеты, которые занимают меньше места, чем того требует их минимальный размер (или минимального места при отсутствии заданного минимального размера) располагаются на минимальном требуемом пространстве. (Виджеты не имеют минимального размера или предпочтения минимального размере, если задан их фактор растяжения.)
-
#Любые виджеты, которые занимают больше места, чем их максимальный размер, размещаются на пространстве, требуемом их максимальным размером. (Виджеты не имеют максимального размера или предпочтения максимального размера, если задан их фактор растяжения.)
+
#Любые виджеты, которые занимают больше места, чем их максимальлный размер, размещаются на пространтстве, требуемом их максимальным размером. (Виджеты не имеют максимального размера или предпочтения максимального размера, если задан их фактор растяжения.)
-
<div id="stretch-factors"></div>
+
-
===Факторы растяжения===
+
-
Виджеты, обычно, создаются без заданного фактора растяжения. При помещении виджета в компоновщик ему выделяется доля общего пространства, в соответствии с максимальным значением из [[Qt:Документация 4.3.2/qwidget#sizePolicy-prop | QWidget::sizePolicy]]() и предпочтения минимального размера. Факторы растяжения используются для изменения пропорций, по отношению друг к другу, частей общего пространства выделяемых каждому виджету.
+
-
Если имеются три виджета, размещаемые с помощью [[Qt:Документация 4.3.2/qhboxlayout | QHBoxLayout]] без установленных факторов растяжения, по получается размещение подобное следующему:
+
===Факторы растяжения===
 +
Виджеты, обычно, создаются без заданного фактора растяжения. При помещении виджета в компоновщик ему выделяетс доля общего пространства, в соответствии с максимальным значением из [[Qt:Документация 4.3.2/qwidget#sizePolicy-prop | QWidget::sizePolicy]]() и предпочтения минимального размера. Факторы растяжения используются для изменения пропорций, по отношению друг к другу, частей общего пространства выделяемых каждому виджету.
 +
 
 +
Если имеются три виджета, размещаемые с помощью [[Qt:Документация 4.3.2/qhboxlayout | QHBoxLayout]] без установленных факторов растяжения, по получется размещение подобное следующему:
[[Image:layout1.png|center]]
[[Image:layout1.png|center]]
Строка 106: Строка 91:
[[Image:layout2.png|center]]
[[Image:layout2.png|center]]
-
<div id="custom-widgets-in-layouts"></div>
 
==Пользовательские виджеты в компоновщиках==
==Пользовательские виджеты в компоновщиках==
Строка 122: Строка 106:
Для получения дальнейших инструкций по реализации данных функций см. [http://doc.trolltech.com/qq/qq04-height-for-width.html Установка Высоты в Зависимости от Ширины] в ''Ежеквартальнике Qt''.
Для получения дальнейших инструкций по реализации данных функций см. [http://doc.trolltech.com/qq/qq04-height-for-width.html Установка Высоты в Зависимости от Ширины] в ''Ежеквартальнике Qt''.
-
<div id="layout-issues"></div>
+
 
==Проблемы компоновки==
==Проблемы компоновки==
Использование виджета метки с форматированным текстом может вызвать некоторые проблемы при компоновке его родительского виджета. Проблема возникает из-за способа обработки форматированного текста менеджерами компоновки Qt, если метка переносит текст по словам.
Использование виджета метки с форматированным текстом может вызвать некоторые проблемы при компоновке его родительского виджета. Проблема возникает из-за способа обработки форматированного текста менеджерами компоновки Qt, если метка переносит текст по словам.
В некоторых случаях родительский компоновщик размещается в режиме [[Qt:Документация 4.3.2/qlayout#SizeConstraint-enum | QLayout::FreeResize]], что значит отказ от адаптации содержимого компоновщика к внутренностям маленьких окон, или даже запрет пользователю на создание окон, слишком маленьких для использования. Это можно преодолеть создав подклассы проблемных виджетов и реализовав подходящим образом функции sizeHint() и minimumSizeHint().
В некоторых случаях родительский компоновщик размещается в режиме [[Qt:Документация 4.3.2/qlayout#SizeConstraint-enum | QLayout::FreeResize]], что значит отказ от адаптации содержимого компоновщика к внутренностям маленьких окон, или даже запрет пользователю на создание окон, слишком маленьких для использования. Это можно преодолеть создав подклассы проблемных виджетов и реализовав подходящим образом функции sizeHint() и minimumSizeHint().
-
<div id="manual-layout"></div>
+
 
==Собственный компоновщик==
==Собственный компоновщик==
Если вы создаете один из видов специального компоновщика, вы также можете создать один из пользовательских виджетов, как это описано выше. Заново реализуйте [[Qt:Документация 4.3.2/qwidget#resizeEvent | QWidget::resizeEvent]]() для расчета требуемых размеров и вызова [[Qt:Документация 4.3.2/qwidget#geometry-prop | setGeometry()]] для каждого дочернего объекта.
Если вы создаете один из видов специального компоновщика, вы также можете создать один из пользовательских виджетов, как это описано выше. Заново реализуйте [[Qt:Документация 4.3.2/qwidget#resizeEvent | QWidget::resizeEvent]]() для расчета требуемых размеров и вызова [[Qt:Документация 4.3.2/qwidget#geometry-prop | setGeometry()]] для каждого дочернего объекта.
Когда схема размещения элементов должна быть повторно расчитана, виджет получит сообщение типа [[Qt:Документация 4.3.2/qevent#Type-enum | QEvent::LayoutHint]]. Заново реализуйте [[Qt:Документация 4.3.2/qwidget#event | QWidget::event]]() чтобы обработать сообщения [[Qt:Документация 4.3.2/qevent#Type-enum | QEvent::LayoutHint]].
Когда схема размещения элементов должна быть повторно расчитана, виджет получит сообщение типа [[Qt:Документация 4.3.2/qevent#Type-enum | QEvent::LayoutHint]]. Заново реализуйте [[Qt:Документация 4.3.2/qwidget#event | QWidget::event]]() чтобы обработать сообщения [[Qt:Документация 4.3.2/qevent#Type-enum | QEvent::LayoutHint]].
-
<div id="writing-custom-layout-managers"></div>
+
 
==Написание собственного менеджера компоновки==
==Написание собственного менеджера компоновки==
Альтернативой ручной компоновке является написание Вашего собственного менеджера компоновки, подкласса [[Qt:Документация 4.3.2/qlayout | QLayout]]. Примеры [[Qt:Документация 4.3.2/layouts-borderlayout | Border Layout]] и [[Qt:Документация 4.3.2/layouts-flowlayout | Flow Layout]] показывают, как это сделать.
Альтернативой ручной компоновке является написание Вашего собственного менеджера компоновки, подкласса [[Qt:Документация 4.3.2/qlayout | QLayout]]. Примеры [[Qt:Документация 4.3.2/layouts-borderlayout | Border Layout]] и [[Qt:Документация 4.3.2/layouts-flowlayout | Flow Layout]] показывают, как это сделать.
Строка 138: Строка 122:
Здесь мы представим подробный пример. Класс CardLayout является подобием менеджера компоновки Java с подобным названием. Он размещает элементы (виджеты или вложенные компоновщики) поверх друг друга, каждый элемент сдвигается на [[Qt:Документация 4.3.2/qlayout#spacing-prop | QLayout::spacing]]().
Здесь мы представим подробный пример. Класс CardLayout является подобием менеджера компоновки Java с подобным названием. Он размещает элементы (виджеты или вложенные компоновщики) поверх друг друга, каждый элемент сдвигается на [[Qt:Документация 4.3.2/qlayout#spacing-prop | QLayout::spacing]]().
-
При написании Вашего класса компоновки, вы должен определить следующее:
+
При написании Вашего класса компоновки, вы должын определить следующее:
*Структура данных для хранения элементов, обрабатываемых компоновщиком. Каждый элемент является [[Qt:Документация 4.3.2/qlayoutitem | QLayoutItem]]. В этом примере мы будем использовать [[Qt:Документация 4.3.2/qlist | QList]].
*Структура данных для хранения элементов, обрабатываемых компоновщиком. Каждый элемент является [[Qt:Документация 4.3.2/qlayoutitem | QLayoutItem]]. В этом примере мы будем использовать [[Qt:Документация 4.3.2/qlist | QList]].
Строка 148: Строка 132:
В большинстве случаев, вы также должны реализовать [[Qt:Документация 4.3.2/qlayout#minimumSize | minimumSize]]().
В большинстве случаев, вы также должны реализовать [[Qt:Документация 4.3.2/qlayout#minimumSize | minimumSize]]().
-
<div id="the-header-file"></div>
+
 
-
===Файл заголовка (<tt>card.h</tt>)===
+
===Файл заголовка (<tt>card.h</tt>)===<source lang="cpp-qt">    #ifndef CARD_H
-
<source lang="cpp-qt">    #ifndef CARD_H
+
     #define CARD_H
     #define CARD_H
Строка 177: Строка 160:
         QList<QLayoutItem*> list;
         QList<QLayoutItem*> list;
     };
     };
-
     #endif</source> <div id="the-implementation-file"></div>
+
     #endif</source>  
-
===Файл реализации (<tt>card.cpp</tt>)===
+
===Файл реализации (<tt>card.cpp</tt>)===<source lang="cpp-qt">    #include "card.h"</source>  
-
<source lang="cpp-qt">    #include "card.h"</source>  
+
Сперва мы реализуем две функции, позволяющие перебирать элементы компоновщика и удалять их: itemAt() и takeAt(). Эти функции используются внутренней системой компоновщика для удаления виджетов. Они также доступны прикладным программистам.
Сперва мы реализуем две функции, позволяющие перебирать элементы компоновщика и удалять их: itemAt() и takeAt(). Эти функции используются внутренней системой компоновщика для удаления виджетов. Они также доступны прикладным программистам.
Строка 250: Строка 232:
         }
         }
         return s + n*QSize(spacing(), spacing());
         return s + n*QSize(spacing(), spacing());
-
     }</source> <div id="further-notes"></div>
+
     }</source>  
===Последние замечания===
===Последние замечания===
Данный компоновщик не обрабатывает зависимость высоты от ширины.
Данный компоновщик не обрабатывает зависимость высоты от ширины.
Строка 261: Строка 243:
Вы не должны дважды вызывать [[Qt:Документация 4.3.2/qlayoutitem#setGeometry | QLayoutItem::setGeometry]]() для одного и того-же элемента в одной функции. Это может быть очень дорого в случае, если элемент имеет несколько дочерних виджетов, так как он должен каждый раз пересчитать компоновку полностью. Вместо этого рассчитайте геометрию, а потом установите ее. (Так поступают не только применительно к компоновщику, вы должны сделать то-же самое, если реализуете собственную resizeEvent().)
Вы не должны дважды вызывать [[Qt:Документация 4.3.2/qlayoutitem#setGeometry | QLayoutItem::setGeometry]]() для одного и того-же элемента в одной функции. Это может быть очень дорого в случае, если элемент имеет несколько дочерних виджетов, так как он должен каждый раз пересчитать компоновку полностью. Вместо этого рассчитайте геометрию, а потом установите ее. (Так поступают не только применительно к компоновщику, вы должны сделать то-же самое, если реализуете собственную resizeEvent().)
 +
{{Qt4.3.2_footer}}
{{Qt4.3.2_footer}}

Пожалуйста, обратите внимание, что все ваши добавления могут быть отредактированы или удалены другими участниками. Если вы не хотите, чтобы кто-либо изменял ваши тексты, не помещайте их сюда.
Вы также подтверждаете, что являетесь автором вносимых дополнений, или скопировали их из источника, допускающего свободное распространение и изменение своего содержимого (см. Wiki.crossplatform.ru:Авторское право). НЕ РАЗМЕЩАЙТЕ БЕЗ РАЗРЕШЕНИЯ ОХРАНЯЕМЫЕ АВТОРСКИМ ПРАВОМ МАТЕРИАЛЫ!


Шаблоны, использованные на текущей версии страницы: