Название: [Лэйауты] Хочется странного Отправлено: SLiDER от Октябрь 09, 2009, 16:28 Вот появилась у меня нужда создать следующую раскладку виджетов (см. приложенную картинку). В двух словах проблема следующая. Есть (допустим) три виджета: верхний, левый и правый; уложенные в QGridLayout по следующей схеме, верхний - лежит в нулевой и первой ячейках нулевго ряда, ну, а левый и правый под ним в нулевой и первой ячейках первого ряда соотвественно (опять же см. рисунок). Необходимо скрывать и показывать правый виджет, по нажатию на кнопку расположенную на левом виджете, так что бы после того как правый виджет был показан а затем скрыт, диалог возвращался к первозданному виду.
Утрахался уже, может у кого есть какие мысли на эту тему, просьба поделиться. К посту кроме картинки прикладываю тестовый проект, так что можно потренироваться :) Название: Re: [Лэйауты] Хочется странного Отправлено: andrewshkovskii от Октябрь 09, 2009, 16:53 Может попробовать сплиттер запихнуть между колонкой с кнопкой и самим "двигающимся" виджетом? При нажатии кнопки сплиттер отодвигать и прятать, при повторном возвращать в было состояние, и фильтровать ивенты сплиттера на ручное его передвижение?
Название: Re: [Лэйауты] Хочется странного Отправлено: Mitchel от Октябрь 09, 2009, 18:22 есть вариант (может не совсем красивый) при show сохранять размены окна, а при нажатии hide устанавливать сохранённые размеры
Название: Re: [Лэйауты] Хочется странного Отправлено: pastor от Октябрь 09, 2009, 18:27 В книге Бланшетте есть пример, реализующий такой диалог (More >>)
Название: Re: [Лэйауты] Хочется странного Отправлено: SLiDER от Октябрь 10, 2009, 00:04 есть вариант (может не совсем красивый) при show сохранять размены окна, а при нажатии hide устанавливать сохранённые размеры А Вы проект приложенный посмотрите, там попытка поступить именно таким образом, ни х.... ни получается, ибо при вызове setVisible(false), реальные размеры спрятываемого виджета, реально меняются х.з. когда, но не сразу после вызова этой функции, а так как у него установлен минимальный размер и весьма большой то и попытка изменения размера диалога не проходит. Название: Re: [Лэйауты] Хочется странного Отправлено: SLiDER от Октябрь 10, 2009, 00:09 В книге Бланшетте есть пример, реализующий такой диалог (More >>) Здравствуйте капитан Очевидность, какими судьбами :) К сожалению в данном случае вся мощь разума господина Бланшетте не в состоянии помочь моей беде. Неверите ??? Попробуйте реализовать, тестовый проект я приложил. :) Название: Re: [Лэйауты] Хочется странного Отправлено: SLiDER от Октябрь 10, 2009, 00:14 Может попробовать сплиттер запихнуть между колонкой с кнопкой и самим "двигающимся" виджетом? При нажатии кнопки сплиттер отодвигать и прятать, при повторном возвращать в было состояние, и фильтровать ивенты сплиттера на ручное его передвижение? Основная проблема в том, что окно не масштабируется обратно, сплиттер здесь не поможет. Название: Re: [Лэйауты] Хочется странного Отправлено: Igors от Октябрь 10, 2009, 06:18 Код: void MyDialog::on_btnLeft_clicked( void ) Название: Re: [Лэйауты] Хочется странного Отправлено: Marat(Qt) от Октябрь 11, 2009, 15:02 Код: void MyDialog::on_btnLeft_clicked() Название: Re: [Лэйауты] Хочется странного Отправлено: CroCIV от Октябрь 12, 2009, 08:20 решал такую проблему, два дня протра... пока не понял как оно устроено. Вощем простейший способ это скрываемую область сделать виджетом, несколько раз удостовериться в том что ни у одного из не скрываемых виджетов нет сайз политики на Экспандинг или Минимум экспандинг. Нельзя пользоваться распорками в данном случае горизонтальными, если распорки все же нужны, то их необходимо скрывать вместе со скрываемым виджетом, т.к. политика Фиксед не прокатывает их серавно распупыживает.
Если не поможет, значит подозреваю, что на главной форме используется компановка типа грид, верхняя ячейка которой какбэ объединена, в этом случае тоже должно работать но лучше начинать с простого, скомпануй по другому через доп лайоуты, если даже простейшая форма не работает как надо, то такого не бывает ;D Но, если вдруг всетаки не работает, то всегда можно переопределить сайзхинт в данном случае у главного окна и управлять им каг душе угодно. В примере у меня какраз у тривьюхи переопределен сайзхинт, распупыживается по контенту или пока свободное место на не скрываемой части формы не кончится Название: Re: [Лэйауты] Хочется странного Отправлено: Danila_Bagrofff от Октябрь 12, 2009, 10:53 я однажды тоже долго мучался с QGridLayout и сложной компановкой с переменным количеством виджетов. В итоге компонвал обычными QVBoxLayout и QHBoxLayout. Все получилось более толково.
Название: Re: [Лэйауты] Хочется странного Отправлено: SLiDER от Октябрь 12, 2009, 17:52 Выношу большую благодарность всем принявшим участие в обсуждении, особенно Igors и Marat(Qt). Оба последних предложенный варианта в большей или меньшей степени приблизились к требуемой функциональности, первый в большей, а второй в меньшей.
Первый вариант (пользователя Igors) правда тоже не был лишен недостатков, и при его использовании получались артефакты показанные на рисунке 1, а если установить минимальную ширину (таким образом: frmLeft->setMinimumWidth(frmLeft->sizeHint().width())) для левого виджета, о и такие как на рисунке 2. Второй вариант (пользователя Marat(Qt)) не запоминал изменения геометрии внесенный пользователем и при скрытии правого виджета всегда принимал некий дефолтный размер, вероятно навязываемый ему лэйаутом, а при установке минимальной ширины (таким образом: frmLeft->setMinimumWidth(frmLeft->sizeHint().width())) для левого виджета, вообще переставал работать. Были еще какие-то неуловимые глюки связанные с масштабирование, но их очень долго описывать, а мне лень :). Однако на базе материалов из данного треда, сегодня родился вариант, который меня удовлетворяет на все 100%, если не считать того что выглядит он не слишком изящно (некую похожую функциональность хотелось бы иметь прямо в библиотеке), однако вот он (для любопытствующих прикладываю и тестовый проект): Код: void MyDialog::on_btnLeft_clicked() P.S. При проведении экспериментов был обнаружен глюк в Qt. При создании и показе диалога, метод geometry() возвращает не валидные значения для координат x и y, а именно равные нулю, вне зависимости от того где он появляется. А если его передвинуть или отмасштабировать, то координаты возвращаются правильные. Название: Re: [Лэйауты] Хочется странного Отправлено: Igors от Октябрь 12, 2009, 18:43 Здравствуйте, SLiDER
1) Проверил Ваш вариант - у меня не работает (Qt 4.5.2). Окно сокращается при каждом show/hide. Кроме того после show ресайз становится ограничен - а об этом не просили. 2) Понятно что все spacing надо добавлять и размер самому вычислять но делать эту рутинную работу никому не хочется :) То что setGeometry не отрабатывает (без выкрутасов) ясно показывает - собака там порылась. Так что надо согласиться с тем что уже сказали - проще/практичнее избегать этого места. Не разглядел артефакт на рисунке 1 (амбиций не имею просто интересно где :)) Название: Re: [Лэйауты] Хочется странного Отправлено: SABROG от Октябрь 12, 2009, 18:56 P.S. При проведении экспериментов был обнаружен глюк в Qt. При создании и показе диалога, метод geometry() возвращает не валидные значения для координат x и y, а именно равные нулю, вне зависимости от того где он появляется. А если его передвинуть или отмасштабировать, то координаты возвращаются правильные. Сам ты глюк :) Читай документацию про geometry. У тебя будут не валидные данные до тех пор пока не отработает цикл событий, а с ним и компановка виджетов через Layout'ы. Название: Re: [Лэйауты] Хочется странного Отправлено: SLiDER от Октябрь 12, 2009, 21:25 Здравствуйте, SLiDER 1) Проверил Ваш вариант - у меня не работает (Qt 4.5.2). Окно сокращается при каждом show/hide. Кроме того после show ресайз становится ограничен - а об этом не просили. Эммм, вот сейчас не понял. Окно после show должно было растянуться на размер показанного виджета, а после hide ровно на его же размер и схлопнуться. У Вас мой пример не так работатет? А ресайз после показа правого виджета оганичен в меньшую сторону, что естественно, ибо определяется установленной миимальной шириной левого и правого виджетов, выставленной ручками. 2) Понятно что все spacing надо добавлять и размер самому вычислять но делать эту рутинную работу никому не хочется :) То что setGeometry не отрабатывает (без выкрутасов) ясно показывает - собака там порылась. Так что надо согласиться с тем что уже сказали - проще/практичнее избегать этого места. Да все понятно ;), просто примененая Вами конструкция - > setMinimumWidth(minimumWidth()) это вещь в себе особенно если до этого невыставить minimumWidth руками, ибо по умолчанию оно всегда будет равно нулю (покрайней мере в нашем примере), и единственное что оно делает ... а что вот собственно она делает ... нет, ну понятно, что выставляет некий минимальный размер для ширины виджета, однако все побочные действия не так уж и ясны, я сегодня полазил по исходникам Qt. Скажем там все весьма не тривиально :-\, одно можно сказать точно, что создается некий новый объект содержимое которого каким-то образом учитывается в последствии при вычислении размеров. И установка данного значения в ноль для нашего левого виджета вовсе не значит, что нам удасться схлопнуть его в ничто.Не разглядел артефакт на рисунке 1 (амбиций не имею просто интересно где :)) Дык, правый виджет же обрезан, т.е. окно отмасштабировалось, а он нет, и не должен был, но и кно недолжно.Название: Re: [Лэйауты] Хочется странного Отправлено: SLiDER от Октябрь 12, 2009, 21:34 Сам ты глюк :) Читай документацию про geometry. У тебя будут не валидные данные до тех пор пока не отработает цикл событий, а с ним и компановка виджетов через Layout'ы. Это кто еще из нас глюк :D Может у меня какая-то другая документация, но в ней точно ни где не написано, что если я создал диалог, а затем нажал на нем кнопку в обработчике которой, попытавшись определить текущие координаты диалога, обязательно получу нули, если не попробую его перед этим подвигать или отмасштабировать. Просвятите неграмотного где это написано ??? Название: Re: [Лэйауты] Хочется странного Отправлено: CroCIV от Октябрь 13, 2009, 08:26 Вот смотрю на Ваши муки и сострадальческие слезы наворачиваются пряма :'( ;D. Вот две минуты заняло, в чем тут проблема ? Дольше компоненты на форму выкидывал.
Держи, не насилуй людям мск ;) Название: Re: [Лэйауты] Хочется странного Отправлено: CroCIV от Октябрь 13, 2009, 08:29 если надо, могу сделать в спп, но вечером тока, если не забуду...
Название: Re: [Лэйауты] Хочется странного Отправлено: Igors от Октябрь 13, 2009, 14:51 если надо, могу сделать в спп, но вечером тока, если не забуду... Ну как "надо" - просто интересно, полезно. Если найдете минутку для cpp, не забудьте пожалуйста добавить 2 детальки которые ui (пока) не делает1) Левая панель должна тоже сайзиться (всегда) 2) Правая панель должна запоминать свой размер и восстанавливать его при следующем show На разнообразные контролы в правой панели время тратить не нужно. Спасибо Название: Re: [Лэйауты] Хочется странного Отправлено: CroCIV от Октябрь 13, 2009, 16:33 так я тоже делал, но там все не так просто, там я что-то перекрывал, помоему сайзхинт(), короче сегодня точно не покажу, времени нет совсем, завтра не знаю, и ИМХО не правая панель запоминает свой размер, а вся форма запоминает свои размеры в свернутом и в развернутом состоянии на момент их последнего изменения... а я, кстати, вспомнил, как это примерно делается, размеры еще совал в реестр...
Название: Re: [Лэйауты] Хочется странного Отправлено: SABROG от Октябрь 13, 2009, 22:53 Это кто еще из нас глюк :D Готов признать, что проблема в другом. Дай угадаю, приложение запускается не под Windows. Скорее всего Linux. Документация - http://doc.qt.nokia.com/latest/geometry.html говорит нам, что гарантий нет никаких в этом случае: Цитировать X11 provides no standard or easy way to get the frame geometry once the window is decorated. Qt solves this problem with nifty heuristics and clever code that works on a wide range of window managers that exist today. Don't be surprised if you find one where QWidget::frameGeometry() returns wrong results though. На этом форуме уже был подобный вопрос и пришли к выводу, что надо настраивать свой Windows Manger соответствующим образом. Вроде бы даже есть опция в WM, которая будет любые открываемые окна центрировать на экране, при этом координаты окна будут 0,0. Попробуй сам центрировать (http://wiki.crossplatform.ru/index.php/%D0%9A%D0%B0%D0%BA_%D1%80%D0%B0%D1%81%D0%BF%D0%BE%D0%BB%D0%BE%D0%B6%D0%B8%D1%82%D1%8C_%D0%BE%D0%BA%D0%BD%D0%BE_%D0%BF%D0%BE_%D1%86%D0%B5%D0%BD%D1%82%D1%80%D1%83_%D1%8D%D0%BA%D1%80%D0%B0%D0%BD%D0%B0%3F) окно. Название: Re: [Лэйауты] Хочется странного Отправлено: SLiDER от Октябрь 13, 2009, 23:21 Вот смотрю на Ваши муки и сострадальческие слезы наворачиваются пряма :'( ;D. Вот две минуты заняло, в чем тут проблема ? Дольше компоненты на форму выкидывал. Держи, не насилуй людям мск ;) Эммм, Ваша ... ммммм ... штука не то чтобы не работает, но работает не так как надо, могу поспорить, что когда она заработатет так как надо, то выглядеть это решение будет весьма похожим на мой последний вариант. Однако будет весьма занятно взглянуть на еще один варриант решения :) Ждем. Реокмендую воспользоваться тестовым проектом, так сказать для унификации. Название: Re: [Лэйауты] Хочется странного Отправлено: SLiDER от Октябрь 13, 2009, 23:35 Это кто еще из нас глюк :D Готов признать, что проблема в другом. Дай угадаю, приложение запускается не под Windows. Скорее всего Linux. Документация - http://doc.qt.nokia.com/latest/geometry.html говорит нам, что гарантий нет никаких в этом случае: Цитировать X11 provides no standard or easy way to get the frame geometry once the window is decorated. Qt solves this problem with nifty heuristics and clever code that works on a wide range of window managers that exist today. Don't be surprised if you find one where QWidget::frameGeometry() returns wrong results though. На этом форуме уже был подобный вопрос и пришли к выводу, что надо настраивать свой Windows Manger соответствующим образом. Вроде бы даже есть опция в WM, которая будет любые открываемые окна центрировать на экране, при этом координаты окна будут 0,0. Попробуй сам центрировать (http://wiki.crossplatform.ru/index.php/%D0%9A%D0%B0%D0%BA_%D1%80%D0%B0%D1%81%D0%BF%D0%BE%D0%BB%D0%BE%D0%B6%D0%B8%D1%82%D1%8C_%D0%BE%D0%BA%D0%BD%D0%BE_%D0%BF%D0%BE_%D1%86%D0%B5%D0%BD%D1%82%D1%80%D1%83_%D1%8D%D0%BA%D1%80%D0%B0%D0%BD%D0%B0%3F) окно. Да, речь идет о Linux и KDE4. Однако приведенная Вами цитата не имеет ни какого оношения к описанной мною проблеме, а говорит о невозможности точно получить так называемую frame-геометрию окна, т.е. размеры окна с учетом декораций которые на него навешивает оконный менеджер, ибо таких менеджеров туева хуча и способы декорирования у всех разные. З.Ы. Кстати, забавным выглядит тот факт, что стоит сдвинуть или отмасштабировать окно хотя бы на пиксел (все равно как, руками или програмно) метод geometry() (как я уже говорил) начинает возвращать вполне валидные значения, так что похоже всетаки глюк :) Название: Re: [Лэйауты] Хочется странного Отправлено: CroCIV от Октябрь 14, 2009, 12:37 Ну я бы сделал как-нибудь так, единственное что мне тут не нравится, это пропорциональное увеличение панелей QSliderа... очень не нравится... хотелось бы, чтобы при растяжении формы, когда видима правая панель, только правая панель и растягивалась бы, а левая свой размер меняло только от действий пользователя.
Жду замечаний Название: Re: [Лэйауты] Хочется странного Отправлено: Igors от Октябрь 14, 2009, 13:44 Ну я бы сделал как-нибудь так, единственное что мне тут не нравится, это пропорциональное увеличение панелей QSliderа... очень не нравится... хотелось бы, чтобы при растяжении формы, когда видима правая панель, только правая панель и растягивалась бы, а левая свой размер меняло только от действий пользователя. Ну растягивать только правую не вопросЖду замечаний Код: splttr->setStretchFactor(0, 0); Название: Re: [Лэйауты] Хочется странного Отправлено: CroCIV от Октябрь 14, 2009, 15:11 Ну растягивать только правую не вопрос Это зачет! )) ваще модно работает.Код: splttr->setStretchFactor(0, 0); А вот когда скрывается правая, видны конвульсии кнопки "Show right" А еще если раздвинуть форму и начать быстро кликать по кнопке, то форма в конце концов ужмется до минсайза ;D )))вот патч: Код: QSize MyDialog::sizeHint() и когда правая открывается - видна лишняя перерисовка. Так что "не лишено недостатков" (как сказал бы SLiDER :)) ниче такого не наблюдаю :-\Название: Re: [Лэйауты] Хочется странного Отправлено: Igors от Октябрь 14, 2009, 15:55 return QSize(LWidth+RWidth+splttr->handleWidth(),this->height()); А чем это отличается от того что сформулировал SLiDER - аккуратно подсчитать размер с учетом всех спейсов лайаута? Только тем что на 3 члена класса больше? :) Название: Re: [Лэйауты] Хочется странного Отправлено: SLiDER от Октябрь 14, 2009, 20:37 Вот такая вот красота с Вашим CroCIV вариантом у меня получается, не слишком красиво ;)
Название: Re: [Лэйауты] Хочется странного Отправлено: CroCIV от Октябрь 15, 2009, 07:53 А чем это отличается от того что сформулировал SLiDER - аккуратно подсчитать размер с учетом всех спейсов лайаута? Только тем что на 3 члена класса больше? :) ну я и не говорил, что будет совсем по другому, я говорил, что делал такое(похожее), а щас реализовал с использованием слайдера, и поведение формы, на мой взгляд самое адекватное.Вот такая вот красота с Вашим CroCIV вариантом у меня получается, не слишком красиво ;) тут необходимо играться с Код: void MyDialog::sltBtnLeft() Название: Re: [Лэйауты] Хочется странного Отправлено: CroCIV от Октябрь 15, 2009, 07:59 о а вот и не проблема, вот патч
Код: MyDialog::MyDialog(QWidget* parent, Qt::WindowFlags flags) Код: void MyDialog::sltBtnLeft() Название: Re: [Лэйауты] Хочется странного Отправлено: CroCIV от Октябрь 15, 2009, 08:05 для тех кому совсем лень
Название: Re: [Лэйауты] Хочется странного Отправлено: spectre71 от Октябрь 15, 2009, 09:46 для тех кому совсем лень Не работает. Вернее криво работает. Название: Re: [Лэйауты] Хочется странного Отправлено: CroCIV от Октябрь 15, 2009, 10:25 для тех кому совсем лень Не работает. Вернее криво работает. Ах атстанте надоело ;D Багрепорт надо в техподдержку писать, чтоб QSplitter вот так (http://www.prog.org.ru/index.php?action=dlattach;topic=10848.0;attach=1309;image) не делал, и предидущий вариант будет полностью работоспособным. Название: Re: [Лэйауты] Хочется странного Отправлено: spectre71 от Октябрь 15, 2009, 10:42 1) Не надо в данном случае использовать QGridLayout !!!
2) Вот пример. Но поскольку Layouts в QT всегда криво работали, то до конца правильно сделать можно только если их переписать. :( Наблюдается небольшое увеличение левой панели(QT баг). Причина ошибки становиться понятной при включеном "Fixed" Название: Re: [Лэйауты] Хочется странного Отправлено: spectre71 от Октябрь 15, 2009, 11:31 2) Вот пример. Но поскольку Layouts в QT всегда криво работали, то до конца правильно сделать можно только если их переписать. :( Наблюдается небольшое увеличение левой панели(QT баг). Причина ошибки становиться понятной при включеном "Fixed" Вот сделал затычку, но заметьте это извращение: Код
Название: Re: [Лэйауты] Хочется странного Отправлено: CroCIV от Октябрь 15, 2009, 12:29 Да этот вариант тоже не фонтан :)))
вот еще один костыль в голову пришел, и вроде как работает, правда код выглядит немного невменяемо )) но зато косяков пока не вижу ::) Название: Re: [Лэйауты] Хочется странного Отправлено: spectre71 от Октябрь 15, 2009, 12:54 Да этот вариант тоже не фонтан :))) Вроде работает. вот еще один костыль в голову пришел, и вроде как работает, правда код выглядит немного невменяемо )) но зато косяков пока не вижу ::) Я со сплитером не пробовал. Название: Re: [Лэйауты] Хочется странного Отправлено: SLiDER от Октябрь 15, 2009, 21:29 Да этот вариант тоже не фонтан :))) вот еще один костыль в голову пришел, и вроде как работает, правда код выглядит немного невменяемо )) но зато косяков пока не вижу ::) Тут тоже интересный спецэффект, до первого нажатия кнопки окно легким движением руки схлопывается в ноль :) |