Ejemplo n.º 1
0
    def run_about(self):
        """Run method for the about dialog"""
        dlgAbout = AboutDialog()
        if dlgAbout.exec_():
            pass

        dlgAbout.deleteLater()
        # Refresh QGIS
        QCoreApplication.processEvents()
Ejemplo n.º 2
0
 def open_about_dialog(self):
     """Метод открытия окна "О программе" """
     self.about = AboutDialog(flags=Q_FLAGS())
     self.about.show()
Ejemplo n.º 3
0
class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.ui = UiMainWindow()
        self.ui.setup_ui(self)

        self.idx_func = 1
        self.parameters = None
        self.func = None
        self.save_file_name = ""
        self.settings_window = None

        self.function_types = [
            "feldbaum_function", "hyperbolic_potential_abs",
            "exponential_potential"
        ]

        # графики
        self.graph_3d = None
        self.contour_graph = None
        self.slice_graph_1 = None
        self.slice_graph_2 = None

        # кнопки
        # self.ui.generate_code_python_func.clicked.connect(self.generate_code)
        self.ui.clear_field_btn.clicked.connect(self.clear_edits)
        self.ui.draw_graph_btn.clicked.connect(self.draw_graph)
        self.ui.find_func_btn.clicked.connect(
            lambda: self.get_func_value(self.ui.point,
                                        self.ui.point_label.text(),
                                        self.ui.func_value,
                                        show_message=True))
        self.ui.reset_plot.clicked.connect(self.reset_plot)
        self.ui.add_noise_btn.clicked.connect(self.add_noise)
        self.ui.save_min_max.clicked.connect(self.save_min_max)

        # действия
        self.ui.actionOpenJson.triggered.connect(self.import_json)
        self.ui.actionSave.triggered.connect(self.save_parameters_in_json)
        self.ui.actionQuit.triggered.connect(self.close)
        self.ui.actionAbout.triggered.connect(self.open_about_dialog)
        self.ui.actionSettings.triggered.connect(self.open_settings_window)
        # self.ui.actionHelp.triggered.connect(self.open_help)

        self.ui.max_func_coord.editingFinished.connect(
            lambda: self.get_func_value(self.ui.max_func_coord,
                                        "",
                                        self.ui.max_func,
                                        show_message=False))
        self.ui.min_func_coord.editingFinished.connect(
            lambda: self.get_func_value(self.ui.min_func_coord,
                                        "",
                                        self.ui.min_func,
                                        show_message=False))

    def generate_code(self):
        # TODO: добавить комментарии
        if self.parameters is None:
            self.parameters = self.read_parameters_function()
        func_type = self.read_type()
        if not (self.parameters is None):
            if func_type == self.function_types[0]:
                method = MethodMinPython()
                file_name = service.get_file_name(self.parameters.idx,
                                                  pattern="test_func",
                                                  expansion=".py")
                method.generate_function(self.idx_func, file_name,
                                         self.parameters)
            elif func_type == self.function_types[1]:
                pass
            elif func_type == self.function_types[2]:
                pass
            self.ui.statusBar.showMessage("Генерация кода успешно завершена",
                                          5000)
            # self.parameters = None
            # method = None

    def read_parameters_function(self):
        # TODO: добавить комментарии
        self.idx_func, er = parser_field.parse_number(self.ui.idx_func.value(),
                                                      self.ui.idx_func_label)
        if er != "":
            self.display_error_message(er)
            return
        number_extrema, er = parser_field.parse_number(
            self.ui.number_extrema.value(), self.ui.number_extrema_label)
        if er != "":
            self.display_error_message(er)
            return
        coordinates, er = parser_field.parse_coordinates(
            self.ui.coordinates.text())
        if er != "":
            self.display_error_message(er)
            return
        function_values, er = parser_field.parse_field(
            self.ui.function_values.text(),
            self.ui.function_values_label.text())
        if er != "":
            self.display_error_message(er)
            return
        degree_smoothness, er = parser_field.parse_field(
            self.ui.degree_smoothness.text(),
            self.ui.degree_smoothness_label.text())
        if er != "":
            self.display_error_message(er)
            return
        coefficients, er = parser_field.parse_field(
            self.ui.coefficients_abruptness_function.text(),
            self.ui.coefficients_abruptness_function_label.text())
        if er != "":
            self.display_error_message(er)
            return
        func_type = self.read_type()
        constraints_high, er = parser_field.parse_field(
            self.ui.constraints_high.text(),
            self.ui.constraints_x1_label.text())
        if er != "":
            self.display_error_message(er)
            return
        constraints_down, er = parser_field.parse_field(
            self.ui.constraints_down.text(),
            self.ui.constraints_x2_label.text())
        if er != "":
            self.display_error_message(er)
            return
        global_min, er = parser_field.parse_field(
            self.ui.min_func_coord.text(), self.ui.min_label.text())
        if er != "":
            self.display_error_message(er)
            return
        global_max, er = parser_field.parse_field(
            self.ui.max_func_coord.text(), self.ui.max_label.text())
        if er != "":
            self.display_error_message(er)
            return

        if len(global_min) != len(global_max) or len(global_min) != len(
                coordinates[0]):
            error = "Поля координат глобального минимума или максимума заполенны некорректно!"
            self.display_error_message(error)
            return None
        if func_type != "":
            p = Parameters(self.idx_func,
                           func_type,
                           number_extrema,
                           coordinates,
                           function_values,
                           degree_smoothness,
                           coefficients,
                           constraints_high,
                           constraints_down,
                           global_min,
                           global_max,
                           min_f=self.ui.min_func.value(),
                           max_f=self.ui.max_func.value())
            ok = validation.validation_parameters(p, func_type)
            if not ok:
                error = "Одно или несколько полей заполнены некорректно!"
                self.display_error_message(error)
                return None
            else:
                return p

    def read_type(self):
        """
        Функция определения метода конструирования тестовой функции.
        :return: Если выбран чекбокс method_min - тип будет "method_min"
                 Если выбран чекбокс hyperbolic_potential - тип будет "hyperbolic_potential"
                 Если выбран чекбокс exponential_potential - тип будет "exponential_potential"
                 Если не выбран ни один чекбокс выведется сообщение об ошибке
        """
        func_type = ""
        if self.ui.method_min.isChecked():
            func_type = self.function_types[0]
        elif self.ui.hyperbolic_potential.isChecked():
            func_type = self.function_types[1]
        elif self.ui.exponential_potential.isChecked():
            func_type = self.function_types[2]
        else:
            error = "Выберите метод конструирования тестовой функции!"
            self.display_error_message(error)
        return func_type

    def display_error_message(self, error: str):
        """
        Метод вывода сообщение об ошибке на экран
        :param error: текст ошибки
        :return: -
        """
        info = QMessageBox.information(self, 'Внимание!', error,
                                       QMessageBox.Cancel, QMessageBox.Cancel)

    def import_json(self):
        """Метод импорта параметров тестовой функции из json-файла посредством вызова диалогового окна,
        если считывание прошло неудачно, то выводится сообщение об ошибке"""
        self.clear_edits()
        file_name, _ = QFileDialog.getOpenFileName(
            self, "Открыть json-файл ...", "/home",
            "Json-Files (*.json);;All Files (*)")

        if file_name:
            self.save_file_name = file_name
            with open(file_name, 'r', encoding="utf-8") as f:
                data = f.read()
            try:
                p = json.loads(data)
                self.parameters = service.dict_in_obj(p)
                self.print_parameters_in_edit()
            except ValueError:
                error = "Файл заполнен некорректно"
                self.display_error_message(error)
            self.ui.statusBar.showMessage("Данные импортированы", 5000)

    def print_parameters_in_edit(self):
        """Вывод параметров тестовой функции на экран"""
        del_square_brackets = slice(1, -1, 1)
        self.activate_radio_btn()
        self.ui.coefficients_abruptness_function.setText(
            str(self.parameters.coefficients_abruptness)[del_square_brackets])
        self.ui.number_extrema.setValue(self.parameters.number_extrema)
        self.ui.function_values.setText(
            str(self.parameters.func_values)[del_square_brackets])
        self.ui.degree_smoothness.setText(
            str(self.parameters.degree_smoothness)[del_square_brackets])
        self.ui.coordinates.setText(
            str(self.parameters.coordinates)[del_square_brackets])
        self.ui.constraints_high.setText(
            str(self.parameters.constraints_high)[del_square_brackets])
        self.ui.constraints_down.setText(
            str(self.parameters.constraints_down)[del_square_brackets])
        self.ui.min_func.setValue(self.parameters.min_value)
        self.ui.max_func.setValue(self.parameters.Max_value)

        self.ui.min_func_coord.setText(
            str(self.parameters.global_min)[del_square_brackets])
        self.ui.max_func_coord.setText(
            str(self.parameters.global_max)[del_square_brackets])

    def activate_radio_btn(self):
        """При загрузке тестовой функции из json файла выбирает чекбокс, 
        который соответствует типу тестовой функции"""
        t = self.parameters.get_type()
        if t == self.function_types[0]:
            self.ui.method_min.setChecked(True)
        elif t == self.function_types[1]:
            self.ui.hyperbolic_potential.setChecked(True)
        elif t == self.function_types[2]:
            self.ui.exponential_potential.setChecked(True)

    def delete_widget(self, layout):
        """
        Метод удаления виджетов из лайаута (в основном графиков)
        :param layout: контейнер типя Layout
        :return: -
        """
        for i in range(layout.count()):
            item = layout.itemAt(i).widget()
            if item is not None:
                item.close()
                item.deleteLater()
            else:
                layout.takeAt(i)

    # def delete_widget(self, widget):
    #     for i in range(widget.count()):
    #         item = widget.itemAt(0)
    #         widget.removeItem(item)

    def reset_plot(self):
        self.graph_3d = None
        self.contour_graph = None
        self.slice_graph_1 = None
        self.slice_graph_2 = None
        self.delete_widget(self.ui.v_box_3d_graph)
        self.delete_widget(self.ui.v_box_contour_graph)
        self.delete_widget(self.ui.v_box_slice_graph1)
        self.delete_widget(self.ui.v_box_slice_graph2)

    def clear_edits(self):
        """Метод очистки текстовых полей и удаления открытых графиков"""
        self.ui.coefficients_abruptness_function.setText(
            self.ui.translate("MainWindow", ""))
        self.ui.number_extrema.setValue(1)
        self.ui.function_values.setText(self.ui.translate("MainWindow", ""))
        self.ui.degree_smoothness.setText(self.ui.translate("MainWindow", ""))
        self.ui.coordinates.setText(self.ui.translate("MainWindow", ""))
        self.ui.constraints_high.setText(self.ui.translate("MainWindow", ""))
        self.ui.constraints_down.setText(self.ui.translate("MainWindow", ""))
        self.ui.slice_expr_x1.setText(self.ui.translate("MainWindow", "0"))
        self.ui.slice_expr_x2.setText(self.ui.translate("MainWindow", "0"))

        self.ui.max_func.setValue(0)
        self.ui.min_func.setValue(0)
        self.ui.amp_noise.setValue(0)
        self.ui.func_value.setText(self.ui.translate("MainWindow", "42"))
        self.ui.point.setText(self.ui.translate("MainWindow", "0, 0"))

        self.graph_3d = None
        self.contour_graph = None
        self.slice_graph_1 = None
        self.slice_graph_2 = None

        self.delete_widget(self.ui.v_box_3d_graph)
        self.delete_widget(self.ui.v_box_contour_graph)
        self.delete_widget(self.ui.v_box_slice_graph1)
        self.delete_widget(self.ui.v_box_slice_graph2)

        self.idx_func = 1
        self.parameters = None
        self.func = None
        self.save_file_name = None

        self.ui.statusBar.showMessage("Зло не дремлет. И мы не должны.", 5000)

    def save_parameters_in_json(self):
        """Метод сохранения параметров тестовой функции в json-файл посредством вызова диалогового окна"""
        # TODO: json поддерживает преобразование None в nill
        self.parameters = self.read_parameters_function()
        file_name, _ = QFileDialog.getOpenFileName(
            self, "Открыть json-файл ...", "/home",
            "Json-Files (*.json);;All Files (*)")

        if file_name:
            self.save_file_name = file_name
            d = self.parameters.__dict__
            if d["min_value"] is None:
                d["min_value"] = 0
            if d["Max_value"] is None:
                d["Max_value"] = 0
            data = json.dumps(d, indent=4)
            with open(file_name, 'w') as f:
                f.write(data)

        self.ui.statusBar.showMessage(
            "Сохранение параметров успешно завершено", 5000)

    def save_min_max(self):
        if self.save_file_name and (not (self.parameters is None)):
            self.parameters.set_min_f(self.ui.min_func.value())
            self.parameters.set_max_f(self.ui.max_func.value())
            self.parameters.global_max, er = parser_field.parse_number_list(
                self.ui.max_func_coord.text(), "")
            if er != "":
                self.display_error_message(
                    "Координаты глобального максимума введены некорректно")
                return
            self.parameters.global_min, er = parser_field.parse_number_list(
                self.ui.min_func_coord.text(), "")
            if er != "":
                self.display_error_message(
                    "Координаты глобального минимума введены некорректно")
                return
            with open(self.save_file_name, 'r') as f:
                js_data = json.load(f)
            with open(self.save_file_name, 'w') as f:
                js_data["min_value"] = self.parameters.get_min_f()
                js_data["Max_value"] = self.parameters.get_max_f()
                js_data["global_max"] = self.parameters.global_max
                js_data["global_min"] = self.parameters.global_min
                js_data["amp_noise"] = abs(self.parameters.get_max_f() -
                                           self.parameters.get_min_f()) / 2
                json.dump(js_data, f, indent=4)
        self.ui.statusBar.showMessage(
            "Сохранение экстремумов успешно завершено", 5000)

    def draw_graph(self):
        self.parameters = self.read_parameters_function()
        # TODO: добавить комментарии

        expr_x1 = self.ui.slice_expr_x1.text()
        expr_x2 = self.ui.slice_expr_x2.text()

        # TODO: написать функцию validation для ограничений, != [], x[0]<x[1]
        if (self.parameters
                is not None) and (self.parameters.constraints_high != []) and (
                    self.parameters.constraints_down != []):
            self.graph_3d = None
            self.contour_graph = None
            self.slice_graph_1 = None
            self.slice_graph_2 = None
            self.delete_widget(self.ui.v_box_3d_graph)
            self.delete_widget(self.ui.v_box_contour_graph)
            self.delete_widget(self.ui.v_box_slice_graph1)
            self.delete_widget(self.ui.v_box_slice_graph2)

            method_type = self.read_type()
            if method_type != "":
                self.func = self.get_func(method_type)

                self.graph_3d = Canvas3dGraph()
                self.create_layout_with_graph(self.ui.v_box_3d_graph,
                                              self.graph_3d,
                                              self.parameters.constraints_high,
                                              self.parameters.constraints_down,
                                              title="F" + str(self.idx_func),
                                              legend_title="F" +
                                              str(self.idx_func))

                self.contour_graph = CanvasContourGraph()
                self.create_layout_with_graph(
                    self.ui.v_box_contour_graph,
                    self.contour_graph,
                    self.parameters.constraints_high,
                    self.parameters.constraints_down,
                    xlabel=settings.Settings.settings['xlabel'].value,
                    ylabel=settings.Settings.settings['ylabel'].value,
                    title="F" + str(self.idx_func),
                    legend_title="F" + str(self.idx_func))

                if (expr_x1 != "") and (expr_x2 != ""):
                    self.slice_graph_1 = CanvasSliceGraph(
                    )  # self.ui.v_box_slice_graph1
                    self.create_layout_with_graph(
                        self.ui.v_box_slice_graph1,
                        self.slice_graph_1,
                        self.parameters.constraints_high,
                        self.parameters.constraints_down,
                        expression=expr_x1,
                        axes=0,
                        amp_noise=0,
                        xlabel=settings.Settings.settings['ylabel'].value,
                        ylabel="F" + str(self.idx_func),
                        title=settings.Settings.settings['xlabel'].value +
                        '=' + expr_x1,
                    )

                    self.slice_graph_2 = CanvasSliceGraph(
                    )  # self.ui.v_box_slice_graph2
                    self.create_layout_with_graph(
                        self.ui.v_box_slice_graph2,
                        self.slice_graph_2,
                        self.parameters.constraints_high,
                        self.parameters.constraints_down,
                        expression=expr_x2,
                        axes=1,
                        amp_noise=0,
                        xlabel=settings.Settings.settings['xlabel'].value,
                        ylabel="F" + str(self.idx_func),
                        title=settings.Settings.settings['ylabel'].value +
                        '=' + expr_x2,
                    )
                self.ui.statusBar.showMessage("Графики успешно построены",
                                              5000)
            else:
                self.display_error_message(
                    "Выберите метод конструирования тестовой функции")
        else:
            self.display_error_message("Что-то пошло не так")

    def create_layout_with_graph(self,
                                 layout,
                                 graph_obj,
                                 constraints_high,
                                 constraints_down,
                                 xlabel="${x}{_1}$",
                                 ylabel="${x}{_2}$",
                                 title="F",
                                 legend_title="F",
                                 **kwargs):
        toolbar = graph_obj.get_toolbar()
        layout.addWidget(toolbar)
        layout.addWidget(graph_obj)
        graph_obj.create_graph(
            constraints_high,
            constraints_down,
            self.func,
            h=settings.Settings.settings['grid_spacing'].value,
            **kwargs
        )  # expr_x=expr_x, expr_y=expr_y, amp_noise=amp_noise, delta=delta
        graph_obj.set_labels(xlabel=xlabel,
                             ylabel=ylabel,
                             title=title,
                             legend_title=legend_title + str(self.idx_func))

    def add_noise(self):
        # TODO: добавить комментарии
        constraints_x, er = parser_field.parse_number_list(
            self.ui.constraints_high.text(),
            self.ui.constraints_x1_label.text())
        if er != "":
            self.display_error_message(er)
            return
        constraints_y, er = parser_field.parse_number_list(
            self.ui.constraints_down.text(),
            self.ui.constraints_x2_label.text())
        if er != "":
            self.display_error_message(er)
            return
        expr_x1 = self.ui.slice_expr_x1.text()
        expr_x2 = self.ui.slice_expr_x2.text()
        amp_noise = self.get_amp_noise()
        if (self.parameters
                is not None) and (self.func is not None) and (amp_noise >= 0):
            self.contour_graph = None
            self.delete_widget(self.ui.v_box_contour_graph)
            self.contour_graph = CanvasContourGraph()
            contour_graph_toolbar = self.contour_graph.get_toolbar()
            self.ui.v_box_contour_graph.addWidget(contour_graph_toolbar)
            self.ui.v_box_contour_graph.addWidget(self.contour_graph)
            self.contour_graph.create_graph(
                constraints_x,
                constraints_y,
                self.func,
                h=settings.Settings.settings['grid_spacing'].value,
                delta=1,
                amp_noise=amp_noise)
            self.contour_graph.set_labels(
                settings.Settings.settings['xlabel'].value,
                settings.Settings.settings['ylabel'].value,
                "F" + str(self.idx_func), "F" + str(self.idx_func))

        if (constraints_x != []) and (constraints_y != []) and (
                not (self.parameters is None)) and (not (self.func is None)):
            if (expr_x1 != "") and (expr_x2 != "") and (amp_noise >= 0):
                h = settings.Settings.settings['chart_step'].value
                self.slice_graph_1 = None
                self.slice_graph_2 = None
                self.delete_widget(self.ui.v_box_slice_graph1)
                self.delete_widget(self.ui.v_box_slice_graph2)

                self.slice_graph_1 = CanvasSliceGraph()
                slice_graph_1_toolbar = self.slice_graph_1.get_toolbar()
                self.ui.v_box_slice_graph1.addWidget(slice_graph_1_toolbar)
                self.ui.v_box_slice_graph1.addWidget(self.slice_graph_1)
                self.slice_graph_1.create_graph(constraints_x,
                                                constraints_y,
                                                self.func,
                                                expression=expr_x1,
                                                h=h,
                                                amp_noise=amp_noise)
                self.slice_graph_1.set_labels(
                    xlabel=settings.Settings.settings['ylabel'].value,
                    ylabel="F" + str(self.idx_func),
                    title=settings.Settings.settings['xlabel'].value + "=" +
                    expr_x1,
                    legend_title="F" + str(self.idx_func))

                self.slice_graph_2 = CanvasSliceGraph()
                slice_graph_2_toolbar = self.slice_graph_2.get_toolbar()
                self.ui.v_box_slice_graph2.addWidget(slice_graph_2_toolbar)
                self.ui.v_box_slice_graph2.addWidget(self.slice_graph_2)
                self.slice_graph_2.create_graph(constraints_x,
                                                constraints_y,
                                                self.func,
                                                expression=expr_x2,
                                                h=h,
                                                amp_noise=amp_noise)
                self.slice_graph_2.set_labels(
                    xlabel=settings.Settings.settings['xlabel'].value,
                    ylabel="F" + str(self.idx_func),
                    title=settings.Settings.settings['ylabel'].value + "=" +
                    expr_x2,
                    legend_title="F" + str(self.idx_func))
                self.ui.statusBar.showMessage(
                    "На графики срезов добавлена аддитивная помеха", 5000)

    def get_func(self, method_type):
        f = None
        if method_type == self.function_types[0]:
            f = test_func.get_test_function_method_min(
                self.parameters.get_number_extrema(),
                self.parameters.get_coefficients_abruptness(),
                self.parameters.get_coordinates(),
                self.parameters.get_degree_smoothness(),
                self.parameters.get_function_values())
        elif method_type == self.function_types[1]:
            f = test_func.get_tf_hyperbolic_potential_abs(
                self.parameters.get_number_extrema(),
                self.parameters.get_coefficients_abruptness(),
                self.parameters.get_coordinates(),
                self.parameters.get_degree_smoothness(),
                self.parameters.get_function_values())
        elif method_type == self.function_types[2]:
            f = test_func.get_tf_exponential_potential(
                self.parameters.get_number_extrema(),
                self.parameters.get_coefficients_abruptness(),
                self.parameters.get_coordinates(),
                self.parameters.get_degree_smoothness(),
                self.parameters.get_function_values())
        return f

    def get_amp_noise(self):
        """Метод расчета амплитуды шума.
        Считывает коэффициент шум/сигнал, минимум и максимум
        Амплитуда = коэффициент шум/сигнал * (максимум - минимум) / 2"""
        k_noise = self.ui.amp_noise.value()
        min_f = self.ui.min_func.value()
        max_f = self.ui.max_func.value()
        amp = k_noise * abs(max_f - min_f) / 2
        if amp == 0:
            error = "Что-то пошло не так!"
            self.display_error_message(error)
            return -1
        else:
            return amp

    def open_about_dialog(self):
        """Метод открытия окна "О программе" """
        self.about = AboutDialog(flags=Q_FLAGS())
        self.about.show()

    def open_settings_window(self):
        """Метод открытия окна "Настройки" """
        if self.settings_window is None:
            self.settings_window = SettingsWindow(self)
            self.settings_window.show()

    # def open_help(self):
    #     script_path = os.path.dirname(os.path.abspath(__file__))
    #     help_path = os.path.join(script_path, '../resources/help.chm')
    #     # os.system("hh.exe d:/help.chm::/4_Userguide.htm#_Toc270510")
    #     os.system("hh.exe " + help_path)

    def get_func_value(self, field, name, res, show_message: bool = False):
        """расчитывает значение в точке, координаты которой введены пользователем"""
        x, er = parser_field.parse_number_list(field.text(), name)
        if er != "":
            self.display_error_message(er)
            return
        if not (self.func is None):
            if len(x) == self.parameters.get_dimension():
                y = self.func(x)
                if type(res) == QLineEdit or type(res) == QLabel:
                    res.setText(self.ui.translate("MainWindow", str(y)))
                elif type(res) == QDoubleSpinBox:
                    res.setValue(y)
                return y
            else:
                error = "Exterminate all the bugs!"
                if show_message:
                    self.display_error_message(error)
        else:
            error = "Ученик, магия тебя ждать не будет!"
            if show_message:
                self.display_error_message(error)
