Layout'ы, растяжение и сплиттеры
От: DTF  
Дата: 05.05.19 12:17
Оценка: 3 (1)
Добрый день.
Я пытаюсь разобраться в идеологии компоновки в Qt, но что-то общая картина ускользает от меня.

Набросал пачку нубских вопросов:

1. Факторы растяжения
У виджетов есть sizePolicy, а у него есть stretchFactor. И есть Layout, у которого есть layoutStretch.
Контролировать относительные размеры виджетов можно как через их sizePolicy, так и через layoutStretch того Layout'a, в котором они лежат.

1.1 Зачем тогда нужен layoutStretch? Получается некоторое дублирование функционала.
1.2 При несовпадении значений в layoutStretch со значениями в sizePolicy дочерних виджетов значения в layoutStretch имеют приоритет.
Почему? Просто потому что кто-то должен иметь приоритет, или это как-то вытекает из общей идеологии?

2. sizeHint.
Работа политик из QSizePolicy зависит от sizeHint() виджета. Этот sizeHint нельзя установить вручную, а можно только переопределить в подклассах.
2.1 Почему так сделано? Это как-то вытекает из партийной идеологии или просто потому что гладиолус?
2.2 Как в Qt Creator в режиме дизайна работать с классами, для которых переопределен sizeHint? Ведь они не отображаются на панели виджетов.
2.3 Когда именно у виджета запрашивается его sizeHint? При каждом изменении размеров окна?
2.4 В каких единицах измеряется sizeHint? В пикселях? Если да, то как борются с измельчением контролов при увеличении разрешения монитора?
2.5 В документации написано , что sizeHint "returns an invalid size if there is no layout for this widget, and returns the layout's preferred size otherwise."
Что такое "layout's preferred size", где его можно посмотреть и/или поменять?

2.6 Получается, что есть два механизме задания относительных размеров виджетов: один это sizeHint + QSizePolicy::Policy, второй — факторы растяжения.
Вроде бы факторы дублируют функционал sizeHint + QSizePolicy::Policy.
Или существуют случаи, когда через sizeHint + QSizePolicy::Policy нельзя реализовать нужное поведение?
Если да, то какие это случаи?

3. QSplitter
3.1 Сплиттер содержит в себе другие виджеты, однако у него нет аналога layoutStretch. Почему?
3.2 У меня есть два виджета по сплиттером. Факторы растяжения этих виджетов установлены в 0. Policy одного из них имеет значение Expanding, Policy другого — Minimum.
Я ожидаю, что при открытии окна виджеты примут свои размеры в соответствии с политиками.
Однако, они принимают какие-то другие размеры, я даже не могу понять, какие именно.
Почему так? Т.е. почему наличие сплиттера блокирует применение политик при открытии окна?

3.3 Виджетам под сплиттером я задаю факторы растяжения 2 и 1. Я ожидаю, что при открытии окна их размеры будут соотноситься как 2 к 1.
При отсутствии сплиттера это так. А вот при наличии сплиттера — нет. Хотя при увеличении фактора растяжения размер виджета при открытии окна увеличивается,
Вопрос: как взаимодействуют факторы растяжения виджетов под сплиттером? Т.е. по какому принципу вычисляются их размеры при открытии окна?

3.4 Как графически обозначить сплиттер? По умолчанию он выглядит как пустое место между виджетами, и, пока не наведешь на него мышку, не поймешь, что это сплиттер и его можно двигать.
Re: Layout'ы, растяжение и сплиттеры
От: Igore Россия  
Дата: 06.05.19 09:18
Оценка: 3 (1)
Здравствуйте, DTF, Вы писали:

DTF>Добрый день.

Добрый.
DTF>Я пытаюсь разобраться в идеологии компоновки в Qt, но что-то общая картина ускользает от меня.
Я по многим вопросам так глубоко не лез, поэтому отвечу только на часть. С факторами растяжения пару раз сталкивался, просто поиграться.

DTF>Набросал пачку нубских вопросов:


DTF>2. sizeHint.

