Thread Tkinter problem

D

Davy

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] == 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()
 
D

Davy

Hi Hendrik,

It works, thank you:)
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()
//--------------------
 
H

Hendrik van Rooyen

Davy said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,066
Latest member
VytoKetoReviews

Latest Threads

Top