Ejemplo n.º 4
0
class MainWindow(QMainWindow):
    """Главное окно программы"""
    def __init__(self, parent=None):
        super().__init__(parent)
        self.ui = UiMainWindow()

        self.settings = Settings()

        self.active_alg_1 = [
            StandardGSA(),
            StandardSAC(),
            NoiseResistanceGSA(),
            AcsaSAC()
        ]
        self.to_test_list = []

        self.ui.setup_ui(self, self.active_alg_1)

        support_func.fill_combobox_list_alg(self.active_alg_1,
                                            self.ui.combobox_alg)
        self.ui.add_new_alg_btn.clicked.connect(lambda: self.add_alg())

        self.window_settings_alg = None
        self.window_common_settings = None

        self.window_choose = None
        self.possible_graphics = []

        self.change_status_activity_buttons(self.ui.alg_form, True)

        self.get_selected_algorithms = self.ui.get_index_active_checkbox(
            self.ui.alg_form)

        self.ui.actionAbout.triggered.connect(self.open_about_dialog)
        self.ui.actionHelp.triggered.connect(self.open_help)

        self.ui.add_linear_graph_btn.clicked.connect(self.add_linear_graph)
        self.ui.add_heat_map_btn.clicked.connect(self.add_heat_map)

        self.param_in_combobox_for_heat_map = {}
        self.ui.param_heat_map_1.activated.connect(
            lambda: self.prohibit_duplicate_selection(
                self.ui.param_heat_map_1, self.ui.param_heat_map_2))
        self.ui.param_heat_map_2.activated.connect(
            lambda: self.prohibit_duplicate_selection(
                self.ui.param_heat_map_2, self.ui.param_heat_map_1))
        self.ui.additional_graphics_btn.clicked.connect(
            self.draw_additional_graphics)
        self.ui.open_data_file_btn.clicked.connect(self.open_data_file)

    def add_linear_graph(self):
        algorithms = self.get_active_algorithm()
        d = support_func.get_value_from_combobox(self.ui.param_linear_graph)
        if d == {None: ''}:
            error = "Выберите параметр итерирования"
            self.print_error(error)
            return
        p = AlgorithmParameter.get_parameters(list(d.keys())[0])
        n = self.ui.list_graph.count()
        if n > 0:
            self.ui.list_graph.takeAt(n - 1)
        if p.allowable_values is not None:
            point_graph = PossibleGraph("POINT_GRAPH", p, [], algorithms)
            point_graph_wdg = PointGraphWidget(point_graph)
            self.ui.list_graph.addWidget(
                point_graph_wdg.get_widget(parent=self,
                                           algorithms=algorithms,
                                           print_error=self.print_error))
        else:
            line_graph = PossibleGraph("LINE_GRAPH", p, [], [])
            line_graph_wdg = LineGraphWidget(line_graph)
            self.ui.list_graph.addWidget(
                line_graph_wdg.get_widget(lower_limit=0,
                                          top_limit=1000,
                                          step_limit=1,
                                          algorithms=algorithms,
                                          print_error=self.print_error))
        self.ui.list_graph.addStretch(1)

    def add_heat_map(self):
        algorithms = self.get_active_algorithm()
        param_x = support_func.get_value_from_combobox(
            self.ui.param_heat_map_1)
        param_y = support_func.get_value_from_combobox(
            self.ui.param_heat_map_2)
        if (param_x == param_y) or (param_x == {
                None: ''
        }) or (param_y == {
                None: ''
        }):
            error = "Параметры итерирования выбраны некорректно!"
            self.print_error(error)
            return
        if len(algorithms) != 1:
            error = "Должен быть выбран один алгоритм!"
            self.print_error(error)
            return
        p_x = AlgorithmParameter.get_parameters(list(param_x.keys())[0])
        p_y = AlgorithmParameter.get_parameters(list(param_y.keys())[0])
        n = self.ui.list_graph.count()
        if n > 0:
            self.ui.list_graph.takeAt(n - 1)
        graph = PossibleGraph("HEAT_MAP", [p_x, p_y], [], self.to_test_list)
        graph_widget = HeatMapWidget(graph)
        self.ui.list_graph.addWidget(
            graph_widget.get_widget(lower_limit=0,
                                    top_limit=1000,
                                    step_limit=1,
                                    algorithm=algorithms,
                                    print_error=self.print_error))
        self.ui.list_graph.addStretch(1)

    def add_parameters_in_combobox(self, get_idx_active_cb):
        def f():
            idx_active_cb = get_idx_active_cb()
            params = self.get_params_on_idx(self.to_test_list, idx_active_cb)
            common_params = support_func.get_common_params(*params)
            self.param_in_combobox_for_heat_map = common_params
            self.fill_combobox(common_params, self.ui.param_linear_graph,
                               self.ui.param_heat_map_1,
                               self.ui.param_heat_map_2)

        return f

    def get_params_on_idx(self, to_test_list, idx_list):
        d = []
        for i in idx_list:
            alg = to_test_list[i]
            if alg is not None:
                p = alg.get_params_dict()
                d.append(p)
        return d

    # def get_params(self, to_test_list):
    #     d = []
    #     for alg in to_test_list:
    #         if alg is not None:
    #             p = alg.get_params_dict()
    #             d.append(p)
    #     return d

    def fill_combobox(self, data, *args):
        # TODO: перенести в общие
        for cmb in args:
            cmb.clear()
            for k in data.keys():
                if (k != "EC") and (k != "RN"):
                    cmb.addItem(data.get(k), k)

    def get_active_algorithm(self):
        idx = self.get_selected_algorithms()
        algorithms = [self.to_test_list[idx[i]] for i in range(len(idx))]
        return algorithms

    def change_status_activity_buttons(self, layout, flag):
        for i in range(layout.count()):
            item = layout.itemAt(i).widget()
            if type(item) == QPushButton:
                item.setDisabled(flag)

    def add_alg(self):
        name = self.ui.combobox_alg.currentText()
        alg = self.ui.combobox_alg.currentData()
        a = copy.deepcopy(alg)
        self.to_test_list.append(a)

        cb_handler = self.add_parameters_in_combobox

        self.ui.add_row_in_form(self.ui.alg_form, a.get_parameters(), name,
                                "Настроить", cb_handler, self)

    def prohibit_duplicate_selection(self, cmb, cmb1):
        item = cmb.currentText()
        item_data = cmb.currentData()

        item1 = cmb1.currentText()

        list_without_item = []
        cmb1.clear()
        for i in self.param_in_combobox_for_heat_map.keys():
            if item_data != i:
                list_without_item.append(i)
                cmb1.addItem(self.param_in_combobox_for_heat_map.get(i), i)

        if item != item1:
            cmb1.setCurrentText(item1)

    def print_error(self, text: str) -> None:
        """Вывод сообщения об ошибке на экран"""
        QMessageBox.information(self, 'Внимание!', text, QMessageBox.Cancel,
                                QMessageBox.Cancel)

    def draw_additional_graphics(self):
        flags = [g['draw'] for g in self.settings.additional_graphics]
        if not any(flags):
            self.print_error("Не выбрано ни одного дополнительного графика")
            return
        if not self.settings.abs_path_test_func:
            self.print_error("Не выбрана тестовая функция")
            return
        test_func_data = support_func.read_json(
            self.settings.abs_path_test_func)
        algorithms = self.get_active_algorithm()
        if not algorithms:
            self.print_error("Не выбрано ни одного алгоритма")
            return
        all_data = []
        if self.ui.data_path_le.text() != "":
            # TODO: здесь чтение данных из файла
            abs_path = self.ui.data_path_le.text()
            data = support_func.read_json(abs_path)
            all_data.append(data['runs'][0])
        else:
            script_path = os.path.dirname(os.path.abspath(__file__))
            for alg in algorithms:
                number_runs = alg.settings.number_of_runs
                alg.settings.number_of_runs = 1
                alg.write_parameters()
                file_name = alg.get_identifier_name() + '.json'
                abs_path = os.path.join(script_path,
                                        "..\\algorithms_exe\\result\\",
                                        file_name)
                alg.run(abs_path, self.settings.abs_path_test_func)
                return_code, run_time = alg.wait_process()
                if return_code != 0:
                    self.print_error("Ошибка при работе алгоритма")
                    return
                data = support_func.read_json(abs_path)
                all_data.append(data['runs'][0])
                alg.settings.number_of_runs = number_runs
                alg.write_parameters()

        for g in self.settings.additional_graphics:
            if g['draw'] and g['name'] == "График движения лучшей точки":
                func = get_test_func(test_func_data['type'],
                                     test_func_data['number_extrema'],
                                     test_func_data['coefficients_abruptness'],
                                     test_func_data['coordinates'],
                                     test_func_data['degree_smoothness'],
                                     test_func_data['func_values'])
                last_iter = min(
                    operator.getitem(i, 'stop_iteration') for i in all_data)
                stop_iter = g['iter'] if g['iter'] <= last_iter else last_iter
                data = [
                    operator.getitem(d, 'coordinates')[:stop_iter]
                    for d in all_data
                ]
                motion_point_graph(
                    data,
                    func,
                    lbl=[alg.get_identifier_name() for alg in algorithms],
                    file_name="motion_graph.png",
                    x_label="${x}{_0}$",
                    y_label="${x}{_1}$",
                    title=g['name'] + " за " + str(g['iter']) + " итераций")

            data = []
            max_stop_iter = max(
                operator.getitem(i, 'stop_iteration') for i in all_data)
            for d in all_data:
                meaningful_data = operator.getitem(
                    d, g['name_field'])[:d['stop_iteration']]
                if d['stop_iteration'] < max_stop_iter:
                    data.append(meaningful_data + [
                        meaningful_data[-1]
                        for _ in range(max_stop_iter - len(meaningful_data))
                    ])
                else:
                    data.append(meaningful_data)

            if g['draw'] and g['name'] == "График сходимости по координатам":
                graph_convergence_coord(data,
                                        [i for i in range(max_stop_iter)],
                                        lbl=[["${x}{_0}$", "${x}{_1}$"]
                                             for _ in range(len(algorithms))],
                                        file_name=[
                                            "graph_convergence_coord_" +
                                            alg.get_identifier_name() + ".png"
                                            for alg in algorithms
                                        ],
                                        x_label="${t}$",
                                        y_label="${x}$",
                                        title=g['name'],
                                        single_graph=False,
                                        marker=None)
            elif g['draw'] and g[
                    'name'] == "График сходимости по значениям функции":
                file_name = "graph_convergence_func_value.png"
                line_graph(
                    data, [i for i in range(max_stop_iter)],
                    lbl=[alg.get_identifier_name() for alg in algorithms],
                    file_name=file_name,
                    x_label="${t}$",
                    y_label="${f(x)}$",
                    title=g['name'],
                    marker='')
            elif g['draw'] and g['name'] == "График дисперсии":
                data = np.array(data)
                label = [
                    "${\sigma}{_x}$_" + alg.get_name().replace(' ', '_')
                    for alg in algorithms
                ]
                file_name = "graph_dispersion.png"
                line_graph(data, [i for i in range(max_stop_iter)],
                           lbl=label,
                           file_name=file_name,
                           x_label="${t}$",
                           y_label="${\sigma}^2$",
                           title=g['name'],
                           marker='')

    def open_data_file(self) -> None:
        """
        Метод открытия окна для выбора json-файла с данными для построения графиков.
        Обработчик события нажатия на кнопку self.ui.open_data_file_btn.
        :return: None.
        """
        file_name = support_func.open_file_dialog(
            "Открыть json-файл данных", "All Files (*);;JSON Files (*.json)",
            self)
        if file_name:
            self.ui.data_path_le.setText(file_name)

    def open_about_dialog(self) -> None:
        """Метод открытия окна "О программе" """
        self.about = AboutDialog(flags=Q_FLAGS())
        self.about.show()

    def open_help(self):
        script_path = os.path.dirname(os.path.abspath(__file__))
        help_path = os.path.join(script_path, '../resource/help.chm')
        # os.system("hh.exe d:/help.chm::/4_Userguide.htm#_Toc270510")
        os.system("hh.exe " + help_path)
