关于wxpython的ScrolledWindow组件在动态添加删除组件时Sizer出现的Layout问题
2012-11-15 23:48
447 查看
最近开发个小应用,出现了如下图一点问题:
这是动态添加组件时发生的
当滚动条拉到底部,点“继续添加”一次,顶部便出现了空白,点第二次时就又恢复了。
滚动条在顶部时则不会有这种情况。
初步判断是在sizer重新Layout计算时将组件移到当前滚动条所在的窗口,使得上面空了出来,查了很多地方,根本找不到根本的解决方案,只好通过模拟两次滚动来解决。
以下是源代码:
这是动态添加组件时发生的
当滚动条拉到底部,点“继续添加”一次,顶部便出现了空白,点第二次时就又恢复了。
滚动条在顶部时则不会有这种情况。
初步判断是在sizer重新Layout计算时将组件移到当前滚动条所在的窗口,使得上面空了出来,查了很多地方,根本找不到根本的解决方案,只好通过模拟两次滚动来解决。
以下是源代码:
class PeopleDialog(wx.Dialog): def __init__(self, parent, readydata): wx.Dialog.__init__ (self, parent, -1, title, size=(480, -1), style=wx.DEFAULT_DIALOG_STYLE|wx.MAXIMIZE_BOX|wx.MINIMIZE_BOX) self.parent = parent self.size = self.GetSize() main_sizer = wx.BoxSizer(wx.VERTICAL) # 添加滚动窗口 self.scrolled_window = wx.ScrolledWindow(self, -1, style=wx.HSCROLL) window = self.scrolled_window window.SetScrollRate(0, 5) self.fg_sizer = wx.FlexGridSizer(0, 3, 0, 0) # 添加控件部分 # 提示 self._addItem(self.fg_sizer, self._staticText(window, '')) prompt = self._staticText(window, u"(加*号为必填项目)") prompt.SetForegroundColour('red') self._addItem(self.fg_sizer, prompt) self._addItem(self.fg_sizer, self._staticText(window, '')) # 姓名 self._addItem(self.fg_sizer, self._staticText(window, u"姓名 *")) self.name = wx.TextCtrl(window, -1, readydata['name'], size=(125, -1)) self._addItem(self.fg_sizer, self.name) self._addItem(self.fg_sizer, self._staticText(window, '')) # 联系方式 self._addItem(self.fg_sizer, self._staticText(window, u"联系方式")) self.contact_textctrl.append(wx.TextCtrl(window, -1, readydata['contact'][0].keys()[0], size=(220, -1))) self._addItem(self.fg_sizer, self.contact_textctrl[0]) items = readydata['contact_type'] self.contact_type_combo.append(wx.ComboBox(window, -1, readydata['contact'][0].values()[0], (-1, -1), (125, -1), items, wx.CB_DROPDOWN|wx.CB_READONLY)) self._addItem(self.fg_sizer, self.contact_type_combo[0]) if readydata['mode'] != 'add': if len(readydata['contact']) > 1: count = 1 for c in readydata['contact'][1:]: self.contact_textctrl.append(wx.TextCtrl(window, -1, readydata['contact'][count].keys()[0], size=(220, -1))) self._addItem(self.fg_sizer, self.contact_textctrl[count]) self.contact_type_combo.append(wx.ComboBox(window, -1, readydata['contact'][count].values()[0], (-1, -1), (125, -1), items, wx.CB_DROPDOWN|wx.CB_READONLY)) self._addItem(self.fg_sizer, self.contact_type_combo[count]) count += 1 self.contact_idx = len(self.fg_sizer.Children) # 继续添加 self._addItem(self.fg_sizer, self._staticText(window, '')) self.btn_add_another_contact = wx.Button(window, -1, u"继续添加") self._addItem(self.fg_sizer, self.btn_add_another_contact) self._addItem(self.fg_sizer, self._staticText(window, '')) self.Bind(wx.EVT_BUTTON, self.addAnotherContact, self.btn_add_another_contact) # 其他控件..... window.SetSizer(self.fg_sizer) window.Layout() self.fg_sizer.Fit(window) main_sizer.Add(window, 1, wx.EXPAND|wx.ALL, 5) # 添加标准对话框按钮 btn_sizer = wx.StdDialogButtonSizer() self.btn_ok = wx.Button(self, wx.ID_OK, u"保存") self.btn_cancel = wx.Button(self, wx.ID_CANCEL, u"退出") btn_sizer.AddButton(self.btn_ok) btn_sizer.AddButton(self.btn_cancel) btn_sizer.Realize() self._addItem(main_sizer, btn_sizer, 0, wx.EXPAND|wx.ALL) self.SetSizer(main_sizer) self.Layout() def _addItem(self, sizer, item, proportion=0, style=wx.ALL, border=5): sizer.Add(item, proportion, style, border) def _insertItem(self, sizer, idx, item, proportion=0, style=wx.ALL, border=5): sizer.Insert(idx, item, proportion, style, border) def _staticText(self, parent, label): return wx.StaticText(parent, -1, label) # 动态添加证件号码 def addAnotherId(self, event): self._insertItem(self.fg_sizer, self.id_idx, self._staticText(self.scrolled_window, '')) self.id_idx += 1 self.id_textctrl.append(wx.TextCtrl(self.scrolled_window, -1, '', size=(220, -1))) self._insertItem(self.fg_sizer, self.id_idx, self.id_textctrl[len(self.id_textctrl) - 1]) self.id_idx += 1 items = self.readydata['id_type'] self.id_type_combo.append(wx.ComboBox(self.scrolled_window, -1, '', (-1, -1), (125, -1), items, wx.CB_DROPDOWN|wx.CB_READONLY)) self._insertItem(self.fg_sizer, self.id_idx, self.id_type_combo[len(self.id_type_combo) - 1]) self.id_idx += 1 self.scrolled_window.SetScrollbars(1, 1, 0, 20) # 页面重新布局 x, y = self.btn_add_another_contact.GetPosition() # 获得按钮位置 self.scrolled_window.Scroll(1, 1) # 手动将页面滚至顶端 self.fg_sizer.Layout() # sizer重新布局 self.scrolled_window.Scroll(x - self.size[0] / 2, y - self.size[1] / 2) # 手动将页面滚动至原位, self.size是整个dialog的大小
相关文章推荐
- Windows Server 2003 添加/删除Windows组件出现错误的问题
- Windows Server 2003 添加/删除Windows组件出现错误的问题
- Windows Server 2003 添加/删除Windows组件出现错误的问题
- Windows Server 2003 添加/删除Windows组件出现错误的问题
- android 动态添加组件出现的一些问题
- Windows Server 2003 添加/删除Windows组件出现错误的问题
- Windows Server 2003 添加/删除Windows组件出现错误的问题
- Windows Server 2003 添加/删除Windows组件出现错误的问题
- Windows Server 2003 添加/删除Windows组件出现错误的问题
- Windows Server 2003 添加/删除Windows组件出现错误的问题
- Windows Server 2003 添加/删除Windows组件出现错误的问题
- Windows Server 2003 添加/删除Windows组件出现错误的问题
- Windows Server 2003 添加/删除Windows组件出现错误的问题
- Windows Server 2003 添加/删除Windows组件出现错误的问题
- Windows Server 2003 添加/删除Windows组件出现错误的问题
- Windows Server 2003 添加/删除Windows组件出现错误的问题
- 关于LinnerLayout动态添加的控件 并且给子控件动态设置Id 、点击的问题
- Windows Server 2003 添加/删除Windows组件出现错误的问题
- Windows Server 2003 添加/删除Windows组件出现错误的问题