wxPython:wx.PyControl是否可以包含一个wx.Sizer?

问题描述:

Can a wx.PyControl can contain a wx.SizerwxPython:wx.PyControl是否可以包含一个wx.Sizer?

请注意,我最终试图在这里做什么(微调浮动值)已经在另一个问题中回答。我特别感兴趣的是在wx.PyControl内部布置小部件,如果我遇到需要制作自己的自定义小部件的技巧,这项技巧可能会很有用。我已经阅读了CreatingCustomControls,但它没有在wx.PyControl子类中使用sizer。我的CustomWidget只是看起来不正确。我还没有执行DoGetBestSize,因为我认为这适用于wx.Sizer代理上的小部件。我实际上有一个wx.Sizer做它的东西里面 a CustomWidget

这里是我的代码(无子部件之间的事件绑定):
编辑:这里是我纠正类代码,这要归功于Steven Sproat

import wx 

class CustomWidget(wx.PyControl): 
    def __init__(self, parent): 
    wx.PyControl.__init__(self, parent=parent, style=wx.NO_BORDER) # Style added. 
    text = wx.TextCtrl(parent=self) 
    spin = wx.SpinButton(parent=self, style=wx.SP_VERTICAL) 
    sizer = wx.GridBagSizer() 
    self.layout(text, spin, sizer) 
    self.OnInit(text, sizer) 

    def OnInit(self, text, sizer): 
    text.SetValue(u"0.000") 

    def layout(self, text, spin, sizer): 
    self.SetSizer(sizer) 
    sizer.Add(text, pos=(0, 0), flag=wx.ALIGN_CENTER) 
    sizer.Add(spin, pos=(0, 1), flag=wx.ALIGN_CENTER) 
    self.Fit() 
    self.Layout() # This is what I lacked. I needed to call .Layout() 
    self.CenterOnParent() 

是的,可以。你只需要调用Layout()来告诉sizer重新计算/布局它的孩子。

import wx 

class Frame(wx.Frame): 
    def __init__(self): 
    wx.Frame.__init__(self, None) 
    blah = CustomWidget(self) 
    self.Show(True) 

class CustomWidget(wx.PyControl): 
    def __init__(self, parent): 
    wx.PyControl.__init__(self, parent=parent) 
    text = wx.TextCtrl(parent=self) 
    spin = wx.SpinButton(parent=self, style=wx.SP_VERTICAL) 
    sizer = wx.GridBagSizer() 
    self.layout(text, spin, sizer) 
    self.OnInit(text, sizer) 

    def OnInit(self, text, sizer): 
    text.SetValue(u"0.000") 

    def layout(self, text, spin, sizer): 
    self.SetSizer(sizer) 
    sizer.Add(text, pos=(0, 0), flag=wx.ALIGN_CENTER) 
    sizer.Add(spin, pos=(0, 1), flag=wx.ALIGN_CENTER) 
    self.Fit() 
    self.Layout() 
    self.CenterOnParent() 

app = wx.App() 
f = Frame() 
app.MainLoop() 

顺便说一句,这将是未来很好,如果你可以附加一个可运行的样品如上:)

+0

这很棒!并感谢关于可运行示例的社区小贴士。我下次会这样做:)我也编辑了我的问题以包含您的解决方案。 – Kit 2010-07-18 01:14:19

+0

我对这个做了一些更多的实验,但是我认为当'CustomWidget'是'wx.Panel'的子元素而不是'wx.Frame'时,它会崩溃。你的想法? – Kit 2010-07-22 00:59:00

+0

你是否按照罗宾的建议尝试? – 2010-07-22 10:26:19

因为从wxControl派生类通常不用于含有其他部件的自动布局代码不存在,因此它在获取EVT_SIZE事件时不会调用Layout()。您可以通过绑定()为EVT_SIZE处理程序并从那里调用self.Layout()来轻松地将该能力添加到您的类中。然后它就像一个面板在获得大小事件时所做的一样,并且具有子级和sizer。