Ejemplo n.º 5
0
    def __init__(self):

        # Okno programu
        self.glade_file = "gui/main_window.glade"
        self.builder = Gtk.Builder()
        self.builder.add_from_file(self.glade_file)
        self.builder.connect_signals(self)
        self.window = self.builder.get_object("main_window")

        # Obiekt łączący algorytm z oknem
        self.controller = WindowController(self)

        # Główne widgety okna
        self.statusbar = self.builder.get_object("statusbar")
        self.context_id = self.statusbar.get_context_id("status")
        self.main_image = self.builder.get_object("main_image")
        self.toolbar = self.builder.get_object("toolbar")

        # Wygenerowanie elementów menu odtwarzania
        self.play_button = self.builder.get_object("play_button")
        self.pause_button = self.builder.get_object("pause_button")
        self.stop_button = self.builder.get_object("stop_button")
        self.replay_button = self.builder.get_object("replay_button")
        self.save_image_button = self.builder.get_object("save_image_button")
        self.record_toggle_button = self.builder.get_object(
            "record_toggle_button")
        self.run_alg_toggle_button = self.builder.get_object("run_alg_button")
        self.display_mask_button = self.builder.get_object(
            "display_mask_button")

        # Wygnerowanie elementów głównego menu
        self.open_file_button = self.builder.get_object("open_file_button")
        self.open_database_button = self.builder.get_object(
            "open_database_button")
        self.open_images_button = self.builder.get_object("open_images_button")
        self.delete_files_button = self.builder.get_object(
            "delete_files_button")
        self.settings_button = self.builder.get_object("settings_button")
        self.documentation_button = self.builder.get_object(
            "documentation_button")
        self.about_button = self.builder.get_object("about_button")

        # Pasek postępu
        self.progressbar = self.builder.get_object("progressbar")

        # Elementy potomne
        self.about_dialog = AboutDialog()
        self.settings_dialog = SettingsDialog()
        self.file_chooser_dialog = None

        # ustawienie pustego obrazu startowego
        self.controller.clear_main_image()

        # Lista wykrytych samochodów
        self.detected_cars_liststore = Gtk.ListStore(int, str, str, str, str,
                                                     str, str)
        self.detected_cars_treeview = self.builder.get_object(
            "detected_cars_treeview")
        self.detected_cars_treeview.set_model(self.detected_cars_liststore)
        for i, col_title in enumerate(
            ["Nr", "Długość", "Wysokość", "Pole", "Prędkość", "Kolor",
             "Plik"]):
            render = Gtk.CellRendererText()
            coulmn = Gtk.TreeViewColumn(col_title, render, text=i)
            self.detected_cars_treeview.append_column(coulmn)

        # Lista plików
        self.files_liststore = Gtk.ListStore(int, str)
        self.files_treeview = self.builder.get_object("files_treeview")
        self.files_treeview.set_model(self.files_liststore)
        for i, col_title in enumerate(["Nr", "Ścieżka"]):
            render = Gtk.CellRendererText()
            coulmn = Gtk.TreeViewColumn(col_title, render, text=i)
            self.files_treeview.append_column(coulmn)

        # Usuwanie plików z listy
        self.files_treeview.connect("button-press-event",
                                    self.button_press_event)

        # Obsługa skrótów klawiszowych
        self.window.connect("key_press_event", self.on_key_press_event)

        # Uruchomienie głównego okna
        self.window.show()
