thanks Cody,
but it think it's somewhat more complex ...
Cody Precord wrote:
Hello,
hello,
I've a fairly large program,
that uses a lot of icon sized images.
So I use the following construct:
- all images are placed in one subdirectory
- on start of the program, I read all images, scale them and place then in a global Global_ImageList (with a trick to maintain the order).
- now when I need icons, e.g. for treectrl, notebook, or whatever, I use AssignImageList ( Global_ImageList )
until now it seemed to work ok,
but ...
in the following case it goes wrong:
- the program starts with a tree and I assign the Global_ImageList to it.
- dynamically I create a notebook (on another form) and assign the same Global_ImageList to it
- now I dynamically destroy the form with the notebook
and then my Global_ImageList seems to be destroyed too.
Why ?
Isn't this a allowed / good method of handling many imagelists ?
The effect is that my main program's tree doesn't have an imagelist anymore,
tries to refresh and crashes.
I believe that when you assign an image list to a window it take ownership of the memory for that object (remember this is c++ code down below). So when it is destroyed it deletes its members during cleanup, leaving your reference as a pointer to a deleted object.
The same affect can be seen in reverse if you create an image list, assign it to a window, then let it go out of scope. When python cleans up the image list you created it will create a bad reference that when the window tries to access now deleted object will cause a crash.
i.e
def __init__()
imglst = wx.ImageList(...)
imgst.Add(...)
tree = wx.TreeCtrl(...)
tree.SetImageList(imglst)
When this method goes out of scope python will cleanup the imglst variable which will cause the list to be deleted so when the TreeCtrl tries to access it it has a pointer to a null object which will cause a crash. Thats why you need to keep reference to it by assigning it to an attribute of the class 'self.imglst' so that it doesn't get deleted until the object it belongs to does.
So if you are using ImageList you will need to make copies for each window that uses it before using SetImageList and keep reference to that copy within the object itself.
I create the ImageList in the main form created first and which remains the whole session
self.Image_List = Get_Image_List ()
but the program still crashes if another form with a notebook (assigned to the same global image list) closes.
I also tried copy.copy but doesn't have any positive effect.
I also tried copy.deepcopy, but that produces a huge error message
Traceback (most recent call last):
File "D:\Data_Python_25\PyLab_Works\control_output_viewer.py", line 312, in __init__
self.image_list = copy.deepcopy ( Get_Image_List () )
File "P:\Python\lib\copy.py", line 189, in deepcopy
y = _reconstruct(x, rv, 1, memo)
File "P:\Python\lib\copy.py", line 337, in _reconstruct
state = deepcopy(state, memo)
File "P:\Python\lib\copy.py", line 162, in deepcopy
y = copier(x, memo)
File "P:\Python\lib\copy.py", line 254, in _deepcopy_dict
y[deepcopy(key, memo)] = deepcopy(value, memo)
File "P:\Python\lib\copy.py", line 189, in deepcopy
y = _reconstruct(x, rv, 1, memo)
File "P:\Python\lib\copy.py", line 322, in _reconstruct
y = callable(*args)
File "P:\Python\Lib\copy_reg.py", line 92, in __newobj__
return cls.__new__(cls, *args)
TypeError: object.__new__(PySwigObject) is not safe, use PySwigObject.__new__()
So for the moment I just create a new imagelist every time I need one.
Will think about another/better solution.
cheers,
Stef
···
On Dec 20, 2008, at 2:39 PM, Stef Mientki wrote: