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

Guilherme Polo ggpolo at gmail.com
Thu Jul 10 23:22:45 CEST 2008


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


More information about the Tkinter-discuss mailing list