def __init__(self, barcode_table, image_frame, options, to_run_on_table_clicked): super(ScanRecordTable, self).__init__() # Read the store from file self._store = Store(options.store_directory.value(), options.store_capacity, FileManager()) self._options = options self._barcodeTable = barcode_table self._imageFrame = image_frame self.setTitle("Scan Records") self._init_ui(to_run_on_table_clicked) self._load_store_records()
def __init__(self, barcode_table, image_frame, options): super(ScanRecordTable, self).__init__() # Read the store from file store_writer = StoreWriter(options.get_store_directory(), "store") store_loader = StoreLoader(options.get_store_directory(), "store") self._store = Store(store_writer, store_loader.load_records_from_file()) self._options = options self._barcodeTable = barcode_table self._imageFrame = image_frame self.setTitle("Scan Records") self.setMaximumWidth(730) self._init_ui() self._load_store_records()
class ScanRecordTable(QGroupBox): """ GUI component. Displays a list of previous scan results. Selecting a scan causes details of the scan to appear in other GUI components (list of barcodes in the barcode table and image of the puck in the image frame). """ COLUMNS = [ 'Date', 'Time', 'Plate Barcode', 'Plate Type', 'Valid', 'Invalid', 'Empty' ] def __init__(self, barcode_table, image_frame, options, to_run_on_table_clicked): super(ScanRecordTable, self).__init__() # Read the store from file self._store = Store(options.store_directory.value(), options.store_capacity, FileManager()) self._options = options self._barcodeTable = barcode_table self._imageFrame = image_frame self.setTitle("Scan Records") self._init_ui(to_run_on_table_clicked) self._load_store_records() def _init_ui(self, to_run_on_table_clicked): # Create record table - lists all the records in the store self._table = QTableWidget() self._table.setFixedWidth(440) self._table.setFixedHeight(600) self._table.setColumnCount(len(self.COLUMNS)) self._table.setHorizontalHeaderLabels(self.COLUMNS) self._table.setColumnWidth(0, 70) self._table.setColumnWidth(1, 55) self._table.setColumnWidth(2, 85) self._table.setColumnWidth(3, 70) self._table.setColumnWidth(4, 45) self._table.setColumnWidth(5, 50) self._table.setColumnWidth(6, 45) self._table.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) self._table.cellPressed.connect(to_run_on_table_clicked) self._table.cellPressed.connect(self._record_selected) # Delete button - deletes selected records btn_delete = QtGui.QPushButton('Delete') btn_delete.setToolTip('Delete selected scan/s') btn_delete.resize(btn_delete.sizeHint()) btn_delete.clicked.connect(self._delete_selected_records) hbox = QHBoxLayout() hbox.setSpacing(10) hbox.addWidget(btn_delete) hbox.addStretch(1) vbox = QVBoxLayout() vbox.addWidget(self._table) vbox.addLayout(hbox) self.setLayout(vbox) def add_record_frame(self, holder_barcode, plate, holder_img, pins_img): """ Add a new scan frame - creates a new record if its a new puck, else merges with previous record""" self._store.merge_record(holder_barcode, plate, holder_img, pins_img) self._load_store_records() if self._options.scan_clipboard.value(): self._barcodeTable.copy_to_clipboard() def _load_store_records(self): """ Populate the record table with all of the records in the store. """ self._table.clearContents() self._table.setRowCount(self._store.size()) for n, record in enumerate(self._store.records): items = [ record.date, record.time, record.holder_barcode, record.plate_type, record.num_valid_barcodes, record.num_unread_slots, record.num_empty_slots ] if (record.num_valid_barcodes + record.num_empty_slots) == record.num_slots: color = self._options.col_ok() else: color = self._options.col_bad() color.a = 192 for m, item in enumerate(items): new_item = QtGui.QTableWidgetItem(str(item)) new_item.setBackgroundColor(color.to_qt()) new_item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) self._table.setItem(n, m, new_item) # Display the first (most recent) record self._table.setCurrentCell(0, 0) self._record_selected() def _record_selected(self): """ Called when a row is selected, causes details of the selected record to be displayed (list of barcodes in the barcode table and image of the scan in the image frame). """ try: row = self._table.selectionModel().selectedRows()[0].row() record = self._store.get_record(row) self._barcodeTable.populate(record.holder_barcode, record.barcodes) marked_image = record.marked_image(self._options) self._imageFrame.display_puck_image(marked_image) except IndexError: self._barcodeTable.clear() self._imageFrame.clear_frame( "Record table empty\nNothing to display") def _delete_selected_records(self): """ Called when the 'Delete' button is pressed. Deletes all of the selected records (and the associated images) from the store and from disk. Asks for user confirmation. """ # Display a confirmation dialog to check that user wants to proceed with deletion quit_msg = "This operation cannot be undone.\nAre you sure you want to delete these record/s?" reply = QtGui.QMessageBox.warning(self, 'Confirm Delete', quit_msg, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) # If yes, find the appropriate records and delete them if reply == QtGui.QMessageBox.Yes: rows = self._table.selectionModel().selectedRows() records_to_delete = [] for row in rows: index = row.row() record = self._store.get_record(index) records_to_delete.append(record) self._store.delete_records(records_to_delete) self._load_store_records() def is_latest_holder_barcode(self, holder_barcode): return self._store.is_latest_holder_barcode(holder_barcode)
def _create_empty_store(self): return Store(self._store_writer, [])
def _create_store_with_records(self, records): return Store(self._store_writer, records)
def _create_store(self): return Store(self._store_writer, self._get_records())
# SHOULD BE OPEN CV 2.4.10 # Directory storing all of the test images from dls_util.shape import Point TEST_IMG_DIR = 'tests/test-resources/blue_stand/' CONFIG_FILE = os.path.join(TEST_IMG_DIR, "system_test_config.ini") FILE_MANAGER = FileManager() OPTIONS = BarcodeConfig(CONFIG_FILE, FILE_MANAGER) # Clear store before creating a new one store_dir = OPTIONS.store_directory.value() if os.path.isdir(store_dir): shutil.rmtree(store_dir) STORE = Store(store_dir, OPTIONS.store_capacity, FILE_MANAGER) def test_generator(): TEST_CASES = generate_test_cases() for params in TEST_CASES: yield run_scans, params[0], params[1] def run_scans(img_file, expected_codes): filepath = os.path.join(TEST_IMG_DIR, img_file) print(img_file) cv_image = Image.from_file(filepath) gray_image = cv_image.to_grayscale() results = GeometryScanner("Unipuck", [14]).scan_next_frame(gray_image, is_single_image=True) plate = results.plate() if plate != None: for expected_code in expected_codes:
# SHOULD BE OPEN CV 2.4.10 # Directory storing all of the test images from dls_util.shape import Point TEST_IMG_DIR = 'tests/test-resources/blue_stand/' CONFIG_FILE = os.path.join(TEST_IMG_DIR, "system_test_config.ini") FILE_MANAGER = FileManager() OPTIONS = BarcodeConfig(CONFIG_FILE, FILE_MANAGER) # Clear store before creating a new one store_dir = OPTIONS.store_directory if os.path.isdir(store_dir.value()): shutil.rmtree(store_dir.value()) comms_manger = StoreWriter(OPTIONS.get_store_directory(), "store") STORE = Store(comms_manger, MagicMock) def test_generator(): TEST_CASES = generate_test_cases() for params in TEST_CASES: yield run_scans, params[0], params[1] def run_scans(img_file, expected_codes): filepath = os.path.join(TEST_IMG_DIR, img_file) print(img_file) cv_image = Image.from_file(filepath) gray_image = cv_image.to_grayscale() results = GeometryScanner("Unipuck", [14]).scan_next_frame(gray_image,
def _create_store(self): return Store(self._directory, self._store_capacity, self._file_manager)