python - Interrupt a blocking evdev reading -


i have module captures reads barcode scanner. problem can not close properly. after sending keyboardinterrupt or systemexit signal, stops when scan barcode.

i tried add method barcodescanner class, still doesn't work:

def interrupt(self):     """envoi la demande d'arrêt."""      super(barcodescanner, self).interrupt()     self.device.write(ecodes.ev_key, ecodes.key_esc, 0)     self.device.write(ecodes.ev_syn, ecodes.syn_report, 0) 

how can that?

interruptable.py

#!/usr/bin/env python3 # -*-coding:utf-8 -*   class interruptable:     """classe intégrant une boucle sans fin pouvant être stoppée proprement."""      interruptables = []      def __init__(self):         """crée un objet interruptible."""          self._interrupted = false         interruptable.interruptables.append(self)      def interrupt(self):         """envoi la demande d'arrêt."""          self._interrupted = true      def reset(self):         """permet le redémarrage d'un service."""          self._interrupted = false      def interrupted(self):         """verifie si la demande d'arrêt à déjà été envoyée."""          return self._interrupted 

barcode_scanner.py

#!/usr/bin/env python3 # -*-coding:utf-8 -*  evdev import inputdevice, ecodes, list_devices, categorize import signal, sys import threading time import sleep  tymsoft.interruptable import interruptable  class barcodescanner(interruptable):     """todo"""      def __init__(self, device_name='bar code', layout='azerty_fr'):         self.modifiers = {             # 0: none, 29: u'lctrl', 42: u'lshft', 54: u'rshft', 56: u'lalt', 97:u'rctrl', 100: u'ralt'             0: 0, 29: 1, 42: 2, 54: 3, 56: 4, 97: 5, 100: 6         }         self.layouts = {             'azerty_fr': {                 # [normal, lctrl, lshft, rshft, lalt, rctrl, ralt]                 2: [u'&', u'', u'1', u'1', u'', u'', u''],                 3: [u'é', u'', u'2', u'2', u'', u'', u'~'],                 4: [u'"', u'', u'3', u'3', u'', u'', u'#'],                 5: [u'\'', u'', u'4', u'4', u'', u'', u'{'],                 6: [u'(', u'', u'5', u'5', u'', u'', u'['],                 7: [u'-', u'', u'6', u'6', u'', u'', u'|'],                 8: [u'è', u'', u'7', u'7', u'', u'', u'`'],                 9: [u'_', u'', u'8', u'8', u'', u'', u'\\'],                 10: [u'ç', u'', u'9', u'9', u'', u'', u'^'],                 11: [u'à', u'', u'0', u'0', u'', u'', u'@'],                 12: [u')', u'', u'°', u'°', u'', u'', u']'],                 13: [u'=', u'', u'+', u'+', u'', u'', u'}'],                 15: [u'\t', u'', u'', u'', u'', u'', u''],                 16: [u'a', u'', u'a', u'a', u'', u'', u''],                 17: [u'z', u'', u'z', u'z', u'', u'', u''],                 18: [u'e', u'', u'e', u'e', u'', u'', u'€'],                 19: [u'r', u'', u'r', u'r', u'', u'', u''],                 20: [u't', u'', u't', u't', u'', u'', u''],                 21: [u'y', u'', u'y', u'y', u'', u'', u''],                 22: [u'u', u'', u'u', u'u', u'', u'', u''],                 23: [u'i', u'', u'i', u'i', u'', u'', u''],                 24: [u'o', u'', u'o', u'o', u'', u'', u''],                 25: [u'p', u'', u'p', u'p', u'', u'', u''],                 26: [u'^', u'', u'¨', u'¨', u'', u'', u''],                 27: [u'$', u'', u'£', u'£', u'', u'', u'¤'],                 28: [u'\n', u'', u'', u'', u'', u'', u''],                 30: [u'q', u'', u'q', u'q', u'', u'', u''],                 31: [u's', u'', u's', u's', u'', u'', u''],                 32: [u'd', u'', u'd', u'd', u'', u'', u''],                 33: [u'f', u'', u'f', u'f', u'', u'', u''],                 34: [u'g', u'', u'g', u'g', u'', u'', u''],                 35: [u'h', u'', u'h', u'h', u'', u'', u''],                 36: [u'j', u'', u'j', u'j', u'', u'', u''],                 37: [u'k', u'', u'k', u'k', u'', u'', u''],                 38: [u'l', u'', u'l', u'l', u'', u'', u''],                 39: [u'm', u'\n', u'm', u'm', u'', u'', u''],                 40: [u'ù', u'', u'%', u'%', u'', u'', u''],                 41: [u'²', u'', u'', u'', u'', u'', u''],                 43: [u'*', u'', u'µ', u'µ', u'', u'', u''],                 44: [u'w', u'', u'w', u'w', u'', u'', u''],                 45: [u'x', u'', u'x', u'x', u'', u'', u''],                 46: [u'c', u'', u'c', u'c', u'', u'', u''],                 47: [u'v', u'', u'v', u'v', u'', u'', u''],                 48: [u'b', u'', u'b', u'b', u'', u'', u''],                 49: [u'n', u'', u'n', u'n', u'', u'', u''],                 50: [u',', u'', u'?', u'?', u'', u'', u''],                 51: [u';', u'', u'.', u'.', u'', u'', u''],                 52: [u':', u'', u'/', u'/', u'', u'', u''],                 53: [u'!', u'', u'§', u'§', u'', u'', u''],                 57: [u' ', u'', u' ', u' ', u'', u'', u''],                 86: [u'<', u'', u'>', u'>', u'', u'', u''],                 96: [u'\n', u'', u'', u'', u'', u'', u'']             },             'qwerty_us': {                 # [normal, lctrl, lshft, rshft, lalt, rctrl, ralt]                 2: [u'1', u'', u'!', u'!', u'', u'', u''],                 3: [u'2', u'', u'@', u'@', u'', u'', u''],                 4: [u'3', u'', u'#', u'#', u'', u'', u''],                 5: [u'4', u'', u'$', u'$', u'', u'', u''],                 6: [u'5', u'', u'%', u'%', u'', u'', u''],                 7: [u'6', u'', u'^', u'^', u'', u'', u''],                 8: [u'7', u'', u'&', u'&', u'', u'', u''],                 9: [u'8', u'', u'*', u'*', u'', u'', u''],                 10: [u'9', u'', u'(', u'(', u'', u'', u''],                 11: [u'0', u'', u')', u')', u'', u'', u''],                 12: [u'-', u'', u'_', u'_', u'', u'', u''],                 13: [u'=', u'', u'+', u'+', u'', u'', u''],                 15: [u'\t', u'', u'', u'', u'', u'', u''],                 16: [u'q', u'', u'q', u'q', u'', u'', u''],                 17: [u'w', u'', u'w', u'w', u'', u'', u''],                 18: [u'e', u'', u'e', u'e', u'', u'', u''],                 19: [u'r', u'', u'r', u'r', u'', u'', u''],                 20: [u't', u'', u't', u't', u'', u'', u''],                 21: [u'y', u'', u'y', u'y', u'', u'', u''],                 22: [u'u', u'', u'u', u'u', u'', u'', u''],                 23: [u'i', u'', u'i', u'i', u'', u'', u''],                 24: [u'o', u'', u'o', u'o', u'', u'', u''],                 25: [u'p', u'', u'p', u'p', u'', u'', u''],                 26: [u'[', u'', u'{', u'{', u'', u'', u''],                 27: [u']', u'', u'}', u'}', u'', u'', u''],                 28: [u'\n', u'', u'', u'', u'', u'', u''],                 30: [u'a', u'', u'a', u'a', u'', u'', u''],                 31: [u's', u'', u's', u's', u'', u'', u''],                 32: [u'd', u'', u'd', u'd', u'', u'', u''],                 33: [u'f', u'', u'f', u'f', u'', u'', u''],                 34: [u'g', u'', u'g', u'g', u'', u'', u''],                 35: [u'h', u'', u'h', u'h', u'', u'', u''],                 36: [u'j', u'', u'j', u'j', u'', u'', u''],                 37: [u'k', u'', u'k', u'k', u'', u'', u''],                 38: [u'l', u'', u'l', u'l', u'', u'', u''],                 39: [u';', u'', u':', u':', u'', u'', u''],                 40: [u'\'', u'', u'"', u'"', u'', u'', u''],                 41: [u'`', u'', u'~', u'~', u'', u'', u''],                 43: [u'\\', u'', u'|', u'|', u'', u'', u''],                 44: [u'z', u'', u'z', u'z', u'', u'', u''],                 45: [u'x', u'', u'x', u'x', u'', u'', u''],                 46: [u'c', u'', u'c', u'c', u'', u'', u''],                 47: [u'v', u'', u'v', u'v', u'', u'', u''],                 48: [u'b', u'', u'b', u'b', u'', u'', u''],                 49: [u'n', u'', u'n', u'n', u'', u'', u''],                 50: [u'm', u'\n', u'm', u'm', u'', u'', u''],                 51: [u',', u'', u'<', u'<', u'', u'', u''],                 52: [u'.', u'', u'>', u'>', u'', u'', u''],                 53: [u'/', u'', u'?', u'?', u'', u'', u''],                 57: [u' ', u'', u' ', u' ', u'', u'', u''],                 96: [u'\n', u'', u'', u'', u'', u'', u'']             }         }         self.eol = [(0, 28), (0, 96), (29, 39)]          self.layout = layout          self.device = none         devices = map(inputdevice, list_devices())         device in devices:             if device_name in device.name:                 self.device = inputdevice(device.fn)                 print('lecteur de codes-barres : ' + device.name)                 break          self._listeners = []         interruptable.__init__(self)         self.device.grab()      def start_capture(self):         """todo"""          def run():             barcode = ''             modifier = 0             keycode = 0             event in self.device.read_loop():                 if not self.interrupted():                     if event.type == ecodes.ev_key:                         data = categorize(event)                         if data.keystate == 1:                             if data.scancode in self.modifiers:                                 modifier = data.scancode                             elif data.scancode in self.layouts[self.layout]:                                 keycode = data.scancode                     elif event.type == ecodes.ev_syn:                         if (modifier, keycode) in self.eol:                             if len(barcode) > 0:                                 listener in self._listeners:                                     listener(barcode)                                 barcode = ''                         elif keycode != 0:                             barcode += self.layouts[self.layout][keycode][self.modifiers[modifier]]                         modifier = 0                         keycode = 0                 else:                     self.device.ungrab()                     break           thread = threading.thread(target=run, name='barcode_scanner')         thread.start()      def register_listener(self, callback):         self._listeners.append(callback) 

