Thread Tkinter problem

Davy zhushenli at gmail.com
Wed Dec 3 07:27:26 EST 2008


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()



More information about the Python-list mailing list