DTF>Работа политик из QSizePolicy зависит от sizeHint() виджета. Этот sizeHint нельзя установить вручную, а можно только переопределить в подклассах.
Извне ты можешь установить setFixedSize и тебе никакой sizeHint не нужен, иначе ты переопределяешь sizeHint и уже во внутренней логике, обращаясь скорей всего к внутреним полям класса вычисляешь размер.
DTF>2.1 Почему так сделано? Это как-то вытекает из партийной идеологии или просто потому что гладиолус?
DTF>2.3 Когда именно у виджета запрашивается его sizeHint? При каждом изменении размеров окна?
Вроде как когда у родителя завется paintEvent(resizeEvent), в частности при изменении размера окна.
DTF>2.4 В каких единицах измеряется sizeHint? В пикселях? Если да, то как борются с измельчением контролов при увеличении разрешения монитора?
DTF>2.5 В документации написано , что sizeHint "returns an invalid size if there is no layout for this widget, and returns the layout's preferred size otherwise."
DTF> Что такое "layout's preferred size", где его можно посмотреть и/или поменять?
Это то что тебе нужно, размер(вычисленый тобой) возвращаемый в layout, давай на примере(это я придымываю), хочу выводить кнопку где еще справа отображается количество непрочитанных сообщений(красиво в кружочке а не просто текстом), переопределяем sizeHint, берем QPushButton::sizeHint() + размер под цифры, и в paintEvent отрисовываем стандартную кнопку плюс дополнительную логику. Если не переопределить sizeHint не увеличить размер кнопки, на самом деле даже minimumSizeHint нужен, то выводится счетчик будет иногда поверх текста кнопки, что не красиво.
Или вот тебе еще пример, возьми обычны QComboBox сделай модель с длинными словами, а теперь попробуй сделать так чтобы у тебя при раскрытии выводились все длинные строки с переносом, в стандартном классе такой возможности нет, но ты можешь написать свой делегат(переопределяем sizeHint) который будет вычислять высоту с учетом переноса строк и выведет тебе на экран все что нужно.

DTF>2.6 Получается, что есть два механизме задания относительных размеров виджетов: один это sizeHint + QSizePolicy::Policy, второй — факторы растяжения.

DTF> Вроде бы факторы дублируют функционал sizeHint + QSizePolicy::Policy.
DTF> Или существуют случаи, когда через sizeHint + QSizePolicy::Policy нельзя реализовать нужное поведение?
DTF> Если да, то какие это случаи?
Это две совершенно разные вещи, sizeHint говорит Layout-у как он должен отображать этот виджет, а фактор отвечает за то как уже min или prefered размеры в каком соотношении занимают свободное место в layout-e. По идее если добавить spacer в layout то factor работать не будет

DTF>3. QSplitter

DTF>3.1 Сплиттер содержит в себе другие виджеты, однако у него нет аналога layoutStretch. Почему?
DTF>3.2 У меня есть два виджета по сплиттером. Факторы растяжения этих виджетов установлены в 0. Policy одного из них имеет значение Expanding, Policy другого — Minimum.
DTF> Я ожидаю, что при открытии окна виджеты примут свои размеры в соответствии с политиками.
DTF> Однако, они принимают какие-то другие размеры, я даже не могу понять, какие именно.
DTF> Почему так? Т.е. почему наличие сплиттера блокирует применение политик при открытии окна?
Потому что у тебя в дизайнере уже есть заданая ширина/высота для виджетов разделеных сплитером, и у этих виджетов уже скорей всего есть минимальная максимальная ширина/высота, сделай какой нибудь предопределеный размер лучше, а потом сохраняй/востанавливай размеры при открытии/закрытии программы.

DTF>3.4 Как графически обозначить сплиттер? По умолчанию он выглядит как пустое место между виджетами, и, пока не наведешь на него мышку, не поймешь, что это сплиттер и его можно двигать.

Частично отображение можно через дизайнере настроить, но в основном это стили.
https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qsplitter

Можешь кстати скачать какой-нибудь проект с специфическими виджетами и там уже поиском и отладчиком смотреть что да как, вот почти 100%-ная увереность что в telegram desktop есть видженты с переопределеными sizeHint-ами.
Отредактировано 07.05.2019 8:11 Igore . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.