A Tkinter status/information bar

Grant Edwards ge at nowhere.none
Mon Oct 2 12:49:50 EDT 2000


Christian Tanzer wrote:

>> In my various modules I have statements like
>> 
>> print __name__,': Reading data from disk'
>> print __name__,': Connecting to server'
>> 
>> This information is in other words currently being printed out to the
>> terminal window. I want this information to be printed out in my main
>> gui window. This feature will give the user a clue of what is going on
>> as well as being COOL ;)
>
>You need an object with a write function taking one string argument.
>This function puts the passed argument into your status bar.

I tried it and it's bit more complicated than I initially
thought. For a single "print" statement, multiple "write" calls
may be made, and you want things like

  print "spam",
  print "and eggs"
  
to behave in an intuitive way.  
  
Here's what I came up with.  There's probably a more efficient
way to do it, but this is nice and obvious:

----------------------------------------------------------------------
#!/usr/bin/python

class StringVarFile:
    def __init__(self,stringVar,window):
        self.__newline = 0
        self.__stringvar = stringVar
        self.__window = window

    def write(self,s):
        new = self.__stringvar.get()
        for c in s:
            if c == '\n':
                self.__newline = 1
            else:
                if self.__newline:
                    new = ""
                    self.__newline = 0
                new = new+c
        self.set(new)
        
    def set(self,s):
        self.__stringvar.set(s)
        self.__window.update()
        
    def get(self):
        return self.__stringvar.get()


if __name__ == "__main__":
    
    import time
    import sys
    from Tkinter import *

    root = Tk()

    def statusTest():
        print "doing something...",
        time.sleep(0.5)
        print "done"
        time.sleep(1.0)
        print "did something else"
        time.sleep(1.0)
        print "doing a bunch of things...",
        for s in ('one','two','three','four','five'):
            print s,
            time.sleep(0.5)
        print "done."
        time.sleep(1.0)
        print "string 1"
        time.sleep(1.0)
        print "string 2"
        time.sleep(1.0)
        print "start counting in 1.0 seconds:"
        root.after(1000, statusUpdate)
            
    count = 0;
    def statusUpdate():
        global count
        if count % 10 == 0:
            print ""
            print "count = ",
        print count,
        count = count + 1
        root.after(100, statusUpdate)

    statusVar = StringVar()
    Label(root, text="top label").pack()
    Label(root, width=60, justify=LEFT, anchor=W, textvariable=statusVar).pack(fill=X,expand=Y)
    status = StringVarFile(statusVar,root)
    sys.stdout = status
    root.after(100, statusTest)
    root.mainloop()

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

-- 
Grant Edwards                   grante             Yow!  Either CONFESS now or
                                  at               we go to "PEOPLE'S COURT"!!
                               visi.com            


Newsgroups: comp.lang.python
Subject: Re: A Tkinter status/information bar 
References: <mailman.970470665.2254.python-list at python.org>
Followup-To: 

Christian Tanzer wrote:

>> In my various modules I have statements like
>> 
>> print __name__,': Reading data from disk'
>> print __name__,': Connecting to server'
>> 
>> This information is in other words currently being printed out to the
>> terminal window. I want this information to be printed out in my main
>> gui window. This feature will give the user a clue of what is going on
>> as well as being COOL ;)
>
>You need an object with a write function taking one string argument.
>This function puts the passed argument into your status bar.

I tried it and it's bit more complicated than I initially
thought. For a single "print" statement, multiple "write" calls
may be made, and you want things like

  print "spam",
  print "and eggs"
  
to behave in an intuitive way.  
  
Here's what I came up with.  There's probably a more efficient
way to do it, but this is nice and obvious:

----------------------------------------------------------------------
#!/usr/bin/python

class StringVarFile:
    def __init__(self,stringVar,window):
        self.__newline = 0
        self.__stringvar = stringVar
        self.__window = window

    def write(self,s):
        new = self.__stringvar.get()
        for c in s:
            if c == '\n':
                self.__newline = 1
            else:
                if self.__newline:
                    new = ""
                    self.__newline = 0
                new = new+c
        self.set(new)
        
    def set(self,s):
        self.__stringvar.set(s)
        self.__window.update()
        
    def get(self):
        return self.__stringvar.get()


if __name__ == "__main__":
    
    import time
    import sys
    from Tkinter import *

    root = Tk()

    def statusTest():
        print "doing something...",
        time.sleep(0.5)
        print "done"
        time.sleep(1.0)
        print "did something else"
        time.sleep(1.0)
        print "doing a bunch of things...",
        for s in ('one','two','three','four','five'):
            print s,
            time.sleep(0.5)
        print "done."
        time.sleep(1.0)
        print "string 1"
        time.sleep(1.0)
        print "string 2"
        time.sleep(1.0)
        print "start counting in 1.0 seconds:"
        root.after(1000, statusUpdate)
            
    count = 0;
    def statusUpdate():
        global count
        if count % 10 == 0:
            print ""
            print "count = ",
        print count,
        count = count + 1
        root.after(100, statusUpdate)

    statusVar = StringVar()
    Label(root, text="top label").pack()
    Label(root, width=60, justify=LEFT, anchor=W, textvariable=statusVar).pack(fill=X,expand=Y)
    status = StringVarFile(statusVar,root)
    sys.stdout = status
    root.after(100, statusTest)
    root.mainloop()

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

-- 
Grant Edwards                   grante             Yow!  Either CONFESS now or
                                  at               we go to "PEOPLE'S COURT"!!
                               visi.com            



More information about the Python-list mailing list