下面您将看到示例代码,其中包含针对我的问题的解决方法。 我将自己的面板作为子项添加到ScrolledPanel。
wx.Frame
|-wx.ScrolledPanel
|-wx.Panel
|-wx.Choice wx.TextCtrl
|-wx.Panel
|-wx.Choice wx.TextCtrl
|-wx.Panel
|-...
将焦点设置到ScrolledPanel中的最后一个子节点时,我想将其带到视图中。但是将我的包含子项的面板作为ScrolledPanel的子项使用,这不能自动调用SetFocus()。在这种情况下永远不会调用ScrolledPanel.OnChildFocus()。所以我必须调用ScrolledPanel.ScrollChildIntoView()explicite作为解决方法。
当使用非面板子项(可能是wx.Button)时,在子项上调用SetFocus()时,这会自动与ScrolledPanel一起工作。
如果没有解决方法,如何解决这个问题?也许我应该报告它背后的(设计)错误?
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import wx
import wx.lib.scrolledpanel
class MyPanel(wx.Panel):
def __init__(self, parent):
super(wx.Panel, self).__init__(parent)
sizer = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(wx.Choice(self, choices=['a', 'b']))
sizer.Add(wx.TextCtrl(self, value=str(id(self))))
self.SetSizer(sizer)
class MyFrame(wx.Frame):
def __init__(self):
super(wx.Frame, self).__init__(None)
sizer = wx.BoxSizer(wx.VERTICAL)
bt = wx.Button(self, label='Test Add')
bt.Bind(wx.EVT_BUTTON, self._OnAdd)
sizer.Add(bt)
self.panel = wx.lib.scrolledpanel.ScrolledPanel(self, style=wx.TAB_TRAVERSAL)
self.panelsizer = wx.BoxSizer(wx.VERTICAL)
i = 0
while i < 20:
self.panelsizer.Add(MyPanel(self.panel))
i += 1
self.panel.SetSizer(self.panelsizer)
self.panel.SetupScrolling()
sizer.Add(self.panel, proportion=1, flag=wx.EXPAND)
self.SetSizer(sizer)
def _OnAdd(self, event):
focus = MyPanel(self.panel)
self.panelsizer.Add(focus)
self.Layout()
# this alone doesn't work
focus.SetFocus()
# this is the workaround
self.panel.ScrollChildIntoView(focus)
if __name__ == '__main__':
app = wx.App()
win = MyFrame()
win.Show()
app.MainLoop()