wxPython:wx.Panel下 wx.PyControl 布局问题

0 投票
1 回答
1190 浏览
提问于 2025-04-16 01:41

这是对之前一个问题的延续:
wxPython: wx.PyControl能包含wx.Sizer吗?

这里主要讨论的是在一个 wx.PyControl 里面使用 wx.Sizer。我在让我的 CustomWidget 自适应它的子控件时遇到了问题。这个问题通过在 Fit() 之后调用 Layout() 来解决。

不过,根据我的经验,这个解决方案只在 CustomWidgetwx.Frame 的直接子控件时有效。当它成为 wx.Panel 的子控件时,就会出现问题。

编辑:使用下面的代码时,CustomWidget 没有正确调整大小以适应它的子控件。我观察到这种情况只发生在 CustomWidget(作为 wx.PyControl 的子类)是 wx.Panel 的子控件时;如果它是 wx.Frame 的直接子控件,则 Fit() 是完全正常的。

以下是代码:

import wx

class Frame(wx.Frame):
  def __init__(self):
    wx.Frame.__init__(self, parent=None)
    panel = Panel(parent=self)
    custom = CustomWidget(parent=panel)
    self.Show()

class Panel(wx.Panel):
  def __init__(self, parent):
    wx.Panel.__init__(self, parent=parent)
    self.SetSize(parent.GetClientSize())

class CustomWidget(wx.PyControl):
  def __init__(self, parent):
    wx.PyControl.__init__(self, parent=parent)

    # Create the sizer and make it work for the CustomWidget        
    sizer = wx.GridBagSizer()
    self.SetSizer(sizer)

    # Create the CustomWidget's children
    text = wx.TextCtrl(parent=self)
    spin = wx.SpinButton(parent=self, style=wx.SP_VERTICAL)

    # Add the children to the sizer        
    sizer.Add(text, pos=(0, 0), flag=wx.ALIGN_CENTER)
    sizer.Add(spin, pos=(0, 1), flag=wx.ALIGN_CENTER)

    # Make sure that CustomWidget will auto-Layout() upon resize
    self.Bind(wx.EVT_SIZE, self.OnSize)
    self.Fit()

  def OnSize(self, event):
    self.Layout()

app = wx.App(False)
frame = Frame()
app.MainLoop()

1 个回答

1

.SetSizerAndFit(sizer) 这个方法可以完成你想要的功能。我不太明白为什么先用 .SetSizer(sizer) 再用 .Fit() 就不行。有没有人知道原因呢?

import wx

class Frame(wx.Frame):
  def __init__(self):
    wx.Frame.__init__(self, parent=None)
    panel = Panel(parent=self)
    custom = CustomWidget(parent=panel)
    self.Show()

class Panel(wx.Panel):
  def __init__(self, parent):
    wx.Panel.__init__(self, parent=parent)
    self.SetSize(parent.GetClientSize())

class CustomWidget(wx.PyControl):
  def __init__(self, parent):
    wx.PyControl.__init__(self, parent=parent)

    # Create the sizer and make it work for the CustomWidget        
    sizer = wx.GridBagSizer()
    self.SetSizer(sizer)

    # Create the CustomWidget's children
    text = wx.TextCtrl(parent=self)
    spin = wx.SpinButton(parent=self, style=wx.SP_VERTICAL)

    # Add the children to the sizer        
    sizer.Add(text, pos=(0, 0), flag=wx.ALIGN_CENTER)
    sizer.Add(spin, pos=(0, 1), flag=wx.ALIGN_CENTER)

    # Set sizer and fit, then layout
    self.SetSizerAndFit(sizer)
    self.Layout()

  # ------------------------------------------------------------
  #  # Make sure that CustomWidget will auto-Layout() upon resize
  #  self.Bind(wx.EVT_SIZE, self.OnSize)
  #  self.Fit()
  #  
  #def OnSize(self, event):
  #  self.Layout()
  # ------------------------------------------------------------    

app = wx.App(False)
frame = Frame()
app.MainLoop()

撰写回答