0

I am trying to make a timer to execute a block of code every second let's say, using tkinter in python. But instead of executing the code every second, which is moving a label across a canvas, it seems to buffer and wait until the loop is finished and only then display the moved label. Beneath is the piece of coding where I think the problem is found. I personally think the for-loop in the second function is creating problems, but I don't know how to solve this.

def roll(self):
    number=randint(2,12)
    print number
    if self.a==0:
        self.place_player_1(self.start_turn_pos_1,number+self.start_turn_pos_1)
        self.start_turn_pos_1+=number
    elif self.a==1:
        self.place_player_2(self.start_turn_pos_2,number+self.start_turn_pos_2)
        self.start_turn_pos_2+=number
    return number

def place_player_1(self,start_turn_pos_1,number):
    #Define the board
    for i in range(self.start_turn_pos_1,number+1,1):
        self.c.after(1000,self.move_1(i))

def move_1(self,i):
    e1=streets_x[i]
    g1=streets_y[i]
    self.label_player1.place(x=e1,y=g1)
konovalov100
  • 87
  • 1
  • 5

2 Answers2

2

self.move_1(i) calls the method immediately. To postpone the call:

self.c.after(1000, self.move_1, i) #note: no parentheses

To repeat the call every second, add .after call at the end of self.move_1 method:

def place_player_1(self,start_turn_pos_1,number):
    self.c.after(1000, self.move_1, start_turn_pos_1, number) # call in a sec

def move_1(self,i, limit):
    e1=streets_x[i]
    g1=streets_y[i]
    self.label_player1.place(x=e1,y=g1)
    if i < limit: # schedule the next call
       self.c.after(1000, self.move_1, i + 1, limit)

See setTimeout(), setInterval() analogs in Python using tkinter, or gtk, or twisted.

Community
  • 1
  • 1
jfs
  • 399,953
  • 195
  • 994
  • 1,670
  • The parentheses made it slower, so thank you for clearification. But it still appears to only execute the self.move_1 method just once, or at least only display the label once, instead of every second on a different position what I want it to do – konovalov100 Jun 04 '13 at 22:12
  • Note: The code for the link given in the answer above puts the function `countdown` in the call to `after`, i.e. it put itself in, which has some kind of recursive-like effect. After the pause it calls `after` again and puts itself in for the next round. – Mike Müller Jun 04 '13 at 22:21
0

All function calls happen at the same time:

self.c.after(1000,self.move_1(i))

Because the are called after 1000 milliseconds.

Make the delay larger for each step. For example:

def place_player_1(self,start_turn_pos_1,number):
    #Define the board
    delay = 1000
    for index, i in enumerate(range(self.start_turn_pos_1, number + 1), 1):
        self.c.after(delay * index, self.move_1, i)

Now you schedule the function calls for different times.

Mike Müller
  • 82,630
  • 20
  • 166
  • 161
  • Thanks for replying, but either I don't fully understand what you're saying, but I am trying to execute the function move_1 in the range stated in function place_player_1 but then make it so that move_1 is executed with a delay from the last time in the loop. Sorry if i'm unclear. Right now it just freezes for a given amount of time and then in one go dispays all the times the move_1 is executed, so with no time delay in between. – konovalov100 Jun 04 '13 at 21:51