Пример #1
0
 def execute(self, settings: Settings) -> bool:
     self.loadSetiings(settings)
     if self.exec() != QDialog.Accepted:
         return False
     self.saveSetiings(settings)
     settings.write()
     return True
Пример #2
0
class Application:
    def __init__(self):
        self.title = u'Tracks detection'
        # Настройки
        self.settings = Settings()

    def application_init(self):
        '''Инициализация Qt приложения'''
        # Создание приложение
        self.qapp = QApplication(sys.argv)
        self.__app_working_status = True
        # Установка локлизатора
        translator = QTranslator(self.qapp)
        translator.load('lang/tr_ru', os.path.dirname(__file__))
        self.qapp.installTranslator(translator)

        self.mainDialog = MainDialog(self, self.title)
        self.mainDialog.closeApp.connect(self.__finalize_before_quit)

        self.controls = {
            'step': ['X', 'Y', 'Z', 'A'],
            'servo': ['B', 'C'],
            'pins': {
                'P1': [],
                'P2': ['UV', 'VIS']
            }
        }

        self.mainDialog.show()
        self.project_init()
        self.gui_init()
        self.communication_init()

        sys.exit(self.qapp.exec_())

    def __finalize_before_quit(self):
        self.__app_working_status = False
        if self.grbl.connection: self.grbl.connection.close()
        if self.communication_thread: self.communication_thread.join()
        self.qapp.exit()

    def retuenicon(self, name):
        return QIcon(
            QPixmap(
                os.path.normpath(
                    os.path.join(os.path.dirname(os.path.realpath(__file__)),
                                 '', name + '.png'))))

    def project_init(self):
        self.project = Project('New')

    def async_sleep(self, sleep):
        for i in range(sleep):
            time.sleep(1)
            if not self.__app_working_status: break

    def __connection_worker(self):
        while self.__app_working_status:
            status = self.__current_conacion_procedure()
            if status: break
            if status:
                self.__current_conacion_procedure = self.grbl.getStatus
            else:
                self.__current_conacion_procedure = self.__auto_seach__
            self.async_sleep(5)
            self.cnc_indicator.setStatus(status)

    def communication_init(self):
        self.grbl = GRBL(HOST=self.settings.grblip)
        self.__current_conacion_procedure = self.__auto_seach__
        self.communication_thread = threading.Thread(
            target=self.__connection_worker)
        self.communication_thread.setDaemon(True)
        self.communication_thread.start()

    def gui_init(self):

        pref_menu = menu_item(u'Preferences')
        ref_menu = menu_item(u'Reference')
        gen_menu = menu_item(u'Device')

        gen_menu.addChildren(menu_item(u'GRBL', self.showGrblDialog))

        file_menu = menu_item(self.qapp.tr(u'File'))
        file_menu.addChildren(menu_item(u'New', self.newProject),
                              menu_item(u'Open', self.openProject),
                              menu_item(u'Import...', self.openFile),
                              menu_item(u'Save', self.saveProject),
                              menu_item(u'Exit', self.qapp.exit))

        pref_menu.addChildren(gen_menu, menu_item(u'Settings'))

        ref_menu.addChildren(menu_item(u'Help'),
                             menu_item(u'About', self.showAbout))

        self.mainDialog.addMenuItems(file_menu, pref_menu, ref_menu)

        self.cnc_indicator = work_indicator(u'CNC')
        self.mainDialog.addStatusObj(self.cnc_indicator)

        self.progressBar = QProgressBar()
        self.progressBar.setTextVisible(True)
        self.progressBar.setAlignment(Qt.AlignCenter)
        self.progressBar.minimum = 1
        self.progressBar.maximum = 100
        self.mainDialog.addPermanentStatusObj(self.progressBar)
        '''Инициализациия таблицы содержания'''
        treeDock = QDockWidget(self.qapp.tr(u'Project tree'), self.mainDialog)
        treeDock.setAllowedAreas(Qt.LeftDockWidgetArea
                                 | Qt.RightDockWidgetArea)
        self.mainDialog.addDockWidget(Qt.LeftDockWidgetArea, treeDock)

        self.mainnodes = [Node("Samples"), Node("Other")]
        self.project_tree = ProjectTree(self, self.mainnodes)
        self.project_tree.doubleClicked.connect(self.on_tree_clicked)
        treeDock.setWidget(self.project_tree)
        '''Инициализациия центра'''
        jog = JogWidget(app=self.qapp,
                        axies=self.controls,
                        pinAcions=self.pinAcions,
                        motorActions=self.send_to_grbl)
        self.mainDialog.addToCenter(jog)
        jog.raise_()

    def send_to_grbl(self, text, send_type):
        if len(text):
            self.grbl.send_task(text, send_type)

    def pinAcions(self, status, pin):
        task = 'M62 {pin}'.format(pin=pin) if status else 'M63 {pin}'.format(
            pin=pin)
        self.grbl.send_task(task, SENDTYPE.IDLE)

    def setProgress(self, step, steps):
        value = step / float(len(steps)) * 100.
        indx = int(ceil(step - 1))
        text = self.qapp.tr(steps[indx])
        self.progressBar.setFormat("{0} - {1}%".format(text, round(value, 0)))
        self.progressBar.setValue(value)
        self.qapp.processEvents()

    def on_tree_clicked(self, index):
        item = self.project_tree.selectedIndexes()[0]
        if self.project.current_sample != item.model().itemFromIndex(
                index).obj:
            self.project.current_sample = item.model().itemFromIndex(index).obj
            self.refresh()

    def newProject(self):
        self.mainDialog.PreparedArea.clear()
        self.mainDialog.ThroughArea.clear()
        self.mainDialog.BacklightArea.clear()
        self.mainnodes = [Node("Samples"), Node("Other")]
        self.project_tree.setMainNodes(self.mainnodes)
        self.project = Project('TEMP')
        self.refresh()

    def openProject(self):

        fileName, _ = QFileDialog.getOpenFileName(
            self.mainDialog, self.qapp.tr("Load project"), ".\\",
            self.qapp.tr("Project file (*.tpr)"))

        infile = open(fileName, 'rb')
        self.project = pickle.load(infile)
        infile.close()

        self.mainDialog.PreparedArea.clear()
        self.mainDialog.ThroughArea.clear()
        self.mainDialog.BacklightArea.clear()
        self.mainnodes = [Node("Samples"), Node("Other")]
        self.project_tree.setMainNodes(self.mainnodes)
        self.refresh()

    def saveProject(self):
        fileName, _ = QFileDialog.getSaveFileName(
            self.mainDialog, self.qapp.tr("Save project"), ".\\",
            self.qapp.tr("Project file (*.tpr)"))
        outfile = open(fileName, "wb")
        pickle.dump(self.project, outfile)
        outfile.close()

    def draw_tree(self):
        target = self.mainnodes[0]
        children = target.children()
        samples_in_tree = []

        for sample in self.project.samples.get_sorted_by_id():
            if len(children) > 0:
                samples_in_tree = [node.obj for node in children]
            if sample not in samples_in_tree:
                target.addChild(Node(sample))

        self.project_tree.refresh()

    def openFile(self):
        path_to_file, _ = QFileDialog.getOpenFileName(
            self.mainDialog, self.qapp.tr("Load Image"),
            self.qapp.tr(u".\example_imgs"), self.qapp.tr("Images (*.jpg)"))
        # path_to_file, _ = QFileDialog.getOpenFileName(self.mainDialog, self.app.tr("Load Image"), self.app.tr("~/Desktop/"), self.app.tr("Images (*.jpg)"))

        # Определяем тип файла на просвет или на подсветку
        tools.processing(path_to_file, self.project, self.separator,
                         self.segmentation, self.counter, self.setProgress)
        self.refresh()

    def refresh(self):
        self.draw_tree()
        self.fill_table()
        self.updete_viewers()

    def fill_table(self):
        data = []
        sample = self.project.current_sample

        if not sample:
            data = [['', '', '']]
            self.mainDialog.tablemodel.setData(data)
            return

        for track in sample.tracks.get_sorted():
            data.append([str(track.id), str(track.count), str(track.area)])

        self.mainDialog.tablemodel.setData(data)
        self.mainDialog.table.resizeRowsToContents()
        self.mainDialog.table.resizeColumnsToContents()

        count = round(
            np.sum([track.count
                    for track in sample.tracks.get_sorted_by_id()]), 2)
        general_area = round(
            np.sum([track.area for track in sample.tracks.get_sorted_by_id()]),
            2)

        self.mainDialog.infolabel.setText('''
                        <p align="center">General tracks count<br>{tracks_count}</p>
                        <p align="center">General tracks area (%)<br>{general_area}</p>
                        '''.format(tracks_count=count,
                                   general_area=general_area))

    def draw_objects(self, viewer, sample):
        for track in sample.tracks.get_sorted():
            viewer.add_rect(track.left, track.rigth, track.top, track.bottom)
            viewer.add_Polygon(track.contour, track.left, track.top)
            text = 'Count: {tracks_count}\nArea (%): {general_area}'.format(
                tracks_count=track.count, general_area=track.area)

            viewer.add_Text(text, track.left, track.top)

    def updete_viewers(self):
        sample = self.project.current_sample

        if not sample:
            return

        self.mainDialog.ThroughArea.load_image(sample.through)
        self.mainDialog.BacklightArea.load_image(sample.backlight)
        self.mainDialog.PreparedArea.load_image(sample.prepared)

        self.draw_objects(self.mainDialog.ThroughArea, sample)
        self.draw_objects(self.mainDialog.BacklightArea, sample)
        self.draw_objects(self.mainDialog.PreparedArea, sample)

    def __connect_to_grbl__(self):
        '''Функция подключения к CNC сканера, которая передается в настройки станка'''
        status = self.grbl.connect()
        if not status: return
        self.cnc_indicator.setStatus(-1)
        self.grbl.reset_alarm()
        self.cnc_indicator.setStatus(status)
        return status

    def __check_ip__(self, ip):
        status = False
        test_grbl = GRBL(HOST=self.settings.grblip)
        test_grbl.setHost(ip)
        try:
            status = test_grbl.connect(check=False)
            test_grbl.connection.close()
        except OSError:
            pass
        return ip if status else None

    def __auto_seach__(self, property=None):
        '''Функция авто поиска IP станка
        property нужен, чтобы вернуть результат в inputField окна настроек
        '''
        if self.grbl.connection: self.grbl.connection.close()
        devices = [device for device in os.popen('arp -a')]
        ip_candidates = [
            re.findall(r"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b", device)[0]
            for device in devices if
            len(re.findall(r"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b",
                           device)) != 0
        ]
        if self.settings.grblip in ip_candidates:
            ip_candidates.remove(self.settings.grblip)
            ip_candidates.insert(0, self.settings.grblip)

        pool = ThreadPool(4)
        results = pool.map(self.__check_ip__, ip_candidates)
        index = np.where(results != None)[0][0]
        if not results[index]:
            # print(self.qapp.tr('There is not  devices in current net'))
            return
        pool.close()
        pool.join()

        self.grbl.setHost(results[index])
        self.__connect_to_grbl__()

        if property:
            property.setText(
                results[index]
            )  # property нужен, чтобы вернуть результат в inputField

        self.settings.grblip = results[index]
        self.settings.write()
        print(self.qapp.tr('Connected to') + ' {ip}'.format(ip=results[index]))
        return True

    def showAbout(self):
        about = about_dialog(self)
        about.open()

    def showGrblDialog(self):
        dialog = grblDialog(self,
                            connection_func=self.__connect_to_grbl__,
                            auto_seach_func=self.__auto_seach__)
        dialog.execute(self.settings)