wxPython: wx.PyControl可以包含wx.Sizer吗?

2 投票
2 回答
505 浏览
提问于 2025-04-16 01:26

一个 wx.PyControl 可以包含一个 wx.Sizer 吗?

我想要做的事情(带有浮点值的旋转器)在另一个问题中已经有答案了。我特别想了解如何在 wx.PyControl 中布局小部件,这项技能可能在我需要制作自定义小部件时会很有用。我已经看过了 创建自定义控件,但里面没有使用 wx.PyControl 子类中的 sizer。

根据我下面的代码,我的 CustomWidget 看起来就是不对劲。我还没有做 DoGetBestSize,因为我觉得这个方法是针对一个 wx.Sizer 对小部件进行操作的。我实际上是在一个 CustomWidget 内部让 wx.Sizer 自己运作。

以下是我的代码(没有子小部件之间的事件绑定):
编辑:这是我修正后的类代码,感谢 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()

2 个回答

1

因为从wxControl派生出来的类通常不用于包含其他小部件,所以它们没有自动布局的代码。因此,当接收到EVT_SIZE事件时,它们不会调用Layout()。你可以通过绑定一个处理函数来轻松地为你的类添加这个功能,当接收到EVT_SIZE事件时,从这个处理函数里调用self.Layout()。这样一来,它就会像面板一样,在接收到大小变化的事件时,能够处理它的子控件和布局。

3

是的,可以做到。你只需要调用 Layout() 方法,这样就可以告诉布局管理器重新计算和安排它的子元素。

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()

顺便说一下,如果将来能附上一个可以运行的示例,那就更好了 :)

撰写回答