【问题标题】:wxPython: Can a wx.PyControl contain a wx.Sizer?wxPython:一个 wx.PyControl 可以包含一个 wx.Sizer 吗?
【发布时间】:2011-03-17 08:16:07
【问题描述】:

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

请注意,我最终在这里尝试做的事情(带有浮点值的微调器)已经在另一个问题中得到解答。我对在wx.PyControl 中布局小部件特别感兴趣,如果我遇到需要制作自己的自定义小部件时,这项技能可能会很有用。我已经阅读了CreatingCustomControls,但它没有在wx.PyControl 子类中使用sizer。

使用下面的代码,我的CustomWidget 看起来不正确。我还没有做DoGetBestSize,因为我认为这适用于wx.Sizer 作用于 小部件。我实际上有一个 wx.Sizerinside 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()

【问题讨论】:

    标签: python wxpython custom-controls widget sizer


    【解决方案1】:

    是的,可以。你只需要调用 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()
    

    顺便说一句,如果你能像上面那样附上一个可运行的样本,那就太好了:)

    【讨论】:

    • 这太棒了!感谢社区提供有关可运行示例的提示。下次我会这样做 :) 我还编辑了我的问题以包含您的解决方案。
    • 我用这个做了更多的实验,但我认为当CustomWidgetwx.Panel 的子代而不是wx.Frame 时它会崩溃。你的想法?
    • 您按照 Robin 的建议尝试了吗?
    • 是的,我也试过了。我写了一个new question here
    【解决方案2】:

    由于从 wxControl 派生的类通常不用于包含其他小部件,因此不存在自动布局代码,因此它在收到 EVT_SIZE 事件时不会调用 Layout()。您可以通过 Bind() 处理 EVT_SIZE 的处理程序并从那里调用 self.Layout() 轻松地将这种能力添加到您的类中。然后它会像面板一样在获得 size 事件并具有子和 sizer 时执行操作。

    【讨论】:

      猜你喜欢
      • 2021-11-20
      • 2011-01-10
      • 1970-01-01
      • 1970-01-01
      • 2018-06-17
      • 2012-07-25
      • 2014-04-21
      • 2012-10-01
      • 2011-03-31
      相关资源
      最近更新 更多