[Tutor] nube question...

Alan Gauld alan.gauld at btinternet.com
Sun Mar 25 10:50:47 CEST 2007


"Lurch" <erik.kloeppel at forethought.net> wrote

> the nuts,bolts, and the occasional nail.  Now Im trying to code a 
> simple
> status window to let the dumb user (me) know what's going on behind 
> the
> curtain.  The idea is, the application calls the subroutine, the
> subroutine pops open a frame and print some text in it, then returns
> control back to the  main app - leaving the frame/text visible. 
> Then,
> the app calls the subroutine and *updates* the frame, so you end up 
> with
> a growing list of notices...(basically, I'm working with a variable 
> set
> of files, and it's convenient to know which is being operated on)

> I've ripped code from Mark Lutz's book (3rd edition), from Welch's 
> book
> (also 3rd edition), and from around the net.

One of the problems with ripping code from books is that you
often wind up with a strange mix of styles without really
understanding any of it. And I think that's happening here.

Do you actually understand how this program is supposed to work?
Can you explain why the MESSAGES class definition is inside
the messages() function?
Do you know what sequence of events leads to your window
being created and where the reference to the window is held?

It would be better to structure your Tkinter app in a more
conventional manner - have you read the online Tkinter
tutorial/reference pages?

The reason I ask is that your code calls messages() every time
is goes round the loopp, but messages() only defines the
MESSAGES class, it doesn't do anything with it. Why are
you doing that?

I also don't understand why you are using a dictionary
as a counter? Why not just use a simple variable to hold
the number and avoid all the x[1] stuff?

If you trace what happens when you run this program:
It creates a MESSAGES instance and then calls mainloop.
But you don't hold a refernce to the object nor do you have
any useful event handlers defined in the GUI.
It then processes (standard) events. When the mainloop exits
it then goes on to call your loop() function which creates the
class definition and prints 'howdee' multiple times. It doesn't
make sense! (to me!)

I suggest you sit down, work out what you actually want
to happen and design the straucture of your code to do that.
That means thinking in terms of events and messages.
You see to be trying to mix a non event-driven model
(your loop() function) and an event driven model - your GUI.
That's not a good idea. You need to rethink what you are doing
so that you crewate the GUI then launch your processing
from a GUI event. You can then update the GUI from your
code. If your processing takes a long time as implied in the
message you will either want to put your code in a thread
(see an earlier thread last week) or break it into chunks
controlled by the GUI - maybe via timers.

> missing something obvious when it comes to self.update.  The 
> subroutine
> works as advertised the first time through, but one the window is 
> open
> and the text displays, the app stops - unless I close the window. 
> Of
> course, then everything works until the NEXT message is displayed.

I don't understand this either. What NEXT message?
There is no reference to NEXT in your code? Also your code
prints to the console but also displays a GUI window, which
window are you referring to? The GUI or the console?

As to self.update - you only call that once when you create
the instance. Do you understand OOP and how objects are
created? The difference between classes and instances?

> Sure, I could add a button and work from that, but I don't *WANT* 
> to -
> the idea is a (more or less) continuous flow of information that I 
> can
> scroll through if need be.

Thats not a problem, you don;t need a button but you do need
to reestructure your code so that your function runs (probably
as a thread) within the GUI mainloop().

> As you can see from the sample code below, I'm using the Text widget
> instead of Message.  I had a reason for that when I started this
> nightmare, but I'm not wedded to it.

Text is probably the right thing to use for what you want.

> Any assistance from anybody would be much appreciated.

I'd start again.
First write a GUI class that just contains the Text widget - forget
about scroll bars for now. Then write a method within that class
that does the looping - your loop() function effectively, and call
that at the end of the init(). Instead of printing make the loop
insert text into the TEXT widget.

That should result in a program that does what you want but
doesn't have scroll bars and is totally unresponsive until the
loop finishes. The next tricxk is to make your methoid run in
a thread, but get the basics working first. It should be a really
short program, maybe 10-15 lines.

HTH,


-- 
Alan Gauld
Author of the Learn to Program web site
http://www.freenetpages.co.uk/hp/alan.gauld

> -----------------------
> from Tkinter import *
>
> data={}
> data[4,9]="you are here"
> data[4,10]=0
> msg=1
> x={}
>
> def loop():
>    global x
>    x[1]=0
>    while x[1]<10:
>        messages(x)
>        print "howdee"
>        x[1]=x[1]+1
>
> def messages(msg):
>    class MESSAGES(Frame):
>        def __init__(self,parent=None,text='', file=None):
>            Frame.__init__(self,parent)
>            self.pack(expand=YES,fill=BOTH)
>            self.makewidgets()
>            self.message(text)
>            self.update()
>
>        def makewidgets(self):
>            sbar=Scrollbar(self)
>            a=Text(self,relief=RAISED)
>            sbar.config(command=a.yview,bg='#fcfcfc')
>            a.config(yscrollcommand=sbar.set,bg='#f0f0f0')
>            sbar.pack(side=RIGHT,fill=Y)
>            a.pack(side=LEFT,expand=YES,fill=BOTH)
>            self.a=a
>            data[4,10]=1
>
>        def message(self,text):
>            self.a.insert(END,text)
>            self.a.focus()
>            return self.a.get('35.2',END+'-1c')
>
>    if __name__=='__main__':
>        root=Tk()
>        MESSAGES(text=data[4,9]).mainloop()
>        return
>
> loop()
>




More information about the Tutor mailing list