示例#1
0
 def __init__(self, identity_service: IdentityService):
     QMainWindow.__init__(self)
     self.__identity_service = identity_service
     self.__view_cam = None
     self.__video_camera = cv2.VideoCapture()
     self.__detector_cfg = DetectorConfig.instance()
     self.__camera_timer = self.__detector_cfg.get_timer()
     self.ui = Ui_MainWindow()
     self.ui.setupUi(self)
     self.build()
     self.binding()
  def __init__(self, parent=None):
      QtGui.QWidget.__init__(self, parent)
     
      self.ui = Ui_MainWindow()
      self.ui.setupUi(self)
 
      self.table = self.ui.table
      self.canceled = False
   
      self.initializeUi()     
      self.setupSignals()
示例#3
0
class MainWindow(QMainWindow):
    def __init__(self, identity_service: IdentityService):
        QMainWindow.__init__(self)
        self.__identity_service = identity_service
        self.__view_cam = None
        self.__video_camera = cv2.VideoCapture()
        self.__detector_cfg = DetectorConfig.instance()
        self.__camera_timer = self.__detector_cfg.get_timer()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.build()
        self.binding()

    def build(self):
        # screen 0
        self.home_screen = HomeScreen(self.__identity_service, self)
        # screen 1
        self.detection_screen = DetectionConfigScreen(self)
        # screen 2
        self.measurement_screen = MeasurementScreen(self)
        # screen 3
        self.test_detect_pair_screen = TestDetectPairScreen(self)
        # screen 4
        self.color_preprocess_config_screen = ColorPreprocessConfigScreen(self)
        # screen 5
        self.color_param_calib_screen = ColorParamCalibrationScreen(self)
        # screen 6
        self.error_detect_screen = ErrorDetectScreen(self)
        # screen 7
        self.progress_screen = ProgressScreen(self)
        # screen 8
        self.asym_config_screen = AsymConfigScreen(self)
        # screen 9
        self.side_error_detect_screen = SideErrorDetectScreen(self)

        # add to Stacked Widget
        self.ui.centralStackWidget.addWidget(self.home_screen)
        self.ui.centralStackWidget.addWidget(self.detection_screen)
        self.ui.centralStackWidget.addWidget(self.measurement_screen)
        self.ui.centralStackWidget.addWidget(self.test_detect_pair_screen)
        self.ui.centralStackWidget.addWidget(self.asym_config_screen)
        self.ui.centralStackWidget.addWidget(
            self.color_preprocess_config_screen)
        self.ui.centralStackWidget.addWidget(self.color_param_calib_screen)
        self.ui.centralStackWidget.addWidget(self.error_detect_screen)
        self.ui.centralStackWidget.addWidget(self.side_error_detect_screen)
        self.ui.centralStackWidget.addWidget(self.progress_screen)

    def showEvent(self, event):
        return

    # binding
    def binding(self):
        self.ui.actionExit.triggered.connect(self.action_exit_triggered)
        self.ui.actionLoadCfg.triggered.connect(
            self.action_load_config_triggered)
        self.ui.actionSaveCfg.triggered.connect(self.action_save_triggered)
        self.__camera_timer.timeout.connect(self.camera_timer_timeout)
        self.ui.centralStackWidget.currentChanged.connect(
            self.current_stack_widget_changed)

        self.home_screen.action_edit.connect(self.change_detection_screen)
        self.home_screen.action_start.connect(self.change_progress_screen)
        self.home_screen.action_exit.connect(self.action_exit_triggered)

        self.detection_screen.backscreen.connect(self.change_home_screen)
        self.detection_screen.nextscreen.connect(
            self.change_measurement_screen)
        self.detection_screen.captured.connect(self.toggle_capture_state)
        self.detection_screen.camera_changed.connect(self.camera_changed)

        self.measurement_screen.backscreen.connect(
            self.change_detection_screen)
        self.measurement_screen.nextscreen.connect(
            self.skipable_change_detect_pair_screen)
        self.measurement_screen.captured.connect(self.toggle_capture_state)

        self.test_detect_pair_screen.backscreen.connect(
            self.change_measurement_screen)
        self.test_detect_pair_screen.nextscreen.connect(
            self.change_color_preprocess_config_screen)
        self.test_detect_pair_screen.captured.connect(
            self.toggle_capture_state)

        self.color_preprocess_config_screen.backscreen.connect(
            self.change_detect_pair_screen)
        self.color_preprocess_config_screen.nextscreen.connect(
            self.change_asym_config_screen)

        self.asym_config_screen.backscreen.connect(
            self.change_color_preprocess_config_screen)
        self.asym_config_screen.nextscreen.connect(
            self.change_color_param_calib_screen)
        self.asym_config_screen.captured.connect(self.toggle_capture_state)

        self.color_param_calib_screen.backscreen.connect(
            self.change_asym_config_screen)
        self.color_param_calib_screen.nextscreen.connect(
            self.change_error_detect_screen)
        self.color_param_calib_screen.captured.connect(
            self.toggle_capture_state)

        self.error_detect_screen.backscreen.connect(
            self.change_color_param_calib_screen)
        self.error_detect_screen.nextscreen.connect(
            self.change_progress_screen)
        self.error_detect_screen.captured.connect(self.toggle_capture_state)

        self.side_error_detect_screen.backscreen.connect(
            self.change_measurement_screen)
        self.side_error_detect_screen.nextscreen.connect(
            self.change_progress_screen)
        self.side_error_detect_screen.captured.connect(
            self.toggle_capture_state)

        self.progress_screen.return_home.connect(self.change_home_screen)
        return

    def closeEvent(self, event):
        self.__detector_cfg.reset()

    def camera_timer_timeout(self):
        if (self.__view_cam is not None and self.__video_camera is not None
                and self.__video_camera.isOpened()):
            _, image = self.__video_camera.read()
            # test only
            # if image is None:
            #     self.__video_camera.open(Videos.instance().next())
            #     _, image = self.__video_camera.read()
            _, current_cfg = self.__detector_cfg.get_current_cfg()
            frame_width, frame_height = current_cfg[
                "frame_width"], current_cfg["frame_height"]
            image = cv2.resize(image, (frame_width, frame_height))
            self.__view_cam(image)

    # event handler
    def camera_changed(self, index):
        if index is not None and index > -1:
            if (self.__detector_cfg.get_last_camera_uri() !=
                    index) or (not self.__video_camera.isOpened()):
                self.__video_camera.open(index)
                # test only
                # self.__video_camera.open(Videos.instance().next())
                self.__detector_cfg.set_last_camera_uri(index)
        else:
            if self.__view_cam is not None: self.__view_cam(None)
            self.__video_camera.release()

    def action_exit_triggered(self):
        self.close()

    def skipable_change_detect_pair_screen(self):
        idx, cfg = self.__detector_cfg.get_current_cfg()
        continue_screen = cfg["is_main"]
        if continue_screen:
            self.ui.centralStackWidget.setCurrentWidget(
                self.test_detect_pair_screen)
        else:
            err_text = self.side_error_detect_screen.validate_show()
            if err_text is not None:
                helpers.show_message(err_text)
                return
            # skip to screen 6 if only side camera is selected
            self.ui.centralStackWidget.setCurrentWidget(
                self.side_error_detect_screen)

    def change_home_screen(self):
        self.ui.centralStackWidget.setCurrentWidget(self.home_screen)

    def change_detection_screen(self):
        self.ui.centralStackWidget.setCurrentWidget(self.detection_screen)

    def change_measurement_screen(self):
        self.ui.centralStackWidget.setCurrentWidget(self.measurement_screen)

    def change_detect_pair_screen(self):
        self.ui.centralStackWidget.setCurrentWidget(
            self.test_detect_pair_screen)

    def change_color_preprocess_config_screen(self):
        self.ui.centralStackWidget.setCurrentWidget(
            self.color_preprocess_config_screen)

    def change_color_param_calib_screen(self):
        self.ui.centralStackWidget.setCurrentWidget(
            self.color_param_calib_screen)

    def change_error_detect_screen(self):
        self.ui.centralStackWidget.setCurrentWidget(self.error_detect_screen)

    def change_progress_screen(self):
        err_mess = self.progress_screen.validate_show()
        if err_mess is not None:
            helpers.show_message(err_mess)
            return
        self.__video_camera.release()
        self.stop_capture()
        self.ui.centralStackWidget.setCurrentWidget(self.progress_screen)

    def change_asym_config_screen(self):
        self.ui.centralStackWidget.setCurrentWidget(self.asym_config_screen)

    def current_stack_widget_changed(self):
        currentWidget = self.ui.centralStackWidget.currentWidget()

        def __change_view_cam(func):
            self.__view_cam = func
            self.__view_cam(None)

        def __remove_view_cam():
            self.__view_cam = None

        if hasattr(currentWidget, 'view_cam'):
            __change_view_cam(currentWidget.view_cam)
        else:
            __remove_view_cam()

    def stop_capture(self):
        self.__camera_timer.stop()

    def start_capture(self):
        if (not self.__camera_timer.isActive()):
            # start timer
            self.__camera_timer.start(20)

    def toggle_capture_state(self):
        if self.__camera_timer.isActive():
            self.__camera_timer.stop()
        else:
            self.__camera_timer.start(20)

    @asyncSlot()
    async def action_load_config_triggered(self):
        url = helpers.file_chooser_open_directory(self)
        if url.isEmpty(): return
        file_path = url.toLocalFile()
        self.stop_capture()
        self.__detector_cfg.reset()
        manager = FQCSManager(config_folder=file_path)
        configs = manager.get_configs()
        for cfg in configs:
            if cfg["is_main"] == True:
                self.__detector_cfg.set_current_cfg_name(cfg["name"])
                try:
                    await manager.load_model(cfg)
                except:
                    helpers.show_message("Error loading model")
                break
        self.__detector_cfg.set_manager(manager)
        self.__detector_cfg.set_current_path(file_path)
        self.__detector_cfg.manager_changed.emit()
        self.change_home_screen()

    def action_save_triggered(self):
        manager = self.__detector_cfg.get_manager()
        configs = manager.get_configs()
        if configs is not None:
            url = helpers.file_chooser_open_directory(self)
            if url.isEmpty(): return
            file_path = url.toLocalFile()
            manager.save_config(file_path)
            self.__detector_cfg.set_current_path(file_path)
        else:
            print("No config provided")
