安排wxpython窗口从其内容明智地继承其大小

时间:2012-07-27 18:32:30

标签: wxpython

我已经编写了我的第一个wxpython应用程序并且工作正常,但我遇到了困难,正确调整了主窗口的大小。该面板包含wx.BoxSizer,而wx.FlexGridSizer又包含wx.TextCtrl,而TextCtrl又包含6个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))

我读过的教程似乎专注于手动设置尺寸。我真正想做的是让{{1}}得出它应该是什么大小来包含来自给定字体的3个字符(比如“WWW”),反过来,它应该自动确定大小FlexGridSizer和主窗口。我不需要担心调整布局的大小(所以Sizer可能不是必需的吗?),我只是希望自动确定大小,而不是将魔法常量放入程序中。

{{1}}

1 个答案:

答案 0 :(得分:4)

您需要执行两个步骤来解决问题。

第一步是计算字符串的宽度(以“WWW”为例)。请看this SO question about computing string widhs in pixels using wxpython。获得宽度和高度后,您可以设置wx.TextCtrl尺寸。

第二步是设置wx.Frame大小。我想开始说,在wxpython术语中,任何可以出现在屏幕上的对象称为窗口,大多数用户称之为窗口(即MS Windows中具有最小化/最大化/关闭按钮的东西)称为帧。我知道,它会让人感到困惑。

因此,您希望使用内容的大小自动设置帧的大小。简单!您想使用Fit()方法(documentation)。您也可以使用SetSizerAndFit()方法(documentation),但这只是一种同时调用SetSizer()Fit()的便捷方法。 Fit()方法查看对象内容的大小,并相应地调整对象的大小。不幸的是,在你的特定代码中并不那么简单。

在您的代码中,您有MyFormwx.Frame个实例),其中包含wx.Panel,其中包含您的sizer和wx.TextCtrl s。不幸的是,这会导致根据内容计算MyForm大小的问题,因此调用Fit()只会将其设置为默认大小。原因是wx.Frame根据其大小调整器(由SetSizer()指定)计算其大小,而当前MyForm没有大小调整器,因此无法根据内容计算大小您的wx.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)


2。将panel放在另一个sizer内,并在SetSizerAndFit()

上拨打MyForm

看起来像这样:

def init_UI(self):

    [...]

    panel.SetSizer(hbox)

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


最后,我想提供一个快速解释,为什么教程倾向于使用那些“魔术数字”。 UI设计很难,有时你需要完美的像素。如果您正在开发一个应用程序,以便在具有不同设置和屏幕分辨率甚至不同操作系统的不同计算机上使用,确保一致显示所有内容,则需要明确设置字体和大小等内容,而不是依赖于系统默认值。当你进步并开始制作更复杂的wxpython应用程序时,你会遇到问题,有时候对象的大小没有正确计算,并且使用我告诉你使用的方法仍会使你的窗口太大/太小。请记住这一点。