基于用户交互,我想在 wxPython 笔记本的面板中动态添加和删除控件。我尝试过的最彻底的方法是调用.Clear()
面板的 sizer 并添加所有新控件。但是,在 Windows 7 和 Linux 桌面上,渲染工件和过时的控件在新内容下仍然可见。如何在没有这些工件的情况下完全删除旧控件并添加新控件?
下面是在 Windows 7 上重现该问题的示例程序。请注意 和 的两种不同.update()
方法:StaticPanel
DynamicPanel
#!/usr/bin/python
import wx
import sys
class StaticPane(wx.Panel):
"""A panel that contains simple text that is updated
when the .update() method is called. The text is updated
using .SetText(), and the text control sticks around
between calls to .update()."""
def __init__(self, *args, **kwargs):
super(StaticPane, self).__init__(*args, **kwargs)
self._sizer = wx.BoxSizer(wx.VERTICAL)
self.SetSizer(self._sizer)
self._counter = 0
self._base_text = "Some Text"
self._text = wx.TextCtrl(self, -1,
self._base_text + "!" * self._counter,
style=wx.TE_READONLY)
self._sizer.Add(self._text, -1, wx.EXPAND)
def update(self):
self._counter += 1
self._text.SetValue(self._base_text + "!" * self._counter)
class DynamicPane(wx.Panel):
"""A panel that contains simple text that is updated
when the .update() method is called. The text is updated
by removing the existing text control, and adding a new one
with the updated text string."""
def __init__(self, *args, **kwargs):
super(DynamicPane, self).__init__(*args, **kwargs)
self._sizer = wx.BoxSizer(wx.VERTICAL)
self.SetSizer(self._sizer)
self._counter = 0
self._base_text = "Some Text"
self._text = wx.TextCtrl(self, -1,
self._base_text + "!" * self._counter,
style=wx.TE_READONLY)
self._sizer.Add(self._text, -1, wx.EXPAND)
def update(self):
self._counter += 1
self._sizer.Clear()
self._text = wx.TextCtrl(self, -1,
self._base_text + "!" * self._counter,
style=wx.TE_READONLY)
self._sizer.Add(self._text, -1, wx.EXPAND)
self.Layout()
class TestViewer(wx.Frame):
"""A Frame with a button and a notebook. When the button is pressed,
each of the two pages in the notebook recieve a call to .update().
"""
def __init__(self, parent):
super(TestViewer, self).__init__(parent, -1, "Test Viewer")
self.Bind(wx.EVT_CLOSE, self.OnClose)
self._panel = wx.Panel(self)
vbox = wx.BoxSizer(wx.VERTICAL)
self._panel.SetSizer(vbox)
update_button = wx.Button(self._panel, wx.ID_CLOSE, "Update")
update_button.Bind(wx.EVT_BUTTON, self.update)
vbox.Add(update_button, 0, wx.EXPAND)
self._nb = wx.Notebook(self._panel)
self._view_one = StaticPane(self._nb, -1)
self._view_two = DynamicPane(self._nb, -1)
self._nb.AddPage(self._view_one, "One")
self._nb.AddPage(self._view_two, "Two")
vbox.Add(self._nb, 1, wx.EXPAND | wx.ALL)
self.Layout()
def update(self, e):
self._view_one.update()
self._view_two.update()
def OnClose(self, event):
sys.exit(0)
if __name__ == "__main__":
app = wx.App(False)
frame = TestViewer(None)
frame.Show()
app.MainLoop()
单击“更新”按钮更新两个面板中的文本。第一个面板使用 更新文本控件.SetText()
,而第二个面板将 替换TextCtrl
为新的。请注意,在单击几次按钮后调整窗口大小或将鼠标悬停在第二个面板上时,会出现重叠的控件和其他伪影。
以下是显示堆叠控件的屏幕截图。两张图片都是在点击相同次数的按钮后拍摄的,它们只是显示两个不同的面板处于相同的状态。我希望文本完全一样。