Question

I am working with python v2.7 and wxPython v3.0 on Windows 7 OS. In my application I have a panel named as myPanel. I have a image as a background on myPanel the image names is green.bmp The myPanel contains a button named as myButton. This myButton also contains an image as a background named as blue.bmp The thread simply changes the image on myButton.

For the demo purpose I am using the same image again and again on myButton. In my real world problem I have different images.

Problem: After executing my application, when I see the memory consumption in the task manager I observed that the memory consumption keeps increasing. What is wrong with my code below that causes unnecessary memory consumption? How can I avoid this?

Code: The images used in the code can be downloaded from here Green.bmp and Blue.bmp. The code snippet is provided below:

import wx
from wx.lib.pubsub import setupkwargs
from wx.lib.pubsub import pub
from threading import Thread
import threading
import time

class gui(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, None, id, title, size=(500,400))
        myPanel = wx.Panel(self, -1, size=(300,200))
        image_file1 = 'green.bmp'
        image1 = wx.Image(image_file1, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
        self.bitmap2 = wx.StaticBitmap(myPanel, -1, image1, (0, 0))
        pub.subscribe(self.addImage, 'Update')

    def addImage(self):
        myButton = wx.Button(self.bitmap2, -1, size =(30,30), pos=(20,20))
        image_file2 = 'blue.bmp'
        image2 = wx.Image(image_file2, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
        self.bitmap1 = wx.StaticBitmap(myButton, -1, image2, (0, 0))

class myThread(Thread):
    def __init__(self):
        Thread.__init__(self)
        self.start()
    def run(self):
        while True:
            time.sleep(2)
            wx.CallAfter(pub.sendMessage, 'Update')

if __name__=='__main__':
    app = wx.App()
    frame = gui(parent=None, id=-1, title="Test")
    frame.Show()
    myThread()
    app.MainLoop()

Thanks for your time.

Était-ce utile?

La solution

Your problem is in addImage. Each time this line executes:

myButton = wx.Button(self.bitmap2, -1, size =(30,30), pos=(20,20))

You are adding another child window to self.bitmap2. The window perfectly overlaps the previous one added, so it is not apparent that you have multiple children. To see what is happening, add this line to the bottom of addImage:

print len(self.bitmap2.GetChildren())

To fix this problem you should destroy all the children before you add the new button. Add this to the top of addImage

self.bitmap2.DestroyChildren()

However, this approach destroys ALL windows you have added to bitmap2, so tread lightly. If you want to only destroy the button, you should keep a reference to it. I've modified your program to use this approach:

import wx
from wx.lib.pubsub import setupkwargs
from wx.lib.pubsub import pub
from threading import Thread
import threading
import time

class gui(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, None, id, title, size=(500,400))
        myPanel = wx.Panel(self, -1, size=(300,200))
        image1 = wx.Image('green.bmp', wx.BITMAP_TYPE_ANY).ConvertToBitmap()
        self.bitmap2 = wx.StaticBitmap(myPanel, -1, image1, (0, 0))
        pub.subscribe(self.addImage, 'Update')
        self.myButton = None

    def addImage(self):
        # Don't keep adding children to bitmap2
        if self.myButton:
            self.myButton.Destroy()
        self.myButton = wx.Button(self.bitmap2, -1, size =(30,30), pos=(20,20))
        image2 = wx.Image('blue.bmp', wx.BITMAP_TYPE_ANY).ConvertToBitmap()
        self.bitmap1 = wx.StaticBitmap(self.myButton, -1, image2, (0, 0))


class myThread(Thread):
    def __init__(self):
        Thread.__init__(self)
        self.start()
    def run(self):
        while True:
            time.sleep(2)
            wx.CallAfter(pub.sendMessage, 'Update')

if __name__=='__main__':
    app = wx.App()
    frame = gui(parent=None, id=-1, title="Test")
    frame.Show()
    myThread()
    app.MainLoop()
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top