У меня проблемы с размерами в Qt. Я создаю свои собственные виджеты и использую разные макеты (как правило, мне нужны свои собственные, чтобы они работали должным образом, не тратя часы на «мощные» макеты по умолчанию ... которые не выкладывают вещи как задумано.)
Как только я закончу с виджетом и его макетом, он не будет работать правильно. Размер никогда не будет установлен должным образом, если только я не вызову widget->resize(1, 1);
, который, наконец, вызывает «изменение размера» и заставляет виджет выглядеть корректно (то есть пересчитывать геометрию.) Даже вызов updateGeometry()
не имеет никакого эффекта.
Это ужасная проблема, когда resize()
нужно вызывать в родительском виджете (чёрт!) И из того, что я читаю, не должно быть необходимости, если макеты правильно запрограммированы.
Есть ли пример, который работает и не имеет нескольких тысяч строк, или Qt требует нескольких тысяч строк, чтобы все работало идеально, даже самый простой виджет?
Какие минимальные функции нужно вызывать для одновременной работы виджета и его макета?
Спасибо.
Alexis
P.S. Я пытался реализовать sizeHint()
, minimumSize()
, maximumSize()
, другие, которые мне не хватает? Я надеялся, что этого будет достаточно. Очевидно, я также реализую setGeometry()
на макете, чтобы соответствующим образом изменить размер дочерних элементов.
--- сложение 1
Существует пример изображения с макетом, который явно недоступен, как в Qt. Расположение, функции и цвета различных клавиш основаны на XML и подходят для любой клавиатуры в мире.
(обратите внимание, что в этом примере не отображается клавиша Enter, отображаемая в двух строках и шире внизу, чем в верхней части; более или менее, ее невозможно выполнить с обычными макетами; конечно, она работает с моей версией.)
--- уточнение
Я не слишком уверен, как лучше описать проблему. Я подумал написать тестовый виджет рядом, чтобы увидеть, как я могу воспроизвести проблему, а затем опубликовать ее и в конечном итоге исправить. 8 -)
Функция разметки по умолчанию, которую используют внутренние разметки Qt, требует большого количества кодирования. Я хотел бы избежать копирования / вставки всего этого, потому что для обслуживания это делает его почти невозможным.
--- сегодняшние выводы
Поскольку мне нужно было настроить один из виджетов, я решил добавить VBoxLayout
и заставить его работать.
Я действительно обнаружил проблему ... Один из виджетов в моем дереве - QScrollArea
, и sizeHint()
возвращает (-1, -1). Не совсем то, что я ожидал, но ... что бы вы ни поместили в этот виджет, он лучше знает, как вычислить его ширину и высоту, иначе ... это не удастся.
Если присмотреться к коду, я мог бы вычислить ширину, используя самую широкую найденную ширину. Как только я это использую, виджет появится (и он на самом деле изменяет свой размер, когда все меняется в списке, круто).
Это, как говорится, мой предыдущий комментарий о наличии дерева виджетов, которые автоматически изменяют размер самих себя. От корня до родителей листьев в вашем дереве, все эти виджеты будут нуждаться в правильном макете. После того, как я добавил один в верхнем виджете, он изменил размеры себя и своих детей должным образом (ну ... в моем случае до QScrollArea
, остальным требовалось изменение размера снизу вверх. Забавно, как это работает!)
--- ах! ха! момент (или: что вы найдете, читая код реализации!)
Сегодня я столкнулся с другой проблемой, которая просто нуждалась в правильном вызове ... Я просто не мог найти ничего стоящего в документации.
Все объекты теперь имеют макет, но определенный родительский объект не будет правильно изменять размер. Простой простой.
Мне позвонили родители следующим образом:
// changes to the children are changing the geometry
parentWidget()->updateGeometry();
Да. Документы говорят, что это то, что вы должны сделать. С этим звонком ничего не происходит. Понятия не имею, что он должен делать, я не смотрел на эту функцию. В любом случае, для меня это ничего не сделало.
Итак ... Я посмотрел на макет, чтобы понять, как он будет отправлять информацию вверх / вниз.Я не видел много, кроме одного интересного комментария:
// will trigger resize
Это сказано о режиме SetFixedSize
.Для достижения этой функции вам нужно сделать макет для обновления.Ах!Да ... макет, а не родительский виджет ... попробуем вместо этого:
parentWidget()->layout()->update();
И вуаля!Он правильно изменяет размеры во всех случаях, которые у меня есть.Совершенно невероятно, что виджет updateGeometry()
не вызывает такой же эффект ...