Ejemplo n.º 6
0
class ProgramView:
    def __init__(self):

        # Okno programu
        self.glade_file = "gui/main_window.glade"
        self.builder = Gtk.Builder()
        self.builder.add_from_file(self.glade_file)
        self.builder.connect_signals(self)
        self.window = self.builder.get_object("main_window")

        # Obiekt łączący algorytm z oknem
        self.controller = WindowController(self)

        # Główne widgety okna
        self.statusbar = self.builder.get_object("statusbar")
        self.context_id = self.statusbar.get_context_id("status")
        self.main_image = self.builder.get_object("main_image")
        self.toolbar = self.builder.get_object("toolbar")

        # Wygenerowanie elementów menu odtwarzania
        self.play_button = self.builder.get_object("play_button")
        self.pause_button = self.builder.get_object("pause_button")
        self.stop_button = self.builder.get_object("stop_button")
        self.replay_button = self.builder.get_object("replay_button")
        self.save_image_button = self.builder.get_object("save_image_button")
        self.record_toggle_button = self.builder.get_object(
            "record_toggle_button")
        self.run_alg_toggle_button = self.builder.get_object("run_alg_button")
        self.display_mask_button = self.builder.get_object(
            "display_mask_button")

        # Wygnerowanie elementów głównego menu
        self.open_file_button = self.builder.get_object("open_file_button")
        self.open_database_button = self.builder.get_object(
            "open_database_button")
        self.open_images_button = self.builder.get_object("open_images_button")
        self.delete_files_button = self.builder.get_object(
            "delete_files_button")
        self.settings_button = self.builder.get_object("settings_button")
        self.documentation_button = self.builder.get_object(
            "documentation_button")
        self.about_button = self.builder.get_object("about_button")

        # Pasek postępu
        self.progressbar = self.builder.get_object("progressbar")

        # Elementy potomne
        self.about_dialog = AboutDialog()
        self.settings_dialog = SettingsDialog()
        self.file_chooser_dialog = None

        # ustawienie pustego obrazu startowego
        self.controller.clear_main_image()

        # Lista wykrytych samochodów
        self.detected_cars_liststore = Gtk.ListStore(int, str, str, str, str,
                                                     str, str)
        self.detected_cars_treeview = self.builder.get_object(
            "detected_cars_treeview")
        self.detected_cars_treeview.set_model(self.detected_cars_liststore)
        for i, col_title in enumerate(
            ["Nr", "Długość", "Wysokość", "Pole", "Prędkość", "Kolor",
             "Plik"]):
            render = Gtk.CellRendererText()
            coulmn = Gtk.TreeViewColumn(col_title, render, text=i)
            self.detected_cars_treeview.append_column(coulmn)

        # Lista plików
        self.files_liststore = Gtk.ListStore(int, str)
        self.files_treeview = self.builder.get_object("files_treeview")
        self.files_treeview.set_model(self.files_liststore)
        for i, col_title in enumerate(["Nr", "Ścieżka"]):
            render = Gtk.CellRendererText()
            coulmn = Gtk.TreeViewColumn(col_title, render, text=i)
            self.files_treeview.append_column(coulmn)

        # Usuwanie plików z listy
        self.files_treeview.connect("button-press-event",
                                    self.button_press_event)

        # Obsługa skrótów klawiszowych
        self.window.connect("key_press_event", self.on_key_press_event)

        # Uruchomienie głównego okna
        self.window.show()

    def write_on_statusbar(self, text):
        self.statusbar.push(self.context_id, text)

    # Funkcje obsługujące przyciski menu odtwarzania

    def on_play_button_clicked(self, object, data=None):
        self.write_on_statusbar("Odtwarzanie...")
        self.controller.start_playing()

    def on_pause_button_clicked(self, object, data=None):
        self.write_on_statusbar("Pauza")
        self.controller.pause_playing()

    def on_stop_clicked(self, object, data=None):
        self.write_on_statusbar("Stop")
        self.controller.stop_playing()
        self.controller.clear_main_image()

    def on_replay_clicked(self, object, data=None):
        self.write_on_statusbar("Ponowne odtwarzanie...")
        self.controller.replay()

    def on_save_image_button_clicked(self, object, data=None):
        self.write_on_statusbar("Zapisywanie...")
        self.controller.save_image()

    def on_record_toggled(self, object, data=None):
        is_pressed = self.record_toggle_button.get_active()
        self.controller.enable_recording(is_pressed)
        if is_pressed:
            self.write_on_statusbar("Nagrywanie włączone.")
        else:
            self.write_on_statusbar("Nagrywanie wyłączone.")

    def on_run_alg_toggled(self, object, data=None):
        is_pressed = self.run_alg_toggle_button.get_active()
        self.controller.enable_algorithm(is_pressed)
        if is_pressed:
            self.write_on_statusbar("Przetwarzanie obrazu włączone.")
        else:
            self.write_on_statusbar("Przetwarzanie obrazu wyłączone.")

    def on_display_mask_button_toggled(self, object, data=None):
        is_pressed = self.display_mask_button.get_active()
        self.controller.enable_mask(is_pressed)
        if is_pressed:
            self.write_on_statusbar("Wyświetlnanie maski włączone.")
        else:
            self.write_on_statusbar("Wyświetlnanie maski wyłączone.")

    # Funkcje obsługujące przyciski głównego menu

    def on_open_file_button_clicked(self, object, data=None):
        self.write_on_statusbar("Otwieranie nowych plików.")
        self.controller.open_files()

    def on_open_database_clicked(self, object, records_text=None):
        self.write_on_statusbar("Otwieranie bazy danych.")
        self.controller.open_database()

    def on_open_images_clicked(self, object, data=None):
        self.write_on_statusbar("Przeglądanie obrazów.")
        self.controller.open_images()

    def on_delete_files_clicked(self, object, data=None):
        self.write_on_statusbar("Usuwanie plików.")
        self.controller.clear_data()

    def on_settings_button_clicked(self, object, data=None):
        self.write_on_statusbar("Ustawienia.")
        self.settings_dialog.show()

    def on_documentation_button_clicked(self, object, data=None):
        self.write_on_statusbar("Dokumentacja.")
        self.controller.open_documentation()

    def on_about_button_clicked(self, object, data=None):
        self.write_on_statusbar("O programie.")
        self.about_dialog.show()

    def on_exit_button_clicked(self, object, data=None):
        self.write_on_statusbar("Zakończenie programu.")
        self.controller.exit()
        Gtk.main_quit()

    def on_main_window_destroy(self, object, data=None):
        self.controller.exit()
        Gtk.main_quit()

    # Usuwanie plików z listy

    def button_press_event(self, treeview, event):
        if event.button == 3:
            x = int(event.x)
            y = int(event.y)
            path_info = treeview.get_path_at_pos(x, y)
            self.controller.remove_element(path_info)

    # Obsługa skrótów klawiszowych

    def on_key_press_event(self, widget, event):
        keyname = Gdk.keyval_name(event.keyval)

        # CTRL+q - otwieranie plików
        if event.state & Gdk.ModifierType.CONTROL_MASK and keyname == 'q':
            self.write_on_statusbar("Otwieranie nowych plików.")
            self.controller.open_files()
        # CTRL+w - otwarcie bazy danych
        elif event.state & Gdk.ModifierType.CONTROL_MASK and keyname == 'w':
            self.write_on_statusbar("Otwieranie bazy danych.")
            self.controller.open_database()
        # CTRL+e - otwarcie obrazów
        elif event.state & Gdk.ModifierType.CONTROL_MASK and keyname == 'e':
            self.write_on_statusbar("Przeglądanie obrazów.")
            self.controller.open_images()
        # CTRL+r - czyszczenie danych
        elif event.state & Gdk.ModifierType.CONTROL_MASK and keyname == 'r':
            self.write_on_statusbar("Usuwanie plików.")
            self.controller.clear_data()
        # CTRL+t - ustawienia
        elif event.state & Gdk.ModifierType.CONTROL_MASK and keyname == 't':
            self.write_on_statusbar("Ustawienia.")
            self.settings_dialog.show()
        # CTRL+y - dokumentacja
        elif event.state & Gdk.ModifierType.CONTROL_MASK and keyname == 'y':
            self.write_on_statusbar("Dokumentacja.")
            self.controller.open_documentation()
        # CTRL+u - o programie
        elif event.state & Gdk.ModifierType.CONTROL_MASK and keyname == 'u':
            self.write_on_statusbar("O programie.")
            self.about_dialog.show()
        # CTRL+z - zamknij program
        elif event.state & Gdk.ModifierType.CONTROL_MASK and keyname == 'z':
            self.write_on_statusbar("Zakończenie programu.")
            self.controller.exit()
            Gtk.main_quit()
        # a - odtwarzanie
        elif keyname == 'a':
            if self.play_button.get_sensitive():
                self.write_on_statusbar("Odtwarzanie...")
                self.controller.start_playing()
        # s - pauza
        elif keyname == 's':
            if self.pause_button.get_sensitive():
                self.write_on_statusbar("Pauza")
                self.controller.pause_playing()
        # d - replay
        elif keyname == 'd':
            if self.replay_button.get_sensitive():
                self.write_on_statusbar("Ponowne odtwarzanie...")
                self.controller.replay()
        # f - stop
        elif keyname == 'f':
            if self.stop_button.get_sensitive():
                self.write_on_statusbar("Stop")
                self.controller.stop_playing()
                self.controller.clear_main_image()
        # g - zapis obrazu
        elif keyname == 'g':
            if self.save_image_button.get_sensitive():
                self.write_on_statusbar("Zapisywanie...")
                self.controller.save_image()