3

いくつかの長い説明があり、それぞれにラジオ ボタンの回答を含む短い質問が続くダイアログを作成しようとしています。GridBagSizer( wxWidgets docs , wxPython docs )を使用してコントロールを配置しています。ここでは、長い説明が 3 つの列すべてにまたがり、質問と 2 つのラジオ ボタンの回答がそれぞれ独自の列に表示されます。

ここに画像の説明を入力

回答を右揃えにしたいので、レイアウトに質問をflag=wx.EXPAND追加する際にパスしてみました。StaticTextただし、これは望ましい効果がないようです。最初の列は、使用可能なスペースを埋めてラジオ ボタンを右に押すのではなく、最も長い質問に適合するのに十分な大きさのままです。

import wx

class MyDialog(wx.Dialog):
    def __init__(self, *args, **kwargs):
        wx.Dialog.__init__(self, *args, **kwargs)

        sizer = wx.GridBagSizer(5, 5)
        sizer.SetEmptyCellSize((0,0))
        sizer.AddGrowableCol(0)

        for i in range(5):
            description = wx.StaticText(self, -1, "This is a long description \
that may span several lines. Filler filler filler filler filler. More filler \
filler filler filler filler.")
            description.Wrap(500)

            question = wx.StaticText(self, -1, "Are you sure?")
            yes = wx.RadioButton(self, -1, "Yes", style = wx.RB_GROUP)
            no = wx.RadioButton(self, -1, "No")

            sizer.Add(description, (i*3, 0), (1, 3))
            sizer.Add(question, (i*3+1, 0), flag=wx.EXPAND)
            sizer.Add(yes, (i*3+1, 1))
            sizer.Add(no, (i*3+1, 2))

        self.SetSizerAndFit(sizer)
        self.Show()


app = wx.App(False)
dialog = MyDialog(None)
app.MainLoop()

また、余分なスペーサー列を追加して設定しようとしましwx.EXPANDたが、それも役に立ちません。ラジオボタンの設定も試してみましwx.ALIGN_RIGHTたが、予想通り、「いいえ」ボタンが右に配置されます.3番目の列が残りのスペースを占有しているためです.

ここで何か不足していますか?使用可能なスペースを埋めるために 1 つの列をGridBagSizer展開することはできませんか、それとも間違っていますか? 私が間違っている場合、それはどこかに文書化されていますか? 適切なドキュメントへの参照が役立ちます。

4

2 に答える 2

2

ギャップを埋めるために wx.Sizer.AddStretchSpacer() を使用して問題を解決しようとしました。http://wxpython.org/docs/api/wx.Sizer-class.html#AddStretchSpacer

動作するようになりましたが、wx.GridBagSizers で StretchSpacers が奇妙に動作するようです

sizer.Add(description, (i*3, 0), (1, 3))
sizer.Add(question, (i*3+1, 0), flag=wx.EXPAND)
sizer.AddStretchSpacer((i*3+1,1))
sizer.Add(yes, (i*3+1, 2), flag=wx.ALIGN_RIGHT)
sizer.Add(no, (i*3+1, 3))

はいボタンを右に揃える必要があることに注意してください。これがなぜなのかわかりません。ストレッチ スペーサーを挿入する列に関係なく、[はい] ボタンを右に揃える必要がありました (スペーサーが列 0 に挿入された場合でも!)。また、[いいえ] ボタンが少し右に表示されすぎています。コードがこのように動作する理由がわかりません。すべてが少しハックに見えるため、このソリューションを使用しないことを強くお勧めします。

ただし、ストレッチ スペーサーを使用すると、ウィンドウの幅に相対的な幅を持つ wx.BoxSizers を作成できます。これにより、ボタンを並べることができます (幅がすべて同じで、ストレッチ スペーサーがボタンを右側に押しているため)。したがって、@Mike Discollが簡単に提案したように、wx.BoxSizersを使用するようにコードをリファクタリングしました

class MyDialog(wx.Dialog):
    def __init__(self, *args, **kwargs):
        wx.Dialog.__init__(self, *args, **kwargs)

        sizer = wx.BoxSizer(wx.VERTICAL)

        for i in range(5):
            description = wx.StaticText(self, -1, "This is a long description \
that may span several lines. Filler filler filler filler filler. More filler \
filler filler filler filler.")
            description.Wrap(500)

            questionSizer = wx.BoxSizer(wx.HORIZONTAL)
            question = wx.StaticText(self, -1, "Are you sure?")
            yes = wx.RadioButton(self, -1, "Yes", style = wx.RB_GROUP)
            no = wx.RadioButton(self, -1, "No")

            sizer.Add(description)
            questionSizer.Add(question)
            questionSizer.AddStretchSpacer()
            questionSizer.Add(yes)
            questionSizer.Add(no)
            sizer.Add(questionSizer, flag=wx.EXPAND)

        self.SetSizerAndFit(sizer)
        self.Show()

あなたが見つけると思うものは、まさにあなたが望んでいた結果をあなたに与えるでしょう:

ストレッチ スペーサーと wx.BoxSizer

wx.EXPAND フラグを指定して questionSizer を追加する必要があることに注意してください。これは、ストレッチ スペーサーが未使用領域を埋めるために拡張されるためです。wx.EXPAND なしで sizer.Add() を呼び出すと、幅はデフォルトでテキストとボタンの長さに設定されます (つまり、ストレッチ スペーサーを埋めるための余分なスペースはありません)。wx.Expand を使用すると、幅が sizer の幅に設定されます (説明により、約 500 ピクセルになることがわかっています)。

境界線をいじって、アイテム間の間隔を好きなようにすることができます。

- -編集 - -

説明テキストを非常に短い文字列 (500 ピクセル未満) に変更して実験を試みましたが、self.SetSizerAndFit() 呼び出しの呼び出しにより、結果のウィンドウは非常に小さく、視覚的に不快です:

最小サイズのない小さな説明

サイザーのサイズを明示的に設定して、一貫した最小幅を確保する方が良いと思います。

[...]
width = 500 #the desired minimum width
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.SetMinSize((width,1)) #ensures sizer will be minimum width
"""NOTE: the minimum size gets recalculated when new items are added.
i.e. if height exceeds 1 pixel or if width exceeds wdith, the sizer
will recalculate the minimum size"""


for i in range(5):
    description = wx.StaticText(self, -1, "Short Description") #description is less than 500 pixels, Wrap() will have no effect.
    description.Wrap(width)
[...]

これにより、次のようになります。

最小サイズの小さな説明

于 2012-05-23T01:01:25.803 に答える
1

問題の一部は、SetSizerAndFit() を使用していることです。SetSizer() だけを使用してみてください。それは大いに役立ちます。個人的には、ウィジェットの外観をよりきめ細かく制御できるため、BoxSizers をネストすることを好みます。

于 2012-05-22T21:37:53.110 に答える