Я перемещаю мое приложение из старого графического интерфейса (где я использовал фиксированные размеры) в wxWidgets (где я пытаюсь изучить основы размеров).
Внутри приложения у меня есть несколько форм с довольно сложной структурой. Характер данных и рабочий процесс позволяют мне хранить все эти данные вместе на одном экране.
Но этот экран должен быть правильно спроектирован, чтобы его можно было использовать.
Вот старая версия формы …
… и вот более или менее то, что я мог бы придумать, используя классификаторы …
Обратите внимание, что я не мог просто использовать 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;
и так далее (это всего лишь скретч, воспринимайте это как грубую идею; должны быть механизмы, позволяющие избежать слишком маленького размера, чтобы вместить текст в виджетах и / или соответственно масштабировать размер шрифта и тому подобное).
Это кажется разумным? Как бы вы столкнулись с темой? Этот выбор сильно повлияет на мое будущее развитие, поэтому любые ответы, критика и комментарии будут приветствоваться.
wxGridSizer
может не соответствовать вашим потребностям, но более гибкие классы, такие как wxGridBagSizer
должен делать то, что вы хотите. Этот класс позволяет вам устанавливать элементы на несколько строк и столбцов, устанавливая wxGBSpan
при звонке wxGridBagSizer::Add
,
Как уже упоминалось в ответе @ sjdowling, вы можете использовать wxGridBagSizer
, Однако я не рекомендую использовать этот класс, поскольку он страдает от некоторых проблем абсолютного позиционирования, в частности, он очень затрудняет перемещение элементов вокруг него или добавление их, кроме как в самом конце.
Это правда, что у sx-виджетов wxWidgets нет возможности выравнивать элементы по разным размерам, а это то, что вам нужно здесь, если вы используете обычные боксы или сетку, и это раздражает. Однако вы можете обойти эту проблему, установив размеры столбцов в явном виде, либо просто жестко закодировав их (пожалуйста, используйте хотя бы диалоговые единицы, а не пиксели, хотя во избежание неправильной разметки, особенно в ситуациях с высоким DPI), или итерируя по всем ярлыки и звонки GetTextExtent()
на всех из них и выбирая самый длинный (это гораздо надежнее, особенно при использовании переводов, которые могут резко изменить ширину строки в пикселях). Затем просто назначьте эту ширину для создаваемых вами меток: поскольку начальная ширина также является минимальной шириной, это обеспечит, что все они имеют эту ширину и выровнены, даже если они имеют разные размеры.
Как я уже писал, это несколько раздражает, но на самом деле не так уж и плохо, если вы создаете макет в коде. Если вы делаете это в дизайнере графического интерфейса, это еще хуже, но вы все равно можете позвонить wxSizer::SetItemMinSize()
из кода. Конечно, единственным реальным решением было бы добавить поддержку выравнивания между размерами, но пока это все еще предпочтительнее использования wxGridBagSizer
ИМО.