2012-11-01 67 views
1

基於用戶交互,我想動態地添加和刪除wxPython筆記本中的面板控件。我最徹底嘗試的方法是在面板的sizer上調用.Clear()並添加所有新控件。但是,在Windows 7和Linux桌面上,渲染工件和陳舊控件在新內容下仍然可見。我怎樣才能完全刪除舊的控件,並添加新的控件沒有這些工件?如何在wxPython的筆記本頁面中添加和刪除控件?

下面是轉載的Windows 7注StaticPanelDynamicPanel兩種不同.update()方法問題的一個範例程序:

#!/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。請注意,當您調整窗口大小或在點擊幾次按鈕後將鼠標懸停在第二個面板上時,會出現重疊控件和其他工件。

以下是顯示堆疊控件的截圖。兩個圖像都是在相同數量的按鈕點擊之後拍攝的,它們只顯示處於相同狀態的兩個不同的面板。我期望的文字是完全一樣的。

panel 1 (<code>.SetText()</code>) panel 2 (<code>TextCtrl</code> replaced)

回答

2

只需清除篩分器將只刪除其內容,而不是小部件引用。當您創建一個小部件時,它將在您提供的父窗口中註冊。請看下面的代碼:

class Frame(wx.Frame): 
    def __init__(self): 
     wx.Frame.__init__(self,None) 
     self.textCtrl = wx.TextCtrl(self) # create with Frame as parent 
     self.textCtrl = None # has no effect on the TextCtrl 

父窗口(框架在這個例子中)將採取TextCtrl的所有權,即使你把它設置爲無,框架將保持它活着,直到它被摧毀。要刪除TextCtrl,你必須明確地摧毀它:

self.textCtrl.Destroy() 

如果你想刪除同時在所有子控件,您可以使用:

self.DestroyChildren() 
+0

這正是我一直在尋找的答案。謝謝! –

相關問題