1

私のアプリケーションを古い GUI (固定サイズを使用していた場所) から wxWidgets (サイザーの基礎を学ぼうとしている場所) に移動しています。

アプリケーション内には、非常に複雑な構造を持つフォームがいくつかあります。データとワークフローの性質から、これらすべてのデータを 1 つの画面にまとめることが推奨されます。しかし、この画面は使いやすいように適切に設計する必要があります。

これが旧バージョンのフォームです...

固定レイアウトのフォーム

...そして、これが多かれ少なかれ、サイザーを使用して思いつくことができるものです...

wxSizers を使用したフォーム

wxGridSizer を単純に使用することはできないことに注意してください。一部のウィジェットは行全体にまたがり、他のウィジェットは固定グリッドの外に出てしまうなどです。

明らかに、見苦しさを軽減するために作業を続けることができましたが、サイザーはそれを行うための正しいツールではないのではないかと考えていました. 私が望むものを達成するには、ある種の colspan/rowspan メカニズムを備えた wxGridSizer に似たものが必要ですが、それでは十分ではないかもしれません。

そこで、次のような「フォームサイザー」を自分で作ろうと考え始めました。

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;

など(これは単なるスクラッチです。大まかなアイデアとして考えてください。すべてを小さすぎてウィジェットのテキストに収まらないようにしたり、それに応じてフォントサイズを拡大縮小したりすることを避けるためのメカニズムが必要です)。

それは合理的に思えますか?あなたはその話題にどのように向き合いますか?この選択は、私の将来の開発にかなり影響するので、どんな回答、批判、コメントも大歓迎です。

4

2 に答える 2

1

wxGridSizerあなたのニーズを満たさないかもしれませんが、あなたがwxGridBagSizer望むことをするべきなどのより柔軟なクラスです。wxGBSpanこのクラスを呼び出すと、アイテムが複数の行と列にまたがるように設定できますwxGridBagSizer::Add

于 2014-11-18T15:05:54.390 に答える
1

@sjdowling の回答で述べたように、使用できますwxGridBagSizer。ただし、絶対配置の問題があるため、このクラスの使用はお勧めしません。特に、要素を移動したり、最後以外で要素を追加したりすることが非常に困難になります。

wxWidgets のサイザーには、さまざまなサイズの要素を整列させる機能がないのは事実です。これは、通常のボックスまたはグリッドのサイザーを使用している場合に必要になるものであり、これは面倒です。ただし、列のサイズを明示的に修正することで、列のサイズを明示的に修正することで回避できます (特に高 DPI の状況では、壊れたレイアウトを避けるために、少なくともピクセルではなくダイアログ単位を使用してください)。ラベルと呼び出しGetTextExtent()それらすべてで最も長いものを選択します(これは、特に文字列の幅をピクセル単位で大幅に変更できる翻訳を使用する場合に、はるかに信頼性が高くなります)。次に、作成するラベルにこの幅を割り当てるだけです。最初の幅は最小幅でもあるため、すべてのラベルがこの幅になり、サイザーが異なっていても整列されます。

私が書いたように、これはやや面倒ですが、コードでレイアウトを作成している場合はそれほど悪くはありません。GUI デザイナでこれを行うとさらに見にくくなりますが、それでもwxSizer::SetItemMinSize()コードから呼び出すことができます。もちろん、唯一の本当の解決策は、サイザー間アライメントのサポートを追加することですが、今のところ、これはwxGridBagSizerIMO を使用するよりも望ましい方法です。

于 2014-11-18T18:17:36.067 に答える