wxPython:wx.PyControl可以包含wx.Sizer吗?
wx.PyControl
可以包含 wx.Sizer
吗?
请注意,我最终想要在这里做的事情(具有浮点值的旋转器)已经在另一个问题中得到了回答。我对在 wx.PyControl
中布局小部件特别感兴趣,如果我需要制作自己的自定义小部件,这项技能可能会很有用。我已经通读了 CreatingCustomControls,但它没有在 wx.PyControl< 中使用 sizer /代码> 子类。
使用下面的代码,我的 CustomWidget
看起来不正确。我还没有做 DoGetBestSize
因为我认为这适用于 作用于小部件的 wx.Sizer
。我实际上有一个wx.Sizer
在内部做它的事情CustomWidget
。
这是我的代码(没有子小部件之间的事件绑定):
编辑:这是我更正后的类代码,感谢史蒂文·斯普罗特:
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()
Can a wx.PyControl
contain a wx.Sizer
?
Note that what I am ultimately trying to do here (spinner with float values) is already answered in another question. I am particularly interested in layouting widgets within a wx.PyControl
, a skill which might prove useful if I come across a need to make my own custom widgets. I already read through CreatingCustomControls, but it didn't use sizers within the wx.PyControl
subclass.
Using my code below, my CustomWidget
just doesn't look right. I'm not yet doing a DoGetBestSize
because I think that applies to a wx.Sizer
acting on a widget. I am actually having a wx.Sizer
doing its thing inside a CustomWidget
.
Here is my code (without the event bindings between sub-widgets):
EDIT: Here is my corrected class code, thanks to 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()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
是的,可以。您只需要调用 Layout() 来告诉 sizer 重新计算/布局其子项。
顺便说一下,如果你能像上面那样附加一个可运行的示例,那就太好了:)
Yes, it can. You just need to call Layout() to tell the sizer to recalculate/layout its children.
By the way, it would be nice in the future if you could attach a runnable sample as above :)
由于从 wxControl 派生的类通常不用于包含其他小部件,因此不存在自动布局代码,因此当它获取 EVT_SIZE 事件时,它不会调用 Layout()。您可以通过 Bind()ing EVT_SIZE 的处理程序并从那里调用 self.Layout() 轻松地将这种功能添加到您的类中。然后,它的行为就像面板在获取大小事件并具有子项和大小调整器时所做的那样。
Since classes derived from wxControl are not normally used for containing other widgets the auto-layout code is not present and so it will not call Layout() when it gets the EVT_SIZE event. You can easily add that ability to your class by Bind()ing a handler for EVT_SIZE and calling self.Layout() from there. Then it will act just like a panel does when it gets the size event and has children and a sizer.