我有一个模块可以捕获条形码扫描仪的所有读数。 我的问题是我无法正确关闭它。 发送KeyboardInterrupt或SystemExit信号后,它仅在我扫描条形码时停止。
我尝试将此方法添加到BarcodeScanner类中,但它仍然无效:
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)
我该怎么做?
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 -*
from evdev import InputDevice, ecodes, list_devices, categorize
import signal, sys
import threading
from time import sleep
from 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())
for 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
for 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:
for 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)
答案 0 :(得分:1)
我通过select()+ read()循环替换read_loop()方法解决了这个问题。通过这种方式,我可以对select进行超时。
#!/usr/bin/env python3
# -*-coding:Utf-8 -*
from evdev import InputDevice, ecodes, list_devices, categorize
from select import select
import signal, sys
import threading
from time import sleep
from 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())
for 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:
for 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:
for 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)