【发布时间】:2016-12-09 04:49:01
【问题描述】:
以下程序存在内存泄漏(我在 linux 系统上使用top 命令验证了这一点)
import wx
from random import randint
class MyPanel(wx.Panel):
def __init__(self,parent):
wx.Panel.__init__(self,parent)
self._parent = parent
self._nb_buttons = 0
self._main_sizer = wx.BoxSizer(wx.VERTICAL)
self._ctrl_sizer = wx.BoxSizer(wx.HORIZONTAL)
self._btns_sizer = wx.BoxSizer(wx.VERTICAL)
self._btn_tim = wx.Button(self,label="Start auto")
self._btn_tim.Bind(wx.EVT_BUTTON, self.OnStartStopEvent)
self._ctrl_sizer.Add(self._btn_tim, 0, wx.CENTER|wx.ALL, 5 )
self._main_sizer.Add(self._ctrl_sizer, 0, wx.CENTER )
self._main_sizer.Add(self._btns_sizer, 0, wx.CENTER|wx.ALL,10)
self.SetSizer(self._main_sizer)
self._timer1 = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.OnTimer, self._timer1)
self._timer_running = False
def OnStartStopEvent(self,event):
if self._timer_running: # toggle state of Timer
self._timer1.Stop()
self._btn_tim.SetLabel("Start")
self._timer_running = False
else:
self._timer1.Start(200,False)
self._btn_tim.SetLabel("Stop")
self._timer_running = True
def AddWidget(self):
self._nb_buttons += 1
label = "Button %d" % self._nb_buttons
name = "button%d" % self._nb_buttons
new_button = wx.Button(self,label=label, name=name)
self._btns_sizer.Add( new_button, 0, wx.ALL, 5 )
self._parent._my_sizer.Layout()
self._parent.Fit()
def RemoveWidget(self):
if self._btns_sizer.GetChildren():
self._btns_sizer.Hide(self._nb_buttons -1 )
self._btns_sizer.Remove(self._nb_buttons -1 )
self._nb_buttons -= 1
self._parent._my_sizer.Layout()
self._parent.Fit()
def OnTimer(self,event):
n = randint(-3,3)
if self._nb_buttons < 2: n += randint(0,2)
if self._nb_buttons > 10: n -= randint(0,3)
while n > 0:
self.AddWidget()
n -= 1
while n < 0:
self.RemoveWidget()
n += 1
class MyFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self,parent=None, title="Add remove buttons")
self._my_sizer = wx.BoxSizer(wx.VERTICAL)
panel1 = MyPanel(self)
self._my_sizer.Add(panel1, 1, wx.EXPAND)
self.SetSizer(self._my_sizer)
self.Fit()
self.Show()
def main():
app = wx.App(False)
frame1 = MyFrame()
app.MainLoop()
if __name__ == '__main__':
main()
问题是在RemoveWidget 中,按钮从Sizer 中删除,而不是从父wx.Panel 中删除。
从父级(在这种情况下为wx.Panel)删除wx.Button 的方法是什么?
当我搜索“删除 wxPython 小部件”时,我找到的答案只告诉了如何从 sizer 中删除。 (实际上,我的代码是 http://www.blog.pythonlibrary.org/2012/05/05/wxpython-adding-and-removing-widgets-dynamically/ 的变体)。
wx.Window 类中有一个 RemoveChild 方法,但文档说它是内部的,不应由用户代码调用 (https://wxpython.org/Phoenix/docs/html/wx.Window.html#wx.Window.RemoveChild)
【问题讨论】: