ユーザーの操作に基づいて、wxPythonノートブックのパネルにコントロールを動的に追加および削除したいと思います。私が最も徹底的に試したアプローチは.Clear()
、パネルのサイザーを呼び出して、すべての新しいコントロールを追加することです。ただし、Windows 7デスクトップとLinuxデスクトップの両方で、レンダリングアーティファクトと古いコントロールは新しいコンテンツの下に表示されたままになります。古いコントロールを完全に削除し、これらのアーティファクトなしで新しいコントロールを追加するにはどうすればよいですか?
以下は、Windows 7で問題を再現するサンプルプログラムです。との2つの異なる.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()
[更新]ボタンをクリックして、2つのパネルのテキストを更新します。最初のパネルは、を使用してテキストコントロールを更新し、2番目のパネルはを新しいものに.SetText()
置き換えます。TextCtrl
ボタンを数回クリックした後、ウィンドウのサイズを変更するか、2番目のパネルの上にマウスを置くと、重複するコントロールやその他のアーティファクトがあることに注意してください。
これは、スタックされたコントロールを示すスクリーンショットです。両方の画像は、同じボタンクリック数の後に撮影されたもので、同じ状態の2つの異なるパネルを示しています。私はテキストがまったく同じであることを期待していました。