#111 zbar thread in python blocks other thread

version_0.10
open
nobody
None
1
2015-02-24
2013-07-09
afnfun
No

I'm using zbar thread (to read a QR code from a wabcam in real time) in python application in parallel with Tkinter loop as the second thread.
The zbar thread blocks the Tk thread! only when the zbar decodes a QR code, in this short slot of time the Tk inter thread works and then blocks again.

See the following portion of my code:

class MyTkApp(threading.Thread):
def init(self):
threading.Thread.init(self)

def callback(self):
   self.root.quit()
def run(self):
    global OVVM
    global proc
    self.root=Tk()
    self.root.protocol("WM_DELETE_WINDOW", self.callback)
    OVVM=VM()
    #modify the window
    self.root.title("VM V.10")
    self.root.geometry("1280x800")
    # Create a text frame to hold the text Label and the Entry widget
    textFrame = Frame(self.root)
    #Create a Label in textFrame
    entryLabel = Label(textFrame)
    entryLabel["text"] = "Enter the text:"
    entryLabel.pack(side=LEFT)
    textFrame.pack()
    myApp = VerMod(self.root)
    #run the function each 500 ms
    self.root.after(50,myApp.verify)
    self.root.mainloop()

class ScanThread(threading.Thread):
def init(self, mode, image):
self.quit = False
self.mode = mode
self.image = image
if mode == 'wait':
self.task = self.task_wait
elif mode == 'one':
self.task = self.task_one
elif mode == 'image':
self.task = self.task_image
else:
self.task = self.task_normal
threading.Thread.init(self)

def run(self):
    self.task()

def terminate(self):
    if hasattr(self, 'proc'):
        self.proc.active = False
    self.quit = True

def init_processor(self):
        #initialize the zbar processor and cam device
        self.proc = zbar.Processor()
        # configure the Processor
        self.proc.parse_config('enable')
        # initialize the Processor
        device = '/dev/video0'
        if len(argv) > 1:
            device = argv[1]
        self.proc.init(device)
        self.proc.set_data_handler(self.process_data)
        # enable the preview window
        self.proc.visible = True
        # initiate scanning
        self.proc.active = True
        time.sleep(0.5)

def task_normal(self):
    self.init_processor()
    # thread is finished here

def task_wait(self):
    self.init_processor()
    self.proc.user_wait() #

def task_one(self):
    self.init_processor()
    while not self.quit:
        #self.start_processor()
        self.proc.process_one(3)

def task_image(self):
    scanner = zbar.ImageScanner()
    scanner.parse_config('disable')
    scanner.parse_config('qrcode.enable')
    while not self.quit:
        pil = Image.open(self.image).convert('L')
        width, height = pil.size
        raw = pil.tostring()
        image = zbar.Image(width, height, 'Y800', raw)
        scanner.scan(image)
        for symbol in image:
            print symbol.data
        del(image)
        del(pil)
        time.sleep(0.5)

def process_data(self, proc, image, closure):
    global readed_code
    for symbol in image:
        if not symbol.count:
                        readed_code= '%s' % symbol.data
                        print readed_code
                        time.sleep(0.1)

main

if name=='main':

# Thread 1: The zbar thread to read a qr code
image = None
mode='one'
zbar_thread = ScanThread(mode, image)
zbar_thread.start()
# Thread 2: the main loop of the Tkinter window
tk_thread=MyTkApp()
tk_thread.start()

Discussion

  • afnfun
    afnfun
    2013-07-09

    I wonder how can I solve this issue, I mean run both threads together?