Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Thread Tkinter problem

122 views
Skip to first unread message

Davy

unread,
Dec 3, 2008, 7:27:26 AM12/3/08
to
Hi all,

I am using thread and tkinter to write some simple programs and
solidify my understanding of Python thread/GUI programing. The scheme
is thread + queue + GUI. One child thread (gen_board_thread) generate
board and insert data into queue infinitely. Meanwhile, the main
thread canvas widget get the board data from queue.

I assume the program will run forever if don't close them explicitly,
but the fact is contrary to my understanding. It seems the child
thread insert data till queue is full, then the main thread eat the
data till the queue is empty, and the main thread starve(when timeout
option is set) and die. So the two thread work like two function call,
but not two thread!

Is this situation caused by deadlock(I guess main thread has higher
priority)? Or how can I know whether the child thread is still alive?
Ultimately, how to solve the problem?

The code are attached.
Any suggestion will be appreciated :-)
Best regards,
Davy

//---------Code below---------------
from Tkinter import *
import thread
import Queue
##import time

x = 3 ## vertical
y = 5 ## horizontal
block_width = 10
block_height = 10
canvas_width = x * block_width
canvas_height = y * block_height

data_queue = Queue.Queue(20)

board_1 = [[1,0,1],
[0,1,1],
[1,0,0],
[0,0,1],
[0,1,0]]

board_2 = [[0,1,0],
[1,0,0],
[0,1,1],
[1,1,0],
[1,0,1]]

def gen_board_thread():
## Problem: the thread seems to be deadlock or killed or postponed
after execution was taken over by main thread draw_canvas_loop()
print 'enter here'
gen_flip = 1
while(data_queue.full() == False):
##print '???'
##time.sleep(0.1)
if (gen_flip == 1):
gen_flip = 0
data = board_1
else:
gen_flip = 1
data = board_2
data_queue.put(data)
print 'put', data_queue.qsize()

def create_canvas(root,canvas_width,canvas_height,):
canvas = Canvas(root, width=canvas_width, height=canvas_height,
bg='white')
canvas.pack(expand=YES)
return canvas

def draw_canvas_loop(canvas_b):
board = data_queue.get(block = True, timeout=1)
print 'get', data_queue.qsize()
draw_canvas(board, canvas_b, x, y, block_width, block_height)
canvas_b.after(300, lambda:draw_canvas_loop(canvas_b))


def draw_canvas(board, canvas_b, x, y, block_width, block_height):
##canvas_b.after(3000)
##time.sleep(3)
for j in range(y):
for i in range(x):
if board[j][i] == 1:
color = 'black'
else:
color = 'white'
start_x = block_width * i
start_y = block_height * j
end_x = start_x + block_width
end_y = start_y + block_height
canvas_b.create_rectangle
(start_x,start_y,end_x,end_y,fill=color)

if __name__ == '__main__':
root = Tk()
root.title('Tetris')
canvas = create_canvas(root,canvas_width,canvas_height)
thread.start_new(gen_board_thread,())
draw_canvas_loop(canvas)
mainloop()

Hendrik van Rooyen

unread,
Dec 3, 2008, 10:13:09 PM12/3/08
to Davy, pytho...@python.org
"Davy" <zhus...@gmail.com> wrote:


> while(data_queue.full() == False):

This will fill the queue and stop.
Use while true and if queue not full...

- Hendrik

Davy

unread,
Dec 3, 2008, 8:08:27 PM12/3/08
to
On Dec 4, 11:13 am, "Hendrik van Rooyen" <m...@microcorp.co.za> wrote:

>  "Davy" <zhushe...@gmail.com> wrote:
> >     while(data_queue.full() == False):
>
> This will fill the queue and stop.
> Use while true and if queue not full...
Hi Hendrik,

It works, thank you:)

Davy
>
> - Hendrik

Davy

unread,
Dec 3, 2008, 10:23:11 PM12/3/08
to
Add changed code:
//------code changed ---
def gen_board_thread():

print 'enter here'
gen_flip = 1
while(True):
time.sleep(0.3)
if (data_queue.full() == False):

if (gen_flip == 1):
gen_flip = 0
data = board_1
else:
gen_flip = 1
data = board_2
data_queue.put(data)
print 'put', data_queue.qsize()
//--------------------
>
> Davy
>
>
>
>
>
> > - Hendrik- Hide quoted text -
>
> - Show quoted text -

Message has been deleted

Hendrik van Rooyen

unread,
Dec 4, 2008, 2:14:26 PM12/4/08
to pytho...@python.org
"Davy" <zhu..@gmail.com> wrote:

>def gen_board_thread():
> print 'enter here'
> gen_flip = 1
> while(True):

You don't need the brackets: while True: is good enough

> time.sleep(0.3)
> if (data_queue.full() == False):

write: if not data_queue.full(): , and lose the brackets here too.

> if (gen_flip == 1):

write: if gen_flip: (no brackets - not needed, ugly)

> gen_flip = 0
> data = board_1
> else:
> gen_flip = 1
> data = board_2
> data_queue.put(data)
> print 'put', data_queue.qsize()

HTH - Hendrik

0 new messages