Что заставляет виджет Qt и его макет вести себя правильно (в отношении его размера)? - PullRequest
5 голосов
/ 25 августа 2011

У меня проблемы с размерами в Qt. Я создаю свои собственные виджеты и использую разные макеты (как правило, мне нужны свои собственные, чтобы они работали должным образом, не тратя часы на «мощные» макеты по умолчанию ... которые не выкладывают вещи как задумано.)

Как только я закончу с виджетом и его макетом, он не будет работать правильно. Размер никогда не будет установлен должным образом, если только я не вызову widget->resize(1, 1);, который, наконец, вызывает «изменение размера» и заставляет виджет выглядеть корректно (то есть пересчитывать геометрию.) Даже вызов updateGeometry() не имеет никакого эффекта.

Это ужасная проблема, когда resize() нужно вызывать в родительском виджете (чёрт!) И из того, что я читаю, не должно быть необходимости, если макеты правильно запрограммированы.

Есть ли пример, который работает и не имеет нескольких тысяч строк, или Qt требует нескольких тысяч строк, чтобы все работало идеально, даже самый простой виджет?

Какие минимальные функции нужно вызывать для одновременной работы виджета и его макета?

Спасибо. Alexis

P.S. Я пытался реализовать sizeHint(), minimumSize(), maximumSize(), другие, которые мне не хватает? Я надеялся, что этого будет достаточно. Очевидно, я также реализую setGeometry() на макете, чтобы соответствующим образом изменить размер дочерних элементов.

--- сложение 1

Существует пример изображения с макетом, который явно недоступен, как в Qt. Расположение, функции и цвета различных клавиш основаны на XML и подходят для любой клавиатуры в мире.

On screen keyboard

(обратите внимание, что в этом примере не отображается клавиша 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() не вызывает такой же эффект ...

Ответы [ 2 ]

2 голосов
/ 09 сентября 2011

Хотя можно делать то, что вы хотите, это звучит как проблемы, которые у вас возникают, потому что вы используете Qt способом, который не предназначен для использования. Зачем вам нужны отдельные виджеты для каждой клавиши, представленной на клавиатуре?

Я вижу два варианта, оба из которых лучше в некотором роде:

  1. Использование QGraphicsScene и QGraphicsView .
  2. Единственный пользовательский виджет, который использует собственный рисунок для отображения клавиатуры (и, вероятно, использует подсказки для наведения).

Первый вариант, вероятно, лучше. Ваши ключи могут быть представлены QGraphicsSimpleTextItem или даже QGraphicsSvgItem . Он также предоставляет ряд стандартных макетов или вы можете написать свой собственный макет . По умолчанию вы можете использовать keyPressEvent или mouseReleaseEvent для ответа на действия пользователя.

Я настоятельно рекомендую вам взглянуть на QGraphicsView примеров , чтобы получить представление о том, что вы можете сделать.

Если вы идете по второму маршруту, вам нужно записать различные ключевые местоположения, чтобы вы могли реагировать соответствующим образом, когда пользователь перемещает мышь, щелкает и т. Д.

1 голос
/ 25 августа 2011

Это не поможет вам в вашей немедленной проблеме, но я хотел показать вам клавиатуру, которую я сделал, используя стандартные раскладки и кнопки. Он не идеален и все равно не поможет вам с клавишей ввода, которая охватывает два ряда, но это не плохо. Это также можно изменить, изменив размер окна, хотя я не уверен, будет ли это видно из изображений ниже, так как они могут масштабировать их. (вы можете просмотреть реальные изображения, открыв их на собственной вкладке)

enter image description here

enter image description here

В любом случае, это было сделано с использованием только Qt Designer без ручного кодирования. Он состоит из вертикального макета верхнего уровня с 5 горизонтальными макетами в нем. Затем кнопки вставляются в один из 5 горизонтальных макетов. Размером клавиш можно управлять, установив горизонтальные и вертикальные политики размера «игнорироваться» для большинства кнопок, а затем горизонтальный «минимум» для кнопок, которые вы хотите расширить. Все можно настроить, установив минимальные и максимальные ограничения размера для кнопок. При изменении размера кнопки не будут сохранять свои относительные пропорции, хотя это, вероятно, потребует некоторого пользовательского программирования.

Стили в вашем примере могут быть аппроксимированы с использованием таблиц стилей CSS и фоновых изображений. Тем не менее, это не легкое усилие, но вы сможете пройти большую часть пути без пользовательских макетов и кнопок.

...