Beispiel #1
0
    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()
Beispiel #2
0
    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()
Beispiel #3
0
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)
Beispiel #4
0
 def _create_empty_store(self):
     return Store(self._store_writer, [])
Beispiel #5
0
 def _create_store_with_records(self, records):
     return Store(self._store_writer, records)
Beispiel #6
0
 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,
Beispiel #9
0
 def _create_store(self):
     return Store(self._directory, self._store_capacity, self._file_manager)