您的位置:首页 > 编程语言 > Python开发

关于wxpython的ScrolledWindow组件在动态添加删除组件时Sizer出现的Layout问题

2012-11-15 23:48 447 查看
最近开发个小应用,出现了如下图一点问题:



这是动态添加组件时发生的

当滚动条拉到底部,点“继续添加”一次,顶部便出现了空白,点第二次时就又恢复了。

滚动条在顶部时则不会有这种情况。

初步判断是在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的大小
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: