我正在尝试实现一个面板子类,如果内容溢出其垂直边界,它将自动插入垂直滚动条。我希望面板在每个方面都像普通面板一样完全但只有一个:它不是面板的最小高度是其尺寸的最小高度,而是应该具有静态值(如200) ,当面板的高度低于其尺寸的高度时,应出现垂直滚动条。换句话说,当面板的高度高于>大小的最小高度时,它的功能应该与普通面板完全相同。
我遇到的问题是,面板上的DoGetBestSize
和GetMinSize
等覆盖函数无效,因为这些函数从未被调用(我通过插入断点来检查)。我猜测面板的父母正在直接与面板的sizer进行通信,在这种情况下,这是一个从面板外部设置的普通box sizer。
class ScrolledPanel(wx.Panel):
"""A panel that will automatically add scrollbars when needed."""
def __init__(self, parent):
wx.Panel.__init__(self, parent, -1)
self.SetBackgroundColour('#FF0000')
# This function is never called.
def DoGetBestSize(self):
"""Override the minimum size of the panel."""
default = self.GetSizer().GetMinSize()
default.SetHeight(250)
return default
有可能达到我追求的效果吗?如果是这样,我该如何规避上述问题?
Here is the code in which I'm trying to use the scrolled panel
我以为我会尝试覆盖SetSizer
功能,将该sizer作为人质并就尺寸进行咨询,但实际上并未在面板上设置sizer。这样就可以调用DoGetBestSize
之类的自定义大小函数。但它失败了。即使没有设置sizer,仍然不会调用这些函数。我已经尝试了Panel
和PyPanel
。这是我当前的滚动面板:
class ScrolledPanel(wx.PyPanel):
"""A panel that will automatically add scrollbars when needed."""
def __init__(self, parent):
wx.Panel.__init__(self, parent, -1)
self.SetBackgroundColour('#FF0000')
# This function is called.
def SetSizer(self, sizer):
import pdb; pdb.set_trace()
self._pet_sizer = sizer
# The below functions are never called.
def DoGetBestSize(self):
"""Override the minimum size of the panel."""
import pdb; pdb.set_trace()
default = self.GetSizer().GetMinSize()
default.SetHeight(250)
return default
def DoGetClientSize(self):
import pdb; pdb.set_trace()
def DoGetSize(self):
import pdb; pdb.set_trace()
def DoGetVirtualSize(self):
import pdb; pdb.set_trace()
答案 0 :(得分:2)
wxPython中的覆盖方法目前需要使用基类,这些基类旨在将对C ++虚拟的一些调用反映到Python中的重写方法。这意味着如果你想捕获面板中的那些,你需要从wx.PyPanel而不是wx.Panel派生你的类。见http://wiki.wxpython.org/OverridingMethods
答案 1 :(得分:0)
你为什么要重新发明轮子? wxPython提供了一个ScrolledPanel小部件: wx.lib.scrolledpanel
你应该使用它。 wxPython演示有一个例子。
编辑:这是一个示例脚本,在sizer中有一个scrolledPanel。
import wx
import wx.lib.scrolledpanel as scrolled
########################################################################
class MyScrolledPanel(scrolled.ScrolledPanel):
""""""
#----------------------------------------------------------------------
def __init__(self, parent):
"""Constructor"""
scrolled.ScrolledPanel.__init__(self, parent)
########################################################################
class MainPanel(wx.Panel):
""""""
#----------------------------------------------------------------------
def __init__(self, parent):
"""Constructor"""
wx.Panel.__init__(self, parent)
text = "one two buckle my shoe three four shut the door five six pick up sticks seven eight lay them straight nine ten big fat hen"
mainSizer = wx.BoxSizer(wx.VERTICAL)
sizer = wx.BoxSizer(wx.VERTICAL)
sPanel = MyScrolledPanel(self)
words = text.split()
for word in words:
hSizer = wx.BoxSizer(wx.HORIZONTAL)
label = wx.StaticText(sPanel, -1, word+":")
tc = wx.TextCtrl(sPanel, -1, word, size=(50,-1))
hSizer.Add(label, flag=wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL | wx.LEFT, border=10)
hSizer.Add(tc, flag=wx.LEFT, border=10)
sizer.Add(hSizer)
sPanel.SetSizer(sizer)
sPanel.SetAutoLayout(1)
sPanel.SetupScrolling()
mainSizer.Add(sPanel, 1, wx.EXPAND)
self.SetSizer(mainSizer)
########################################################################
class MainFrame(wx.Frame):
""""""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
wx.Frame.__init__(self, None)
panel = MainPanel(self)
if __name__ == "__main__":
app = wx.App(False)
frame = MainFrame()
frame.Show()
app.MainLoop()
答案 2 :(得分:0)
你不需要做任何特别的事情。如果您在任何SetVirtualSize()
上致电wxWindow
,包括wxPanel
,它就会根据需要显示滚动条,并且大小调整器将使用虚拟大小来布置此窗口内容。