class MainWindowController(QtGui.QWidget):
    # UI and signal setup
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
       
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
   
        self.table = self.ui.table
        self.canceled = False
     
        self.initializeUi()     
        self.setupSignals()
    
    def initializeUi(self):
        self.setWindowState(QtCore.Qt.WindowMaximized)
        self.table.initialize()
        
    def setupSignals(self):
        self.ui.pushButtonAddGame.clicked.connect(self.add_game_clicked)
        self.ui.pushButtonRemoveGame.clicked.connect(self.remove_game_clicked)
        self.ui.pushButtonLoadBacklog.clicked.connect(self.load_backlog_clicked)
        self.ui.pushButtonSaveBacklog.clicked.connect(self.save_backlog_clicked)
        self.ui.pushButtonReloadScores.clicked.connect(self.reload_scores_clicked)
        self.ui.pushButtonSortData.clicked.connect(self.sort_data_clicked)
        self.ui.pushButtonFilterData.clicked.connect(self.filter_data_clicked)
        self.ui.lineEditSearchGame.textChanged.connect(self.search_text_changed)
        
    def add_game_clicked(self):
        addGameController = AddGameController(self.table, self)
        addGameController.show()
    
    def remove_game_clicked(self):
        indexes = self.table.selectionModel().selectedRows()
        if len(indexes) > 0:
            actual_indexes = []
            for index in sorted(indexes):
                actual_indexes.append(index.row())
            names = []
            systems = []
            for i in actual_indexes:
                names.append(self.table.item(i,0).text())
                systems.append(self.table.item(i,1).text())
            
            delete_msg = "Are you sure you want to delete the following entries?\n" 
            for i in range(0,min(len(names),10)):
                delete_msg = delete_msg + '\n' + names[i] + ' (' + systems[i] + ')'
            if len(names) > 10:
                delete_msg = delete_msg + '\n...'
            reply = QtGui.QMessageBox.question(self, 'Confirm game removal', 
                             delete_msg, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
        
            if reply == QtGui.QMessageBox.Yes:
                for i in range(len(actual_indexes) - 1, -1, -1):
                    system = self.table.getGameData(actual_indexes[i])[COLUMN_SYSTEM]
                    status = self.table.getGameData(actual_indexes[i])[COLUMN_STATUS]
                    labels = self.table.cellWidget(actual_indexes[i],headers.index(COLUMN_LABELS)).getLabels()
                    self.table.system_list_model.remove(system)
                    self.table.status_list_model.remove(status)
                    for label in labels:
                        self.table.label_list_model.remove(label)
                    self.table.removeRow(actual_indexes[i])
                self.table.changed = True
        else:
            error = QErrorMessage()
            error.showMessage('No games were selected')
            error.setWindowTitle('Remove game')
            error.exec_()
    
    def load_backlog_clicked(self):
        confirm = False
        if self.table.changed:
            confirm = self.showConfirmDialog()
        if confirm or not self.table.changed:    
            self.ui.lineEditSearchGame.setText('')            
            
            fileName = QtGui.QFileDialog.getOpenFileName(self, 'Load backlog', '', '*.blg')
            if fileName:
                self.table.system_list_model.clear()
                self.table.status_list_model.clear()
                self.table.label_list_model.clear()
                for i in reversed(range(self.table.rowCount())):
                    self.table.removeRow(i)
                with open(fileName, 'r') as fp:
                    reader = csv.reader(fp, delimiter=',',quoting=csv.QUOTE_ALL)
                    rows = sum(1 for row in reader)
                    fp.seek(0)
                    progress = QProgressDialog("Loading backlog", "", 0, rows, self)
                    progress.setCancelButton(None)
                    progress.setWindowModality(QtCore.Qt.WindowModal)
                    i = 0
                    self.table.setRowCount(rows)
                    self.table.loading = True
                    for row in reader:
                        row_dict = dict()
                        for j in range(0,len(headers)): 
                            row_dict[headers[j]] = row[j]
                        self.table.addGameRow(row_dict, i)
                        progress.setValue(i+1)
                        i = i + 1
                    self.table.changed = False
                    self.table.loading = False
                    self.table.resizeColumns()
    
    def save_backlog_clicked(self):
        if not self.checkEmpty():
            fileName = QtGui.QFileDialog.getSaveFileName(self, 'Save backlog', '', '*.blg')
            if fileName:
                with open(fileName, 'w') as fp:
                    writer = csv.writer(fp, delimiter=',',lineterminator='\n',quoting=csv.QUOTE_ALL)
                    rows = self.table.rowCount()
                    progress = QProgressDialog("Saving backlog", "", 0, rows, self)
                    progress.setCancelButton(None)
                    progress.setWindowModality(QtCore.Qt.WindowModal)
                    for i in range(0,rows):
                        data = self.table.getGameData(i)
                        data_list = []
                        for h in headers: 
                            data_list.append(str(data[h]))
                        writer.writerows([data_list])
                        progress.setValue(i+1)
                    self.table.changed = False
    
    def reload_scores_clicked(self):
        if not self.checkEmpty():
            self.table.reload_scores()
    
    def sort_data_clicked(self):
        if not self.checkEmpty():
            sgc = SortGamesController(self.table, self)
            sgc.exec_()
            sgc.applySorting()
    
    def filter_data_clicked(self):
        if not self.checkEmpty():
            fgc = FilterGamesController(self.table, self)
            fgc.exec_()
            fgc.applyFiltering()
    
    def search_text_changed(self):
        search_text = str(self.ui.lineEditSearchGame.text()).lower()
        self.table.hide_rows_search(search_text)

    def checkEmpty(self):
        empty = self.table.rowCount() == 0
        if empty:
            error = QErrorMessage()
            error.showMessage('Add some games first!')
            error.setWindowTitle('No games')
            error.exec_()
        return(empty)
        
    def showConfirmDialog(self):
        reply = QtGui.QMessageBox.question(self, 'Confirm action', 
                     "Your data changed since you loaded it. Are you sure you want to do this?", 
                     QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
        return reply == QtGui.QMessageBox.Yes                     

    def closeEvent(self, event):
        confirm = False
        if self.table.changed:
            confirm = self.showConfirmDialog()
        if confirm or not self.table.changed:
            event.accept()
        else:
            event.ignore()