11import multiprocessing
22import queue
3+ import time
34
45from PyQt4 import QtGui , QtCore
56
67from dls_barcode .config import BarcodeConfig , BarcodeConfigDialog
7- from dls_barcode .camera import CameraScanner , CameraSwitch
8+ from dls_barcode .camera import CameraScanner , CameraSwitch , NoNewBarcodeMessage
89from dls_util import Beeper
910from dls_util .file import FileManager
10- from dls_util .message import MessageType , Message
1111from .barcode_table import BarcodeTable
1212from .image_frame import ImageFrame
1313from .record_table import ScanRecordTable
14- from .message_display import MessageDisplay
14+ from .message_box import MessageBox
15+ from .message_factory import MessageFactory
16+
17+
18+ RESULT_TIMER_PERIOD = 1000 # ms
19+ VIEW_TIMER_PERIOD = 1 # ms
20+ MESSAGE_TIMER_PERIOD = 1 # ms
1521
1622
1723class DiamondBarcodeMainWindow (QtGui .QMainWindow ):
@@ -39,19 +45,20 @@ def __init__(self, config_file):
3945 self ._view_queue = multiprocessing .Queue ()
4046 self ._message_queue = multiprocessing .Queue ()
4147 self ._initialise_scanner ()
48+ self ._reset_msg_timer ()
4249
4350 # Timer that controls how often new scan results are looked for
4451 self ._result_timer = QtCore .QTimer ()
4552 self ._result_timer .timeout .connect (self ._read_result_queue )
46- self ._result_timer .start (1000 )
53+ self ._result_timer .start (RESULT_TIMER_PERIOD )
4754
4855 self ._view_timer = QtCore .QTimer ()
4956 self ._view_timer .timeout .connect (self ._read_view_queue )
50- self ._view_timer .start (1 )
57+ self ._view_timer .start (VIEW_TIMER_PERIOD )
5158
5259 self ._message_timer = QtCore .QTimer ()
5360 self ._message_timer .timeout .connect (self ._read_message_queue )
54- self ._message_timer .start (1 )
61+ self ._message_timer .start (MESSAGE_TIMER_PERIOD )
5562
5663 self ._camera_switch .restart_live_capture_from_side ()
5764
@@ -74,8 +81,8 @@ def _init_ui(self):
7481 self ._record_table = ScanRecordTable (self ._barcode_table , self ._image_frame , self ._config , self .on_record_table_clicked )
7582
7683 # Message display
77- self ._message_display = MessageDisplay ()
78- self ._message_display .setFixedHeight (64 )
84+ self ._message_box = MessageBox ()
85+ self ._message_box .setFixedHeight (64 )
7986
8087 # Open options first to make sure the cameras are set up correctly.
8188 # Start live capture of the side as soon as the dialog box is closed
@@ -89,7 +96,7 @@ def _init_ui(self):
8996
9097 img_vbox = QtGui .QVBoxLayout ()
9198 img_vbox .addWidget (self ._image_frame )
92- img_vbox .addWidget (self ._message_display )
99+ img_vbox .addWidget (self ._message_box )
93100 hbox .addLayout (img_vbox )
94101
95102 vbox = QtGui .QVBoxLayout ()
@@ -185,20 +192,46 @@ def _camera_capture_alive(self):
185192 return self ._camera_scanner is not None and self ._camera_switch is not None
186193
187194 def _read_view_queue (self ):
188- if not self ._view_queue .empty ():
189- try :
190- image = self ._view_queue .get (False )
191- self ._image_frame .display_puck_image (image )
192- except queue .Empty :
193- pass
195+ if self ._view_queue .empty ():
196+ return
197+
198+ try :
199+ image = self ._view_queue .get (False )
200+ except queue .Empty :
201+ return
202+
203+ self ._image_frame .display_puck_image (image )
194204
195205 def _read_message_queue (self ):
196- if not self ._message_queue .empty ():
197- try :
198- message = self ._message_queue .get (False )
199- self ._message_display .display_message (message )
200- except queue .Empty :
201- return
206+ if self ._message_queue .empty ():
207+ return
208+
209+ try :
210+ scanner_msg = self ._message_queue .get (False )
211+ except queue .Empty :
212+ return
213+
214+ if self ._camera_switch .is_side () and isinstance (scanner_msg , NoNewBarcodeMessage ):
215+ if not self ._msg_timer_is_running ():
216+ # The result queue is read at a slower rate - use a timer to give it time to process a new barcode
217+ self ._start_msg_timer ()
218+ elif self ._has_msg_timer_timeout ():
219+ self ._message_box .display (MessageFactory .duplicate_barcode_message ())
220+ else :
221+ self ._reset_msg_timer ()
222+ self ._message_box .display (MessageFactory .from_scanner_message (scanner_msg ))
223+
224+ def _reset_msg_timer (self ):
225+ self ._duplicate_msg_timer = None
226+
227+ def _start_msg_timer (self ):
228+ self ._duplicate_msg_timer = time .time ()
229+
230+ def _msg_timer_is_running (self ):
231+ return self ._duplicate_msg_timer is not None
232+
233+ def _has_msg_timer_timeout (self ):
234+ return self ._msg_timer_is_running () and time .time () - self ._duplicate_msg_timer > 2 * RESULT_TIMER_PERIOD / 1000
202235
203236 def _read_result_queue (self ):
204237 """ Called every second; read any new results from the scan results queue, store them and display them.
@@ -222,17 +255,19 @@ def _read_side_scan(self):
222255
223256 # Barcode successfully read
224257 Beeper .beep ()
225- print ("MAIN: holder barcode recorded" )
258+ print ("MAIN: puck barcode recorded" )
226259 if self ._record_table .unique_side_barcode (plate ): # if new side barcode
227260 self .original_plate = plate
228261 self ._latest_holder_image = holder_image
229- self ._message_display . display_message ( Message ( MessageType . INFO , "Plate barcode recorded" ))
262+ self ._message_box . display ( MessageFactory . puck_recorded_message ( ))
230263 self ._camera_switch .restart_live_capture_from_top ()
264+ else :
265+ self ._message_box .display (MessageFactory .duplicate_barcode_message ())
231266
232267 def _read_top_scan (self ):
233268 if self ._result_queue .empty ():
234269 if self ._camera_switch .is_top_scan_timeout ():
235- self ._message_display . display_message ( Message ( MessageType . INFO , "Scan timeout" , lifetime = 4 ))
270+ self ._message_box . display ( MessageFactory . scan_timeout_message ( ))
236271 print ("\n *** Scan timeout ***" )
237272 self ._camera_switch .restart_live_capture_from_side ()
238273 return
@@ -248,6 +283,6 @@ def _read_top_scan(self):
248283 # Barcodes successfully read
249284 Beeper .beep ()
250285 print ("Scan Completed" )
251- self ._message_display . display_message ( Message ( MessageType . INFO , "Scan completed" ))
286+ self ._message_box . display ( MessageFactory . scan_completed_message ( ))
252287 self ._camera_switch .restart_live_capture_from_side ()
253288
0 commit comments