3

私は最初のwxpythonアプリケーションを作成しましたが、正常に動作しますが、メインウィンドウのサイズを適切に設定するのに問題が発生しました。パネルには、6秒を含むが含まれていwx.BoxSizerます。wx.FlexGridSizerwx.TextCtrl

私が読んだチュートリアルは、手動でサイズを設定することに焦点を当てているようでした。私が本当にやりたいのはTextCtrl、特定のフォント(「WWW」など)から3文字を含めるために、sにサイズを計算させ、FlexGridSizerとメインのサイズを自動的に決定することです。窓。レイアウトのサイズ変更について心配する必要はありません(したがって、Sizerは必要ないのでしょうか?)。プログラムに魔法の定数を入れるのではなく、サイズを自動的に決定したいだけです。

import wx
from names_as_vs import name_sum, name_mult

NAME_SIZE = 35

class MyForm(wx.Frame):
    def __init__(self, parent,title):
        wx.Frame.__init__(self,parent,title=title,size=(405,200))

        self.default_init_UI()
        self.init_UI()
        self.Show()

    def default_init_UI(self):
        """Do all the standard UI stuff"""
        file_menu = wx.Menu()
        menuAbout = file_menu.Append(wx.ID_ABOUT,"About\tCtrl-A")
        menuExit = file_menu.Append(wx.ID_EXIT,"Quit\tCtrl-Q")

        menu_bar = wx.MenuBar()
        menu_bar.Append(file_menu,"File")
        self.SetMenuBar(menu_bar)

        self.Bind(wx.EVT_MENU, self.OnAbout, menuAbout)
        self.Bind(wx.EVT_MENU, self.OnExit, menuExit)

    def init_UI(self):
        """Particular UI setup for this program"""

        hbox = wx.BoxSizer(wx.HORIZONTAL)
        panel = wx.Panel(self)
        fgs = wx.FlexGridSizer(2,5,9,9)

        fixed_elts_args = {"size":(30,70)}
        plus = wx.StaticText(panel, label="+", **fixed_elts_args)
        times = wx.StaticText(panel, label=".",**fixed_elts_args)

        equals1 = wx.Button(panel, label="=", **fixed_elts_args)
        equals2 = wx.Button(panel, label="=", **fixed_elts_args)
        equals1.Bind(wx.EVT_BUTTON, self.compute_sum)
        equals2.Bind(wx.EVT_BUTTON, self.compute_mult)

        font = wx.Font(48,wx.ROMAN,wx.NORMAL,wx.NORMAL)
        text_ctrl_args = {"size":(95,70)}
        self.summand1 = wx.TextCtrl(panel, **text_ctrl_args)
        self.summand2 = wx.TextCtrl(panel, **text_ctrl_args)
        self.scalar = wx.TextCtrl(panel, **text_ctrl_args)
        self.multiplicand = wx.TextCtrl(panel, **text_ctrl_args)
        self.sum_result = wx.TextCtrl(panel, style = wx.TE_READONLY, **text_ctrl_args)
        self.mult_result = wx.TextCtrl(panel, style = wx.TE_READONLY,     **text_ctrl_args)

        for ctrl in (plus,times,equals1,equals2,self.summand1,self.summand2,
                     self.scalar,self.multiplicand,self.sum_result,self.mult_result):
            ctrl.SetFont(font)

        fgs.AddMany([ 
            self.summand1,plus,self.summand2,equals1,self.sum_result,
            self.scalar,times,self.multiplicand,equals2,self.mult_result
            ])

        hbox.Add(fgs, proportion=1, flag= wx.ALL, border=15)
        panel.SetSizer(hbox)

    def OnAbout(self,e):
        dlg = wx.MessageDialog(self, "A GUI implementation of 815 as a vector space",     "About 815 as a vector space", wx.OK)
        dlg.ShowModal() # Shows it
        dlg.Destroy() # finally destroy it when finished.

    def OnExit(self,e):
        self.Close(True)  # Close the frame.

    def compute_sum(self,e):
        """Computes the sum of the names in summand1 and summand2 and displays the result in self.sum_result"""
        n1 = self.summand1.GetValue()
        n2 = self.summand2.GetValue()
        self.sum_result.SetValue(name_sum(n1,n2))

    def compute_mult(self,e):
        """
        Computes the scalar multiple of the name in multiplicand by the scalar in scalar and displays the result in self.mult_result
        """
        n = self.multiplicand.GetValue()
        lamb = self.scalar.GetValue()
        self.mult_result.SetValue(name_mult(lamb,n))
