Хороший ли способ определения размера формы?

Я перемещаю мое приложение из старого графического интерфейса (где я использовал фиксированные размеры) в wxWidgets (где я пытаюсь изучить основы размеров).

Внутри приложения у меня есть несколько форм с довольно сложной структурой. Характер данных и рабочий процесс позволяют мне хранить все эти данные вместе на одном экране.
Но этот экран должен быть правильно спроектирован, чтобы его можно было использовать.

Вот старая версия формы …

форма с исправлением макета

… и вот более или менее то, что я мог бы придумать, используя классификаторы …

Форма с wxSizers

Обратите внимание, что я не мог просто использовать wxGridSizer, так как некоторые виджеты охватывают всю строку, другие выходят из фиксированной сетки и т. Д.

Очевидно, что я мог бы продолжать работать над этим, чтобы сделать его менее уродливым, но я подумал, что, может быть, калибры не являются подходящим инструментом для этого. Чтобы добиться того, чего я хочу, мне нужно что-то похожее на wxGridSizer с каким-то механизмом colspan / rowspan, и, возможно, этого будет недостаточно.

Поэтому я начал думать о том, чтобы создать «Form Sizer» сам, который мог бы пойти что-то вроде

int w,h;
GetClientSize(&w,&h);
MyFormSizer *formSizer(w,h);
formSizer->SetDimension( widget1, 100, 20 );
formSizer->SetDimension( widget2, 500, 20 );
formSizer->newRow();
formSizer->SetDimension( widget3, 100, 20 );
formSizer->SetDimension( widget4, 250, 20 );
formSizer->SetDimension( widget5, 250, 20 );
formSizer->Layout();

Пользователь устанавливает относительные размеры каждого виджета, чтобы полностью заблокировать геометрию формы. Чтобы эта геометрия соответствовала wxPanel при изменении размера Layout() рассчитал бы соответствующий коэффициент масштабирования f а затем установил бы все размеры и позиции, делая что-то вроде

widget1->SetSize(CalculatedX, CalculatedY, 100/f, 20/f);
CalculatedX+=100/f;
widget2->SetSize(CalculatedX, CalculatedY, 500/f, 20/f);
CalculatedX+=0;
CalculatedY+=20/f;

и так далее (это всего лишь скретч, воспринимайте это как грубую идею; должны быть механизмы, позволяющие избежать слишком маленького размера, чтобы вместить текст в виджетах и ​​/ или соответственно масштабировать размер шрифта и тому подобное).

Это кажется разумным? Как бы вы столкнулись с темой? Этот выбор сильно повлияет на мое будущее развитие, поэтому любые ответы, критика и комментарии будут приветствоваться.

1

Решение

wxGridSizer может не соответствовать вашим потребностям, но более гибкие классы, такие как wxGridBagSizer должен делать то, что вы хотите. Этот класс позволяет вам устанавливать элементы на несколько строк и столбцов, устанавливая wxGBSpan при звонке wxGridBagSizer::Add,

1

Другие решения

Как уже упоминалось в ответе @ sjdowling, вы можете использовать wxGridBagSizer, Однако я не рекомендую использовать этот класс, поскольку он страдает от некоторых проблем абсолютного позиционирования, в частности, он очень затрудняет перемещение элементов вокруг него или добавление их, кроме как в самом конце.

Это правда, что у sx-виджетов wxWidgets нет возможности выравнивать элементы по разным размерам, а это то, что вам нужно здесь, если вы используете обычные боксы или сетку, и это раздражает. Однако вы можете обойти эту проблему, установив размеры столбцов в явном виде, либо просто жестко закодировав их (пожалуйста, используйте хотя бы диалоговые единицы, а не пиксели, хотя во избежание неправильной разметки, особенно в ситуациях с высоким DPI), или итерируя по всем ярлыки и звонки GetTextExtent() на всех из них и выбирая самый длинный (это гораздо надежнее, особенно при использовании переводов, которые могут резко изменить ширину строки в пикселях). Затем просто назначьте эту ширину для создаваемых вами меток: поскольку начальная ширина также является минимальной шириной, это обеспечит, что все они имеют эту ширину и выровнены, даже если они имеют разные размеры.

Как я уже писал, это несколько раздражает, но на самом деле не так уж и плохо, если вы создаете макет в коде. Если вы делаете это в дизайнере графического интерфейса, это еще хуже, но вы все равно можете позвонить wxSizer::SetItemMinSize() из кода. Конечно, единственным реальным решением было бы добавить поддержку выравнивания между размерами, но пока это все еще предпочтительнее использования wxGridBagSizer ИМО.

1

По вопросам рекламы [email protected]