2

我在 Mac OS X 10.6.8、wxPython 2.9.3.1 和 64 位 Python v2.7.2 下运行以下代码:

import wx

class MyFrame(wx.Frame):
    def __init__(self):
        super(MyFrame,self).__init__(None, title="Frame", size=(100, 100))
        self.field = wx.TextCtrl(self, -1, "Text", (30, 7))
    def startLoop(self):
        counter = 0
        while True:
            counter += 1
            self.field.SetValue(str(counter))
            wx.Yield()
class Main(wx.App):
    def __init__(self):
        self.counter = 0
        super(Main,self).__init__(0)

    def OnInit(self):
        self.frame = MyFrame()
        self.frame.Show()
        self.frame.startLoop()
        self.MainLoop()
        return True
Main()

它只会消耗更多的内存。我是在做一些非常错误的事情还是 wxPython 被严重破坏了?最重要的是有一个解决方法,因为我已经编写了一个基于 wxPython 的巨大 GUI。

非常感谢!

wx.StaticText 在上面的代码中泄漏完全相同。

4

3 回答 3

4

Mike 的回答至少部分正确,如果可以的话,避免使用 wx.Yield 总是一个好主意。切换到使用 EVT_IDLE 事件后,仍然存在明显的内存泄漏,尽管它比以前小得多且速度慢得多。切换到 wx.StaticText 而不是 wx.TextCtrl 显示完全没有泄漏,因此似乎确实存在与 wx.TextCtrl.SetValue 相关的问题。请在 trac.wxwidgets.org 上制作一张票,并将组件设置为 wxOSX-cocoa,并包含指向此页面的链接。

import wx

class MyFrame(wx.Frame):
    def __init__(self):
        super(MyFrame,self).__init__(None, title="Frame", size=(100, 100))
        ##self.field = wx.TextCtrl(self, -1, "Text", (30, 7))
        self.field = wx.StaticText(self)

    def startIdle(self):
        self.counter = 0
        self.Bind(wx.EVT_IDLE, self.onIdle)

    def onIdle(self, evt):
        self.counter += 1
        ##self.field.SetValue(str(self.counter))
        self.field.SetLabel(str(self.counter))
        evt.RequestMore()


class Main(wx.App):
    def OnInit(self):
        self.frame = MyFrame()
        self.frame.Show()
        self.frame.startIdle()
        self.MainLoop()
        return True
Main()
于 2012-07-19T16:44:37.340 回答
1

我怀疑您调用 wx.Yield 过于频繁,并且事件正在堆积。我怀疑你的 GUI 也反应灵敏。更好的方法是只使用 wx.Timer 并让它定期更新标签。您必须在 wxPython 邮件列表上询问才能获得真正的技术性答案。

于 2012-07-19T15:48:29.557 回答
1

OSX 具有自动释放池的概念,即许多操作系统“临时”对象仅在通过事件循环迭代后才被清除,您的紧密循环永远不会让操作系统有机会清除任何东西,调用 yield 在这里没有帮助。

The reason for the memory consumption in Robin's idle implementation when using the textctrl is the fact that - as long as the textfield has the focus - it stores everything in its undo-stack, this memory is only reclaimed when the focus changes. I'll see whether I can turn this off automatically.

Thanks for bringing this up.

于 2012-07-20T19:27:44.187 回答