4

1 に答える 1

5

問題を解決するために実装する必要がある2つのステップがあります。

最初のステップは、文字列の幅を計算することです(例として「WWW」を指定します)。wxpythonを使用したピクセル単位の文字列widhの計算に関するこのSOの質問をご覧ください。幅と高さが決まったら、wx.TextCtrlサイズを設定できます。

2番目のステップはwx.Frameサイズを設定することです。wxpythonの用語では、画面に表示できるオブジェクトはウィンドウと呼ばれ、ほとんどのユーザーがウィンドウと呼ぶもの(つまり、MS Windowsの最小化/最大化/閉じるボタンを持つもの)はフレームと呼ばれます。それは混乱する可能性があります、私は知っています。

そのため、コンテンツのサイズを使用してフレームのサイズを自動的に設定する必要があります。簡単!Fit()メソッド(ドキュメント)を使用します。SetSizerAndFit()メソッド(ドキュメント)を使用することもできますが、これは両方SetSizer()Fit()同時に呼び出す便利なメソッドです。このFit()メソッドは、オブジェクトのコンテンツのサイズを調べ、それに応じてそのオブジェクトのサイズを決定します。残念ながら、特定のコードではそれほど単純ではありません。

コードには、サイザーとsを含むを含むMyFormwx.Frameインスタンス)があります。残念ながら、これにより、コンテンツに基づいてのサイズを計算する際に問題が発生するため、呼び出すとデフォルトのサイズに設定されます。その理由は、sは(によって割り当てられた)サイザーに基づいてサイズを計算し、currentにはサイザーがないため、の内容に基づいてサイズを計算できないためです。幸い、この問題には2つの解決策があり、どちらも非常に簡単です。wx.Panelwx.TextCtrlMyFormFit()wx.FrameSetSizer()MyFormwx.Panel

1.すべてを削除panelして直接の子として設定し、MyForm次に呼び出しますSetSizerAndFit()

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

def init_UI(self):

    [...]

    #note that the parent is now "self" and not "panel"
    self.multiplicand = wx.TextCtrl(self, **text_ctrl_args)
    self.sum_result = wx.TextCtrl(self, style = wx.TE_READONLY, **text_ctrl_args)
    self.mult_result = wx.TextCtrl(self, style = wx.TE_READONLY,     **text_ctrl_args)

    [...]

    self.SetSizerAndFit(hbox)


panel2.別のサイザーの中に置きSetSizerAndFit()MyForm

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

def init_UI(self):

    [...]

    panel.SetSizer(hbox)

    sizer = wx.BoxSizer(wx.Horizontal)
    sizer.Add(panel)
    self.SetSizerAndFit(sizer) 


最後に、チュートリアルでこれらの「マジックナンバー」を使用する傾向がある理由について簡単に説明します。UIデザインは難しく、ピクセル単位で完璧にする必要がある場合もあります。さまざまな設定や画面解像度、さらにはさまざまなOSを備えたさまざまなコンピューターで使用するアプリを開発している場合、すべてが一貫して表示されるようにするには、システムのデフォルトに依存せずに、フォントやサイズなどを明示的に設定する必要があります。進行してより複雑なwxpythonアプリケーションの作成を開始すると、オブジェクトのサイズが適切に計算されないことがあり、使用するように指示したメソッドを使用すると、ウィンドウが大きすぎたり小さすぎたりするという問題が発生します。これを念頭に置いて前進してください。

于 2012-07-28T04:24:19.890 に答える