[Python-bugs-list] [ python-Bugs-632323 ] Tkinter: BitmapImage vanishes if not stored in non-local var

noreply@sourceforge.net noreply@sourceforge.net
Tue, 05 Nov 2002 14:13:44 -0800


Bugs item #632323, was opened at 2002-11-01 23:39
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=632323&group_id=5470

Category: Tkinter
Group: Python 2.2.2
Status: Closed
Resolution: Invalid
Priority: 5
Submitted By: L. Peter Deutsch (lpd)
Assigned to: Nobody/Anonymous (nobody)
Summary: Tkinter: BitmapImage vanishes if not stored in non-local var

Initial Comment:
The following program incorrectly produces a blank canvas:

#!/usr/bin/env python

from Tkinter import *

class Me(Canvas):

    def init1(self):
        return BitmapImage(foreground = '#ff0000',
                           background = '#00ff00',
                           data = """\
#define t_width 8
#define t_height 8
static unsigned char t_bits[] = {
   0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3c, 0x3c};
""",

                           maskdata = """\
#define t_width 8
#define t_height 8
static unsigned char t_bits[] = {
   0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x3c, 0x18};
""")

    def init2(self, image):
        self.create_image(32, 32, anchor = NW, image =
image)

self = Me()
self.pack(expand = 1, fill = BOTH)
self.init2(self.init1())
#img = self.init1()
#self.init2(img)
self.mainloop()

----------------

However, the following program correctly draws a small
red-and-green icon:

#!/usr/bin/env python

from Tkinter import *

class Me(Canvas):

    def init1(self):
        return BitmapImage(foreground = '#ff0000',
                           background = '#00ff00',
                           data = """\
#define t_width 8
#define t_height 8
static unsigned char t_bits[] = {
   0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3c, 0x3c};
""",

                           maskdata = """\
#define t_width 8
#define t_height 8
static unsigned char t_bits[] = {
   0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x3c, 0x18};
""")

    def init2(self, image):
        self.create_image(32, 32, anchor = NW, image =
image)

self = Me()
self.pack(expand = 1, fill = BOTH)
#self.init2(self.init1())
img = self.init1()
self.init2(img)
self.mainloop()

----------------

The two programs are identical except that one of them
assigns the BitmapImage to a variable rather than
passing it directly as an argument.

Python 2.2.1, OS = Linux version 2.4.18-3
(bhcompile@daffy.perf.redhat.com) (gcc version 2.96
20000731 (Red Hat Linux 7.3 2.96-110)) #1 Thu Apr 18
07:37:53 EDT 2002


----------------------------------------------------------------------

>Comment By: Martin v. L÷wis (loewis)
Date: 2002-11-05 23:13

Message:
Logged In: YES 
user_id=21627

Mentioning "the docs" is somewhat funny when it comes to
Tkinter: there was no documentation on images in the first
place. I've added a new section on this in tkinter.tex 1.17.

I've also added a Tk wishlist item at

http://sourceforge.net/tracker/?func=detail&aid=633300&group_id=12997&atid=362997

If they ever act on this, we can improve Tkinter in this
respect.

----------------------------------------------------------------------

Comment By: Guido van Rossum (gvanrossum)
Date: 2002-11-05 22:23

Message:
Logged In: YES 
user_id=6380

Let's close this as Not A Bug.

Maybe it needs to be fixed in the docs?

----------------------------------------------------------------------

Comment By: Martin v. L÷wis (loewis)
Date: 2002-11-04 08:26

Message:
Logged In: YES 
user_id=21627

When the BitmapImage object is no longer referenced, it is
finalized; finalization causes "image delete" to be invoked.

Tcl does not keep a reference to the image object; if you
don't yourself, nobody does. In turn, the image object goes
away right after being created.

The right approach would be for Tcl to somehow keep a
reference to the Python object, but I think this is
unimplementable.

----------------------------------------------------------------------

Comment By: L. Peter Deutsch (lpd)
Date: 2002-11-03 20:42

Message:
Logged In: YES 
user_id=8861

The bug does *not* manifest with the following definition
for init():

    def init(self):
        self.img = self.init1()
        self.init2(self.img)

I think this is even stronger evidence that we're seeing a
reference counting / garbage collection / finalization (?)
problem.


----------------------------------------------------------------------

Comment By: Internet Discovery (idiscovery)
Date: 2002-11-03 06:14

Message:
Logged In: YES 
user_id=33229

This may be the same as what I'm seeing in Demo/tix/tixwidgets.py
Look for image1 in tixwidgets.py: I put the following comment in the code:

    # This image is not showing up under Python unless it is set to a
    # global variable - no problem under Tcl. I assume it is being garbage
    # collected some how, even though the tcl command 'image names' shows
    # that as far as Tcl is concerned, the image exists and is called pyimage1.

Can anyone explain to me what's going on? IMHO, either this is a Tkinter bug, 
or a documentation bug because the documentation does not explain to me why
this image1 has to be global, or am I missing something here.


----------------------------------------------------------------------

Comment By: L. Peter Deutsch (lpd)
Date: 2002-11-02 05:32

Message:
Logged In: YES 
user_id=8861

Comment #1: This bug is still there in Python 2.2.2.

Comment #2: Using a variable isn't the whole story. The bug
also manifests if I define:

    def init(self):
        img = self.init1()
        self.init2(img)

and then have the calling program invoke self.init().


----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=632323&group_id=5470