[Tkinter-discuss] Stopping a for loop with a sleep() funciton in it

Alexnb alexnbryan at gmail.com
Fri Jul 11 00:31:24 CEST 2008




Guilherme Polo wrote:
> 
> On Thu, Jul 10, 2008 at 5:57 PM, Alexnb <alexnbryan at gmail.com> wrote:
>>
>> Okay, so I have a for loop with a sleep command. I want the loop to
>> continue
>> until it is told to stop. I want to tell it to stop when a list goes from
>> empty to having something. The problem is that when that loop starts, the
>> program pretty much stops with it.
> 
> You need to remove the use of sleep and use "after" instead. You keep
> scheduling your task till the condition is not met anymore, then you
> stop scheduling it with "after".
> 
>> To make things harder, I really want that
>> to be it's own class, so I have to pass it the list that triggers the
>> stopping, but I can only pass it the list once. So I don't think it is
>> possible.
> 
> It is, just pass some other object along which can call the method
> "after".
> 
>> But if this made sense to anyone, and you have a suggestion I
>> would love it. Heres the full code: (but at the bottom, the Open function
>> is
>> really the only thing that matters)
>>
> 
> If you want help based on code, you have to post a short-enough code
> that demonstrates the problem.
> 
>> from Tkinter import *
>> import time
>>
>> class BusyBar(Frame):
>>    def __init__(self, master=None, **options):
>>        # make sure we have sane defaults
>>        self.master=master
>>        self.options=options
>>        self.width=options.setdefault('width', 300)
>>        self.height=options.setdefault('height', 20)
>>        self.background=options.setdefault('background', 'white')
>>        self.relief=options.setdefault('relief', 'sunken')
>>        self.bd=options.setdefault('bd', 2)
>>
>>        #extract options not applicable to frames
>>        self._extractOptions(options)
>>
>>        # init the base class
>>        Frame.__init__(self, master, options)
>>
>>        self.incr=self.width*self.increment
>>        self.busy=0
>>        self.dir='right'
>>
>>        # create the canvas which is the container for the bar
>>        self.canvas=Canvas(self, height=self.height, width=self.width,
>> bd=0,
>>                           highlightthickness=0,
>> background=self.background)
>>        # catch canvas resizes
>>        self.canvas.bind('<Configure>', self.onSize)
>>
>>        # this is the bar that moves back and forth on the canvas
>>        self.scale=self.canvas.create_rectangle(0, 0,
>> self.width*self.barWidth, self.height, fill=self.fill, width = 0)
>>
>>        # label that is in the center of the widget
>>        self.label=self.canvas.create_text(self.canvas.winfo_reqwidth() /
>> 2,
>>                                           self.height / 2,
>> text=self.text,
>>                                           anchor="c",
>> fill=self.foreground,
>>                                           font=self.font)
>>        self.update()
>>        self.canvas.pack(side=TOP, fill=X, expand=NO)
>>
>>    def _extractOptions(self, options):
>>        # these are the options not applicable to a frame
>>        self.foreground=pop(options, 'foreground', 'white')
>>        self.fill=pop(options, 'fill', 'black')
>>        self.interval=pop(options, 'interval', 30)
>>        self.font=pop(options, 'font','arial 12')
>>        self.text=pop(options, 'text', '')
>>        self.barWidth=pop(options, 'barWidth', 0.2)
>>        self.increment=pop(options, 'increment', 0.05)
>>
>>    # todo - need to implement config, cget, __setitem__, __getitem__ so
>> it's more like a reg widget
>>    # as it is now, you get a chance to set stuff at the constructor but
>> not
>> after
>>
>>    def onSize(self, e=None):
>>        self.width = e.width
>>        self.height = e.height
>>        # make sure the label is centered
>>        self.canvas.delete(self.label)
>>        self.label=self.canvas.create_text(self.width / 2, self.height /
>> 2,
>> text=self.text,
>>                                           anchor="c",
>> fill=self.foreground,
>> font=self.font)
>>
>>    def on(self):
>>        self.busy = 1
>>        self.canvas.after(self.interval, self.update)
>>
>>    def of(self):
>>        self.busy = 0
>>
>>    def update(self):
>>        # do the move
>>        x1,y1,x2,y2 = self.canvas.coords(self.scale)
>>        if x2>=self.width:
>>            self.dir='left'
>>        if x1<=0:
>>            self.dir='right'
>>        if self.dir=='right':
>>            self.canvas.move(self.scale, self.incr, 0)
>>        else:
>>            self.canvas.move(self.scale, -1*self.incr, 0)
>>
>>        if self.busy:
>>            self.canvas.after(self.interval, self.update)
>>        self.canvas.update_idletasks()
>>
>> def pop(dict, key, default):
>>    value = dict.get(key, default)
>>    if dict.has_key(key):
>>        del dict[key]
>>    return value
>>
>>
>> #if __name__=='__main__':
>>
>> #-----------------------------IMPORTANT
>> STUFF-------------------------------------------------
>> def Open(root):
>>
>>    bb = BusyBar(root, text='Grabbing Definitions')
>>    bb.pack(side=LEFT, expand=NO)
>>
>>    bb.on()
>>    root.update_idletasks()
>>    for i in range(0, 100):
>>        time.sleep(0.1)
>>        root.update()
>>    bb.of()
>>
>> and the Open fucntion is with I would be calling from another program.
>> --
>> View this message in context:
>> http://www.nabble.com/Stopping-a-for-loop-with-a-sleep%28%29-funciton-in-it-tp18391735p18391735.html
>> Sent from the Python - tkinter-discuss mailing list archive at
>> Nabble.com.
>>
>> _______________________________________________
>> Tkinter-discuss mailing list
>> Tkinter-discuss at python.org
>> http://mail.python.org/mailman/listinfo/tkinter-discuss
>>
> 
> 
> 
> -- 
> -- Guilherme H. Polo Goncalves
> _______________________________________________
> Tkinter-discuss mailing list
> Tkinter-discuss at python.org
> http://mail.python.org/mailman/listinfo/tkinter-discuss
> 
> 

Okay, so I modified the bottom code to this:

def Open(root):

    bb = BusyBar(root, text='Grabbing Definitions')
    bb.pack(side=LEFT, expand=NO)


    def sleeper():
        root.update
        root.after(1, sleeper)
    bb.on()
    root.update_idletasks()
    
    sleeper()

    #for i in range(0, 100):
        #time.sleep(0.1)
        #root.update()
    bb.of()

but it doesn't repeat. What am I missing?

-- 
View this message in context: http://www.nabble.com/Stopping-a-for-loop-with-a-sleep%28%29-funciton-in-it-tp18391735p18393290.html
Sent from the Python - tkinter-discuss mailing list archive at Nabble.com.



More information about the Tkinter-discuss mailing list