Re: How to know if an object is still be referenced?

2016-03-02 Thread jfong
sohca...@gmail.com at 2016/3/3  UTC+8 7:38:45AM wrote:
> "label" might be a local variable, but it's constructor includes a reference 
> to the frame in which it is going.  The frame object will create a reference 
> to the newly-created Label object.  At that point, there will be two 
> references to the new Label object.  When the function exits and "label" goes 
> out of scope, the object still exists because the frame still has a reference.
> 
It sound reasonable enough:-)

There is a page talking about why should keep a separate reference in tkinter.
http://effbot.org/pyfaq/why-do-my-tkinter-images-not-appear.htm

I also saw almost every code on the web about it was written in this way:
label = Label(playbar_frame, image=photo)
label.image = photo
But why? Won't it be better if it was written as:
label = Label(playbar_frame, image=photo)
label.imgKeeper = photo
At least it makes the meaning more clear, not lead someone to a wrong 
direction:-(

Anyway, following Terry's suggestion might be a better idea, making it bind to 
an object which will live for as long as the application is.

--Jach
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How to know if an object is still be referenced?

2016-03-02 Thread sohcahtoa82
On Wednesday, March 2, 2016 at 3:35:32 AM UTC-8, jf...@ms4.hinet.net wrote:
> Terry Reedy at 2016/3/2  UTC+8 3:04:10PM wrote:
> > On 3/1/2016 9:35 PM, jf...@ms4.hinet.net wrote:
> > > Recently I was puzzled by a tkinter problem. The codes below (from a 
> > > book) can display the picture correctly.
> > >
> > >  gifdir = "../gifs/"
> > >  from tkinter import *
> > >  win = Tk()
> > >  photo = PhotoImage(file=gifdir + "ora-pp.gif")
> > >  Button(win, image=photo).pack()
> > >  win.mainloop()
> > 
> > Since photo is a global name, the binding remain until you explicitly 
> > delete it or exit the app.
> > 
> > > And the codes below (from another book) will also work.
> > >
> > >  class DrumMachine:
> > >  
> > >  
> > >  def create_play_bar(self):
> > >  
> > >  
> > >  photo = PhotoImage(file='images/signature.gif')
> > >  label = Label(playbar_frame, image=photo)
> > >  label.image = photo
> > >  label.grid(row=start_row, column=50, padx=1, sticky='w')
> > >  
> > >  
> > 
> > Here photo is a local name and the binding disappears when the function 
> > exits.  I would rewrite it to follow pattern 1.
> > 
> >   self.photo = PhotoImage(file='images/signature.gif')
> >   label = Label(playbar_frame, image=self.photo)
> > 
> > To me, saving an attribute reference is not worth the extra line.
> > 
> > > In the second example, I noticed that the "photo" was referenced two times
> > > and I think it might be a redundancy so I remove the line "label.image = 
> > > photo". But it fails then.
> > 
> > On another question, I made the same suggestion.  Oops.
> > 
> > -- 
> > Terry Jan Reedy
> 
> Thanks, Terry. After reading your reply I noticed that I had make a mistake. 
> The "image" is not an attribute of the Button. It's an option. The 
> "label.image=photo" does a different thing. But it didn't help on solving my 
> puzzle.
> 
> If the problem was caused by the "photo" is a local, then binding the "photo" 
> to an local attribute ("label" is a local too) seems no meaning at all. But 
> it did make difference! No idea how the underneath mechanism works.
> 
> I run this example under the pdb and it can display the picture correctly 
> even without the "label.image=photo" statement. Why it fails on running at 
> real time? tk event scheduling? I don't know.
> 
> --Jach

"label" might be a local variable, but it's constructor includes a reference to 
the frame in which it is going.  The frame object will create a reference to 
the newly-created Label object.  At that point, there will be two references to 
the new Label object.  When the function exits and "label" goes out of scope, 
the object still exists because the frame still has a reference.

If you're a C/C++ programmer, another way of thinking of it is imagining EVERY 
variable is created on the heap, not the stack, and so it is safe to pass 
around references to "local" variables, even when the function that creates it 
exits.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How to know if an object is still be referenced?

2016-03-02 Thread jfong
Terry Reedy at 2016/3/2  UTC+8 3:04:10PM wrote:
> On 3/1/2016 9:35 PM, jf...@ms4.hinet.net wrote:
> > Recently I was puzzled by a tkinter problem. The codes below (from a book) 
> > can display the picture correctly.
> >
> >  gifdir = "../gifs/"
> >  from tkinter import *
> >  win = Tk()
> >  photo = PhotoImage(file=gifdir + "ora-pp.gif")
> >  Button(win, image=photo).pack()
> >  win.mainloop()
> 
> Since photo is a global name, the binding remain until you explicitly 
> delete it or exit the app.
> 
> > And the codes below (from another book) will also work.
> >
> >  class DrumMachine:
> >  
> >  
> >  def create_play_bar(self):
> >  
> >  
> >  photo = PhotoImage(file='images/signature.gif')
> >  label = Label(playbar_frame, image=photo)
> >  label.image = photo
> >  label.grid(row=start_row, column=50, padx=1, sticky='w')
> >  
> >  
> 
> Here photo is a local name and the binding disappears when the function 
> exits.  I would rewrite it to follow pattern 1.
> 
>   self.photo = PhotoImage(file='images/signature.gif')
>   label = Label(playbar_frame, image=self.photo)
> 
> To me, saving an attribute reference is not worth the extra line.
> 
> > In the second example, I noticed that the "photo" was referenced two times
> > and I think it might be a redundancy so I remove the line "label.image = 
> > photo". But it fails then.
> 
> On another question, I made the same suggestion.  Oops.
> 
> -- 
> Terry Jan Reedy

Thanks, Terry. After reading your reply I noticed that I had make a mistake. 
The "image" is not an attribute of the Button. It's an option. The 
"label.image=photo" does a different thing. But it didn't help on solving my 
puzzle.

If the problem was caused by the "photo" is a local, then binding the "photo" 
to an local attribute ("label" is a local too) seems no meaning at all. But it 
did make difference! No idea how the underneath mechanism works.

I run this example under the pdb and it can display the picture correctly even 
without the "label.image=photo" statement. Why it fails on running at real 
time? tk event scheduling? I don't know.

--Jach

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How to know if an object is still be referenced?

2016-03-01 Thread Terry Reedy

On 3/1/2016 9:35 PM, jf...@ms4.hinet.net wrote:

Recently I was puzzled by a tkinter problem. The codes below (from a book) can 
display the picture correctly.

 gifdir = "../gifs/"
 from tkinter import *
 win = Tk()
 photo = PhotoImage(file=gifdir + "ora-pp.gif")
 Button(win, image=photo).pack()
 win.mainloop()


Since photo is a global name, the binding remain until you explicitly 
delete it or exit the app.



And the codes below (from another book) will also work.

 class DrumMachine:
 
 
 def create_play_bar(self):
 
 
 photo = PhotoImage(file='images/signature.gif')
 label = Label(playbar_frame, image=photo)
 label.image = photo
 label.grid(row=start_row, column=50, padx=1, sticky='w')
 
 


Here photo is a local name and the binding disappears when the function 
exits.  I would rewrite it to follow pattern 1.


 self.photo = PhotoImage(file='images/signature.gif')
 label = Label(playbar_frame, image=self.photo)

To me, saving an attribute reference is not worth the extra line.


In the second example, I noticed that the "photo" was referenced two times
and I think it might be a redundancy so I remove the line "label.image = 
photo". But it fails then.


On another question, I made the same suggestion.  Oops.

--
Terry Jan Reedy

--
https://mail.python.org/mailman/listinfo/python-list