i solved issue replacing read_loop() method loop of select()+read(). in way, put timeout on select.

#!/usr/bin/env python3 # -*-coding:utf-8 -*  evdev import inputdevice, ecodes, list_devices, categorize select import select import signal, sys import threading time import sleep  tymsoft.interruptable import interruptable  class barcodescanner(interruptable):     """todo"""      def __init__(self, device_name='bar code', layout='azerty_fr'):         self.modifiers = {             # 0: none, 29: u'lctrl', 42: u'lshft', 54: u'rshft', 56: u'lalt', 97:u'rctrl', 100: u'ralt'             0: 0, 29: 1, 42: 2, 54: 3, 56: 4, 97: 5, 100: 6         }         self.layouts = {             'azerty_fr': {                 # [normal, lctrl, lshft, rshft, lalt, rctrl, ralt]                 2: [u'&', u'', u'1', u'1', u'', u'', u''],                 3: [u'é', u'', u'2', u'2', u'', u'', u'~'],                 4: [u'"', u'', u'3', u'3', u'', u'', u'#'],                 5: [u'\'', u'', u'4', u'4', u'', u'', u'{'],                 6: [u'(', u'', u'5', u'5', u'', u'', u'['],                 7: [u'-', u'', u'6', u'6', u'', u'', u'|'],                 8: [u'è', u'', u'7', u'7', u'', u'', u'`'],                 9: [u'_', u'', u'8', u'8', u'', u'', u'\\'],                 10: [u'ç', u'', u'9', u'9', u'', u'', u'^'],                 11: [u'à', u'', u'0', u'0', u'', u'', u'@'],                 12: [u')', u'', u'°', u'°', u'', u'', u']'],                 13: [u'=', u'', u'+', u'+', u'', u'', u'}'],                 15: [u'\t', u'', u'', u'', u'', u'', u''],                 16: [u'a', u'', u'a', u'a', u'', u'', u''],                 17: [u'z', u'', u'z', u'z', u'', u'', u''],                 18: [u'e', u'', u'e', u'e', u'', u'', u'€'],                 19: [u'r', u'', u'r', u'r', u'', u'', u''],                 20: [u't', u'', u't', u't', u'', u'', u''],                 21: [u'y', u'', u'y', u'y', u'', u'', u''],                 22: [u'u', u'', u'u', u'u', u'', u'', u''],                 23: [u'i', u'', u'i', u'i', u'', u'', u''],                 24: [u'o', u'', u'o', u'o', u'', u'', u''],                 25: [u'p', u'', u'p', u'p', u'', u'', u''],                 26: [u'^', u'', u'¨', u'¨', u'', u'', u''],                 27: [u'$', u'', u'£', u'£', u'', u'', u'¤'],                 28: [u'\n', u'', u'', u'', u'', u'', u''],                 30: [u'q', u'', u'q', u'q', u'', u'', u''],                 31: [u's', u'', u's', u's', u'', u'', u''],                 32: [u'd', u'', u'd', u'd', u'', u'', u''],                 33: [u'f', u'', u'f', u'f', u'', u'', u''],                 34: [u'g', u'', u'g', u'g', u'', u'', u''],                 35: [u'h', u'', u'h', u'h', u'', u'', u''],                 36: [u'j', u'', u'j', u'j', u'', u'', u''],                 37: [u'k', u'', u'k', u'k', u'', u'', u''],                 38: [u'l', u'', u'l', u'l', u'', u'', u''],                 39: [u'm', u'\n', u'm', u'm', u'', u'', u''],                 40: [u'ù', u'', u'%', u'%', u'', u'', u''],                 41: [u'²', u'', u'', u'', u'', u'', u''],                 43: [u'*', u'', u'µ', u'µ', u'', u'', u''],                 44: [u'w', u'', u'w', u'w', u'', u'', u''],                 45: [u'x', u'', u'x', u'x', u'', u'', u''],                 46: [u'c', u'', u'c', u'c', u'', u'', u''],                 47: [u'v', u'', u'v', u'v', u'', u'', u''],                 48: [u'b', u'', u'b', u'b', u'', u'', u''],                 49: [u'n', u'', u'n', u'n', u'', u'', u''],                 50: [u',', u'', u'?', u'?', u'', u'', u''],                 51: [u';', u'', u'.', u'.', u'', u'', u''],                 52: [u':', u'', u'/', u'/', u'', u'', u''],                 53: [u'!', u'', u'§', u'§', u'', u'', u''],                 57: [u' ', u'', u' ', u' ', u'', u'', u''],                 86: [u'<', u'', u'>', u'>', u'', u'', u''],                 96: [u'\n', u'', u'', u'', u'', u'', u'']             },             'qwerty_us': {                 # [normal, lctrl, lshft, rshft, lalt, rctrl, ralt]                 2: [u'1', u'', u'!', u'!', u'', u'', u''],                 3: [u'2', u'', u'@', u'@', u'', u'', u''],                 4: [u'3', u'', u'#', u'#', u'', u'', u''],                 5: [u'4', u'', u'$', u'$', u'', u'', u''],                 6: [u'5', u'', u'%', u'%', u'', u'', u''],                 7: [u'6', u'', u'^', u'^', u'', u'', u''],                 8: [u'7', u'', u'&', u'&', u'', u'', u''],                 9: [u'8', u'', u'*', u'*', u'', u'', u''],                 10: [u'9', u'', u'(', u'(', u'', u'', u''],                 11: [u'0', u'', u')', u')', u'', u'', u''],                 12: [u'-', u'', u'_', u'_', u'', u'', u''],                 13: [u'=', u'', u'+', u'+', u'', u'', u''],                 15: [u'\t', u'', u'', u'', u'', u'', u''],                 16: [u'q', u'', u'q', u'q', u'', u'', u''],                 17: [u'w', u'', u'w', u'w', u'', u'', u''],                 18: [u'e', u'', u'e', u'e', u'', u'', u''],                 19: [u'r', u'', u'r', u'r', u'', u'', u''],                 20: [u't', u'', u't', u't', u'', u'', u''],                 21: [u'y', u'', u'y', u'y', u'', u'', u''],                 22: [u'u', u'', u'u', u'u', u'', u'', u''],                 23: [u'i', u'', u'i', u'i', u'', u'', u''],                 24: [u'o', u'', u'o', u'o', u'', u'', u''],                 25: [u'p', u'', u'p', u'p', u'', u'', u''],                 26: [u'[', u'', u'{', u'{', u'', u'', u''],                 27: [u']', u'', u'}', u'}', u'', u'', u''],                 28: [u'\n', u'', u'', u'', u'', u'', u''],                 30: [u'a', u'', u'a', u'a', u'', u'', u''],                 31: [u's', u'', u's', u's', u'', u'', u''],                 32: [u'd', u'', u'd', u'd', u'', u'', u''],                 33: [u'f', u'', u'f', u'f', u'', u'', u''],                 34: [u'g', u'', u'g', u'g', u'', u'', u''],                 35: [u'h', u'', u'h', u'h', u'', u'', u''],                 36: [u'j', u'', u'j', u'j', u'', u'', u''],                 37: [u'k', u'', u'k', u'k', u'', u'', u''],                 38: [u'l', u'', u'l', u'l', u'', u'', u''],                 39: [u';', u'', u':', u':', u'', u'', u''],                 40: [u'\'', u'', u'"', u'"', u'', u'', u''],                 41: [u'`', u'', u'~', u'~', u'', u'', u''],                 43: [u'\\', u'', u'|', u'|', u'', u'', u''],                 44: [u'z', u'', u'z', u'z', u'', u'', u''],                 45: [u'x', u'', u'x', u'x', u'', u'', u''],                 46: [u'c', u'', u'c', u'c', u'', u'', u''],                 47: [u'v', u'', u'v', u'v', u'', u'', u''],                 48: [u'b', u'', u'b', u'b', u'', u'', u''],                 49: [u'n', u'', u'n', u'n', u'', u'', u''],                 50: [u'm', u'\n', u'm', u'm', u'', u'', u''],                 51: [u',', u'', u'<', u'<', u'', u'', u''],                 52: [u'.', u'', u'>', u'>', u'', u'', u''],                 53: [u'/', u'', u'?', u'?', u'', u'', u''],                 57: [u' ', u'', u' ', u' ', u'', u'', u''],                 96: [u'\n', u'', u'', u'', u'', u'', u'']             }         }         self.eol = [(0, 28), (0, 96), (29, 39)]          self.layout = layout          self.device = none         devices = map(inputdevice, list_devices())         device in devices:             if device_name in device.name:                 self.device = inputdevice(device.fn)                 print('lecteur de codes-barres : ' + device.name)                 break          self._listeners = []         interruptable.__init__(self)         self.device.grab()      def start_capture(self):         """todo"""          def run():             barcode = ''             modifier = 0             keycode = 0             while not self.interrupted():                 select([self.device], [], [], 0.25)                 try:                     event in self.device.read():                             if event.type == ecodes.ev_key:                                 data = categorize(event)                                 if data.keystate == 1:                                     if data.scancode in self.modifiers:                                         modifier = data.scancode                                     elif data.scancode in self.layouts[self.layout]:                                         keycode = data.scancode                             elif event.type == ecodes.ev_syn:                                 if (modifier, keycode) in self.eol:                                     if len(barcode) > 0:                                         listener in self._listeners:                                             listener(barcode)                                         barcode = ''                                 elif keycode != 0:                                     barcode += self.layouts[self.layout][keycode][self.modifiers[modifier]]                                 modifier = 0                                 keycode = 0                 except blockingioerror:                     pass             self.device.ungrab()          thread = threading.thread(target=run, name='barcode_scanner')         thread.start()      def register_listener(self, callback):         self._listeners.append(callback) 

Comments