示例#1
0
def main():
    pass
# Zip Test
    # archive = zip.Make_presskit("presskit.zip")
    # if archive.Validate_presskit() is True:
    #     archive.make_presskit()
    # else:
    #     print("Something went wrong")
    #
    # archive.options["full"]()

    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())
class Main(QMainWindow):
	def __init__(self):
		QMainWindow.__init__(self)

		# Set up the user interface from Designer
		self.mainWindow = Ui_MainWindow()
		self.mainWindow.setupUi(self)

		# Change the ui
		self.setDefaultValues()
		self.setEvents()

		self.show()

	def setDefaultValues(self):
		# TODO: Make this read from a file
		self.mainWindow.gasJetDiameter.setText("1e-3")
		self.mainWindow.gasJetIntersectionDistance.setText("1e-2")

		self.mainWindow.electronBeamDiameter.setText("1e-3")
		self.mainWindow.electronsCount.setText("1e5")

		self.mainWindow.laserBeamDiameter.setText("1e-2")
		self.mainWindow.laserBeamIntersectionDistance.setText("0.13875")
		self.mainWindow.laserBeamApexLength.setText("15e-2")
		self.mainWindow.laserBeamWavelength.setText("1.064")
		self.mainWindow.laserBeamElectronEnergy.setText("100")
		self.mainWindow.laserBeamPower.setText("2e6")

	def setEvents(self):
		self.mainWindow.graphBins.clicked.connect(self.displayGraph)
		self.mainWindow.graphIntegrals.clicked.connect(self.displayPolarizationAngleVersusIntegral)

	def displayGraph(self):
		scatterSimulation = self.configureScatterSimulation(ScatterSimulation())
		if scatterSimulation is False: return

		scatterSimulation.run()

		print ''.join(['-'] * 30)
		scatterSimulation.printBins()
		print ''.join(['-'] * 30)

		scatterSimulation.plotBins()

	def displayPolarizationAngleVersusIntegral(self, startX = False, stopX = False):
		# TODO: Retrieve this from input
		startX, stopX = -1.42, -0.92

		print "----------Laser Off:----------"
		print "Integral, Error"
		laserOffSimulation = self.configureScatterSimulation(ScatterSimulation())
		if laserOffSimulation is False: return
		laserOffSimulation.laserBeamRadius = 0

		laserOffSimulation.run()

		# Computing integral for when the beam is off...   0: 84877574
		# 11178736.5941
		theoreticalRatioInIntersection = 84877574 / float(10**8)
		calculatedRatioInIntersection = sum(laserOffSimulation.getBins().values()) / laserOffSimulation.electronsCount
		scale = theoreticalRatioInIntersection / calculatedRatioInIntersection

		# TODO: Fix errors.  They are not being computed correctly.
		laserOffIntegral = laserOffSimulation.sumBins(startX, stopX, scale)
		laserOffError = 0
		laserOffP = laserOffIntegral / laserOffSimulation.sumBins(scale = scale)
		print laserOffIntegral, laserOffError
		laserOnSimulation = self.configureScatterSimulation(ScatterSimulation())
		if laserOnSimulation is False: return

		integrals = []
		errors = []
		polarizationAngles = range(0, 91)

		print
		print "----------Laser On:----------"
		print "Angle, Integral, Error, n, p, n * p"
		for polarizationAngle in polarizationAngles:
			laserOnSimulation.laserBeamPolarizationAngleInDegrees = polarizationAngle

			print polarizationAngle,
			laserOnSimulation.run()

			binsIntegral = laserOnSimulation.sumBins(startX, stopX)
			# binsIntegral = laserOnSimulation.sumBins(startX, stopX, includeUnaffected = False)
			integral = binsIntegral - laserOffIntegral
			integrals.append(integral)

			n = laserOnSimulation.affectedByLaserCount
			p = laserOnSimulation.sumBins(startX, stopX, includeUnaffected = False) / laserOnSimulation.affectedByLaserCount
			# p = binsIntegral / laserOnSimulation.affectedByLaserCount

			errors.append(math.sqrt(n * p * (1 - p)))

			print integral, errors[-1], n, p, n * p

			laserOnSimulation.reset()

		import numpy
		import matplotlib.pyplot
		figure = matplotlib.pyplot.figure()
		axii = figure.add_subplot(111)
		# axii.scatter(polarizationAngles, integrals, marker="o")
		axii.errorbar(polarizationAngles, integrals, errors)
		axii.set_xbound(0, 90)
		axii.set_xlabel("Polarization Angle (Degrees)")
		axii.set_ylabel("Integral")
		matplotlib.pyplot.show()

	def configureScatterSimulation(self, scatterSimulation):
		"""Configures the scatter simulation based on the GUI input"""
		try:
			scatterSimulation.gasJetRadius = self.__getNumericFieldValue("gasJetDiameter") / 2.0
			scatterSimulation.gasJetIntersectionDistance = self.__getNumericFieldValue("gasJetIntersectionDistance")
			scatterSimulation.gasJetCosineSquaredDistribution = self.mainWindow.gasJetCosineSquaredDistribution.isChecked()

			scatterSimulation.electronBeamRadius = self.__getNumericFieldValue("electronBeamDiameter") / 2.0
			scatterSimulation.electronsCount = self.__getNumericFieldValue("electronsCount")

			scatterSimulation.laserBeamRadius = self.__getNumericFieldValue("laserBeamDiameter") / 2.0
			scatterSimulation.laserBeamIntersectionDistance = self.__getNumericFieldValue("laserBeamIntersectionDistance")
			scatterSimulation.laserBeamApexLength = self.__getNumericFieldValue("laserBeamApexLength")
			scatterSimulation.laserBeamWavelength = self.__getNumericFieldValue("laserBeamWavelength")
			scatterSimulation.laserBeamElectronEnergy = self.__getNumericFieldValue("laserBeamElectronEnergy")
			scatterSimulation.laserBeamPower = self.__getNumericFieldValue("laserBeamPower")
			scatterSimulation.laserBeamGaussianDistribution = self.mainWindow.laserBeamGaussianDistribution.isChecked()
		except ValueError as exception:
			errorMessage = QMessageBox.critical(self, "Input Error", ('Could not understand the value of the field "%s".\n\nPlease make sure that it\'s a number.' % exception.fieldName))
			return False

		# These are not implemented yet
		scatterSimulation.horizontalAngleInDegrees = 90
		scatterSimulation.maximumBoundLength = 1e10
		scatterSimulation.laserBeamPolarizationAngleInDegrees = 0

		return scatterSimulation

	def __getNumericFieldValue(self, fieldName):
		""" Tries to get the value of fieldName and convert it to a float.  Returns ValueError on failure. """
		try:
			textInBox = vars(self.mainWindow)[fieldName].text()
			numericConversion = float(textInBox)
			return numericConversion
		except ValueError as exception:
			exception.fieldName = fieldName
			raise exception
示例#3
0
class ValidityCheckWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        # # Set up the user interface from Designer.
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        # Set default values
        self.model = None

        # Set default values for validity settings.
        self.validity_settings_date = datetime.now().isoformat()
        self.drop_rows = []
        self.headers = None
        self.headers_index = None
        self.subjects = None
        self.subjects_index = None
        self.dates = None
        self.dates_index = None
        self.validity_questions = None
        self.validity_questions_responses = None

        # Set list of widgets to reset to disabled whenever opening a new data file or clearing all options.
        self._widgets_disable = {
            'group_boxes': [self.ui.settingsGroupBox],
            'sections': [self.ui.validitySaveExport],
            'labels': [],
            'buttons': [],
            'recent_files': [self.ui.openSettingsFileFrame],
            # 'recent_files'    : [self.ui.openRecentDataFileButton, self.ui.openRecentValiditySettingsFileButton],
            'settings_buttons': [
                self.ui.open_remove_rows, self.ui.skipRemoveRows,
                self.ui.open_header_select, self.ui.open_subject_select,
                self.ui.open_date_select, self.ui.skipDateSelect,
                self.ui.open_question_select, self.ui.open_response_select
            ]
        }
        self._widgets_reset = {
            'labels': [],
            'fields': [],
            'recent_files': [
                self.ui.selectRecentDataFileComboBox,
                self.ui.selectRecentValiditySettingsFileComboBox
            ],
            'settings_checkboxes': [
                self.ui.removeRowsCheckBox, self.ui.headersCheckBox,
                self.ui.subjectCheckBox, self.ui.dateCheckBox,
                self.ui.questionsCheckBox, self.ui.responsesCheckBox
            ]
        }
        # Get settings
        self.settings = QSettings()
        try:
            self.recent_file_path = self.settings.value(
                RECENT_FILE_PATH, DEFAULT_PATH, 'QString')
            self.recent_data_files = self.settings.value(
                RECENT_DATA_FILES, [], 'QStringList')
            self.recent_validity_settings_files = self.settings.value(
                RECENT_VALIDITY_SETTINGS_FILES, [], 'QStringList')
        except TypeError as e:
            print(e)
            self.recent_file_path = str(
                self.settings.value(RECENT_FILE_PATH, DEFAULT_PATH))
            self.recent_data_files = list(
                self.settings.value(RECENT_DATA_FILES, []))
            self.recent_validity_settings_files = list(
                self.settings.value(RECENT_VALIDITY_SETTINGS_FILES, []))
        self.recent_data_files = self.update_recent_files(
            combobox=self.ui.selectRecentDataFileComboBox,
            recent_files=self.recent_data_files)
        self.recent_validity_settings_files = self.update_recent_files(
            combobox=self.ui.selectRecentValiditySettingsFileComboBox,
            recent_files=self.recent_validity_settings_files)

        self.ui.actionClearSettingsData.triggered.connect(self.clear_all)
        self.ui.actionClearRecentFiles.triggered.connect(
            self.clear_recent_files)
        self.ui.actionAbout.triggered.connect(self.about_dialog)
        self.ui.openDataFileButton.clicked.connect(self.open_data_file)
        self.ui.openValiditySettingsFileButton.clicked.connect(
            self.open_validity_settings_file)
        self.ui.selectRecentDataFileComboBox \
            .currentIndexChanged \
            .connect(self.check_recent_data_selection)
        self.ui.selectRecentValiditySettingsFileComboBox \
            .currentIndexChanged \
            .connect(self.check_recent_validity_settings_selection)
        self.ui.openRecentDataFileButton \
            .clicked \
            .connect(self.open_recent_data_file)
        self.ui.openRecentValiditySettingsFileButton \
            .clicked \
            .connect(self.open_recent_validity_settings_file)

        self.ui.open_remove_rows.clicked.connect(self.drop_row_dialog)
        self.ui.skipRemoveRows.clicked.connect(self.show_header_select)
        self.ui.open_header_select.clicked.connect(self.header_dialog)
        self.ui.open_subject_select.clicked.connect(self.subject_dialog)
        self.ui.open_date_select.clicked.connect(self.date_dialog)
        self.ui.skipDateSelect.clicked.connect(self.show_questions_select)
        self.ui.open_question_select.clicked.connect(self.question_dialog)
        self.ui.open_response_select.clicked.connect(self.response_dialog)
        self.ui.clearSettings.clicked.connect(self.reset_settings)
        self.ui.saveSettingsButton.clicked.connect(
            self.save_validity_settings_file)
        self.ui.exportValidityReportButton.clicked.connect(
            self.save_validity_report)

    # define protected methods which abstract away from data/settings files
    def _add_recent_file(self, combobox, file_path, recent_files,
                         recent_files_type):
        """
        Generic method to add a new file to the list of recent files for *data* files or *validity settings* files.
         New file is inserted at the start of the `recent_files` list, then calling `self.update_recent_files` with the
         combobox, file path, and recent files' list to perform the updates. Finally, a call to `self._update_settings`
         will update the recent files list in the apps system-wide settings (pyqt5.QtCore.QSettings).
        :param combobox:  pyqt5.Qt.Combobox, the combobox being updated with the new file.
        :param file_path: str, absolute path to the file being added to the recent files list.
        :param recent_files: list, recently used files' absolute paths where the new file path is added.
        :param recent_files_type: str, ('data' or 'validity_settings')
        """
        recent_files.insert(0, file_path)
        recent_files = list(set(recent_files))
        self.update_recent_files(combobox, file_path, recent_files)
        self._update_settings(file_path, recent_files_type, recent_files)

    @staticmethod
    def _check_iter(_item):
        """
        Check if `_item` is iterable. If not, convert to a single-item tuple.
        :param _item:
        :return: iterable variable (list, tuple, set) or single-item tuple.
        """
        if type(_item) not in (list, tuple, set):
            return (_item, )
        return _item

    @staticmethod
    def _check_recent(file_path=None, file_list=None):
        """
        Check if file path(s) (either individually as `file_path` or as a list in `file_list`) are linked to an actual
         file or if orphaned.
        :param file_path:
        :param file_list:
        :return:
        """
        if file_path is not None and not Path(file_path).is_file():
            file_path = None
        if file_list is not None:
            file_list = [
                _file_path for _file_path in file_list
                if Path(_file_path).is_file()
            ]
            file_list = list(set(file_list))
        return file_path, file_list

    @staticmethod
    def _check_selection_and_button(combobox, button):
        button_is_disabled = combobox.currentIndex() < 0
        button.setDisabled(button_is_disabled)

    @staticmethod
    def _reset_combobox(combobox):
        combobox.setCurrentIndex(-1)

    def _toggle_settings(self,
                         disable=None,
                         check_box=None,
                         enable=None,
                         uncheck_box=None):
        for group, _disable in ((disable, True), (enable, False)):
            if group is not None:
                group = self._check_iter(group)
                [button.setDisabled(_disable) for button in group]
        for boxes, state in ((check_box, Qt.Checked), (uncheck_box,
                                                       Qt.Unchecked)):
            if boxes is not None:
                boxes = self._check_iter(boxes)
                [box.setCheckState(state) for box in boxes]

    def _update_settings(self,
                         file_path=None,
                         recent_files_type=None,
                         recent_files=None):
        if file_path is not None:
            self.settings.setValue(RECENT_FILE_PATH, file_path)
        if None not in (recent_files_type, recent_files):
            self.settings.setValue(RECENT_FILES_TYPES[recent_files_type],
                                   recent_files)
        self.settings.sync()

    def update_recent_files(self, combobox, file_path=None, recent_files=None):
        file_path, recent_files = self._check_recent(file_path=file_path,
                                                     file_list=recent_files)
        if file_path is None:
            if recent_files:
                combobox.addItems(recent_files)
            else:
                combobox.clear()
            self._reset_combobox(combobox=combobox)
        else:
            combobox.setCurrentText(file_path)
        return recent_files

    def add_recent_data_file(self, file_path):
        self._add_recent_file(combobox=self.ui.selectRecentDataFileComboBox,
                              file_path=file_path,
                              recent_files=self.recent_data_files,
                              recent_files_type='data')
        self.ui.selectRecentDataFileComboBox.update()

    def add_recent_validity_settings_file(self, file_path):
        self._add_recent_file(
            combobox=self.ui.selectRecentValiditySettingsFileComboBox,
            file_path=file_path,
            recent_files=self.recent_validity_settings_files,
            recent_files_type='validity_settings')
        self.ui.selectRecentValiditySettingsFileComboBox.update()

    def check_recent_selections(self):
        self.check_recent_data_selection()
        self.check_recent_validity_settings_selection()

    def check_recent_data_selection(self):
        self._check_selection_and_button(
            combobox=self.ui.selectRecentDataFileComboBox,
            button=self.ui.openRecentDataFileButton)

    def check_recent_validity_settings_selection(self):
        self._check_selection_and_button(
            combobox=self.ui.selectRecentValiditySettingsFileComboBox,
            button=self.ui.openRecentValiditySettingsFileButton)

    def open_file_dialog(self, file_type):
        return \
            QFileDialog.getOpenFileName(self, f'Open {FILE_TYPES[file_type]["title"]} file',
                                        self.recent_file_path, FILE_TYPES[file_type]["extension"])[0]

    def save_file_dialog(self, file_type):
        return \
            QFileDialog.getSaveFileName(self, f'Save {FILE_TYPES[file_type]["title"]} file',
                                        self.recent_file_path, FILE_TYPES[file_type]["extension"])[0]

    def open_data_file(self, _checked=None, path=None):
        path = self.try_path(path=path, file_type='data')
        if path is None:
            return
        self.clear_all()
        self.set_tables(path)
        self.add_recent_data_file(path)
        self.ui.data_file_location_label.setText(path)
        self.ui.openSettingsFileFrame.setDisabled(False)
        self.show_remove_rows_select()

    def open_validity_settings_file(self, _checked=None, path=None):
        path = self.try_path(path=path, file_type='validity_settings')
        if path is None:
            return
        with open(path, 'r') as f:
            validity_settings = json.load(f)
        self.reset_settings()
        self.validity_settings_date = validity_settings['date_created']
        self.drop_rows = validity_settings['drop_rows']
        self.subjects = validity_settings['subjects']
        self.subjects_index = validity_settings['subjects_index']
        self.headers = validity_settings['headers']
        self.headers_index = validity_settings['headers_index']
        self.dates = validity_settings['dates']
        self.dates_index = validity_settings['dates_index']
        self.validity_questions = validity_settings['validity_questions']
        self.validity_questions_responses = validity_settings[
            'validity_questions_responses']
        if self.drop_rows:
            self.model.removeRow(self.drop_rows)
        if self.headers_index is not None:
            self.set_data_headers(headers_index=self.headers_index)
        if self.subjects_index is not None:
            self.set_data_subjects(subjects_index=self.subjects_index)
        if self.dates_index is not None:
            self.set_data_dates(dates_index=self.dates_index)
        if self.validity_questions is not None:
            self.model.select_columns(columns=self.validity_questions)
        if self.validity_questions_responses is not None:
            self.model.validate_columns(self.validity_questions_responses)
        self.ui.validity_settings_file_location_label.setText(path)
        self.add_recent_validity_settings_file(path)
        self.show_export()
        self.ui.centralWidget.update()
        # for checkbox in self._widgets_reset['settings_checkboxes']:
        #     checkbox.setChecked(True)
        self.hide_all_select()

    def open_recent_data_file(self):
        path = self.ui.selectRecentDataFileComboBox.currentText()
        if path is None:
            return
        self.open_data_file(path=path)

    def open_recent_validity_settings_file(self):
        path = self.ui.selectRecentValiditySettingsFileComboBox.currentText()
        if path is None:
            return
        self.open_validity_settings_file(path=path)

    def save_validity_report(self):
        path = self.try_path(file_type='data', file_dialog='save')
        if path is None:
            return
        self.model.save_file(path)
        self._update_settings(file_path=path)

    def save_validity_settings_file(self, _checked=None):
        path = self.try_path(file_type='validity_settings', file_dialog='save')
        if path is None:
            return
        validity_settings = {
            'date_created': datetime.now().isoformat(),
            'drop_rows': self.drop_rows,
            'subjects': self.subjects,
            'subjects_index': self.subjects_index,
            'headers': self.headers,
            'headers_index': self.headers_index,
            'dates': self.dates,
            'dates_index': self.dates_index,
            'validity_questions': self.validity_questions,
            'validity_questions_responses': self.validity_questions_responses
        }
        self.save_validity_settings(path=path,
                                    validity_settings=validity_settings)
        self.add_recent_validity_settings_file(file_path=path)

    @staticmethod
    def save_validity_settings(path, validity_settings):
        with open(path, 'w') as f:
            json.dump(validity_settings, f)

    def set_data_headers(self, headers_index=None):
        self.headers_index = headers_index
        if headers_index is not None:
            self.headers = self.model.set_headers(header_index=headers_index)
        if self.headers is None:
            self.headers = self.model.headerData(orientation=Qt.Horizontal)

    def set_data_subjects(self, subjects_index=None):
        self.subjects_index = subjects_index
        if subjects_index is not None:
            self.subjects = self.model.set_index(index=subjects_index)
        if self.subjects is None:
            self.subjects = self.model.headerData(orientation=Qt.Vertical)

    def set_data_dates(self, dates_index=None):
        self.dates_index = dates_index
        if dates_index is not None:
            self.dates = self.model.set_dates(index=dates_index)

    def set_tables(self, path):
        self.model = PandasModel(file_path=path)
        self.ui.rawTableView.setModel(self.model.head)
        self.ui.validityReportTableView.setModel(self.model)

    def try_path(self, file_type, path=None, file_dialog='open'):
        if path is not None:
            return path
        if file_dialog == 'open':
            path = self.open_file_dialog(file_type=file_type)
        elif file_dialog == 'save':
            path = self.save_file_dialog(file_type=file_type)
        if path == '':
            return None
        else:
            return path

    def clear_all(self):
        # Set default values
        self.model = None
        self.ui.rawTableView.setModel(None)
        self.ui.validityReportTableView.setModel(None)
        self.reset_settings()
        self.reset_file_widgets()

    def clear_recent_files(self):
        for file_type, combobox in (
            ('data', self.ui.selectRecentDataFileComboBox),
            ('validity_settings',
             self.ui.selectRecentValiditySettingsFileComboBox)):
            self.update_recent_files(combobox=combobox, recent_files=[])
            self._update_settings(recent_files_type=file_type, recent_files=[])

    def reset_settings(self, _checked=None):
        self.drop_rows = []
        self.subjects = None
        self.subjects_index = None
        self.dates = None
        self.dates_index = None
        self.headers = None
        self.headers_index = None
        self.validity_questions = None
        self.validity_questions_responses = None
        self.validity_settings_date = datetime.now().isoformat()
        self.reset_settings_widgets()
        if self.model is not None:
            self.model.reset_data()
            self.show_remove_rows_select()

    @staticmethod
    def _disable(ui_group):
        for disabled_widget in ui_group:
            disabled_widget.setDisabled(True)

    @staticmethod
    def _reset(ui_group):
        for reset_widget in ui_group:
            reset_widget.setChecked(False)

    def reset_file_widgets(self):
        for group in ('group_boxes', 'recent_files'):
            self._disable(ui_group=self._widgets_disable[group])
        for combobox in self._widgets_reset['recent_files']:
            self._reset_combobox(combobox=combobox)
        self.check_recent_selections()
        self.ui.rawTableView.reset()
        self.ui.validityReportTableView.reset()
        self.ui.centralWidget.update()
        self.ui.centralWidget.show()

    def reset_settings_widgets(self):
        self._reset(ui_group=self._widgets_reset['settings_checkboxes'])
        self._disable(ui_group=self._widgets_disable['settings_buttons'])

    def show_data_setup(self):
        self.ui.settingsGroupBox.setDisabled(False)
        self.show_clear_settings()
        self.show_export()

    def show_remove_rows_select(self):
        self.show_data_setup()
        self._toggle_settings(enable=(self.ui.open_remove_rows,
                                      self.ui.skipRemoveRows),
                              uncheck_box=self.ui.removeRowsCheckBox)

    def show_header_select(self):
        self._toggle_settings(disable=(self.ui.open_remove_rows,
                                       self.ui.skipRemoveRows),
                              check_box=self.ui.removeRowsCheckBox,
                              enable=self.ui.open_header_select,
                              uncheck_box=self.ui.headersCheckBox)
        self.show_clear_settings()

    def show_subject_select(self):
        self._toggle_settings(disable=self.ui.open_header_select,
                              check_box=self.ui.headersCheckBox,
                              enable=self.ui.open_subject_select,
                              uncheck_box=self.ui.subjectCheckBox)

    def show_date_select(self):
        self._toggle_settings(disable=self.ui.open_subject_select,
                              check_box=self.ui.subjectCheckBox,
                              enable=(self.ui.open_date_select,
                                      self.ui.skipDateSelect),
                              uncheck_box=self.ui.dateCheckBox)

    def show_questions_select(self):
        self._toggle_settings(disable=(self.ui.open_date_select,
                                       self.ui.skipDateSelect),
                              check_box=self.ui.dateCheckBox,
                              enable=self.ui.open_question_select,
                              uncheck_box=self.ui.questionsCheckBox)

    def show_responses_select(self):
        self._toggle_settings(disable=self.ui.open_question_select,
                              check_box=self.ui.questionsCheckBox,
                              enable=self.ui.open_response_select,
                              uncheck_box=self.ui.responsesCheckBox)

    def hide_all_select(self):
        self._toggle_settings(
            disable=self._widgets_disable['settings_buttons'],
            check_box=self._widgets_reset['settings_checkboxes'])

    def show_clear_settings(self):
        self._toggle_settings(enable=self.ui.clearSettings)

    def show_export(self):
        self._toggle_settings(enable=self.ui.validitySaveExport)

    def drop_row_dialog(self):
        """Launch the question selector dialog."""
        dlg = RowSelectorDialog(self, model=self.model, purpose="drop")
        dlg.exec_()
        if dlg.selected_rows is not None:
            self.model.removeRow(dlg.selected_rows)
            self.drop_rows.extend(dlg.selected_rows)
            self.show_header_select()

    def header_dialog(self):
        """Launch the question selector dialog."""
        dlg = RowSelectorDialog(self, model=self.model, purpose="header")
        dlg.exec_()
        if dlg.selected_rows is not None:
            self.set_data_headers(headers_index=dlg.selected_rows)
            self.headers_index = dlg.selected_rows
            self.show_subject_select()

    def subject_dialog(self):
        """Launch the question selector dialog."""
        dlg = ColumnSelectorDialog(self, model=self.model, purpose="subject")
        dlg.exec_()
        if dlg.selected_column is not None:
            self.set_data_subjects(subjects_index=dlg.selected_column)
            self.subjects_index = dlg.selected_column
            self.show_date_select()

    def date_dialog(self):
        """Launch the question selector dialog."""
        dlg = ColumnSelectorDialog(self, model=self.model, purpose="date")
        dlg.exec_()
        if dlg.selected_column is not None:
            self.set_data_dates(dates_index=dlg.selected_column)
            self.dates_index = dlg.selected_column
            self.show_questions_select()

    def question_dialog(self):
        """Launch the question selector dialog."""
        dlg = QuestionSelectorDialog(self, questions=self.model.get_headers())
        dlg.exec_()
        if dlg.selected_questions is not None:
            self.validity_questions = dlg.selected_questions
            self.model.select_columns(columns=self.validity_questions)
            self.show_responses_select()

    def response_dialog(self):
        """Launch the question selector dialog."""
        dlg = ResponseSelectorDialog(
            self,
            data=self.model.get_data(),
            questions=self.model.get_headers(),
            selected_responses=self.validity_questions_responses)
        dlg.exec_()
        if dlg.selected_responses is not None:
            self.validity_questions_responses = dlg.selected_responses
            self.model.validate_columns(self.validity_questions_responses)
            self.hide_all_select()

    @staticmethod
    def about_dialog():
        about_window = AboutWindow()
        about_window.exec_()
示例#4
0
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.app = QApplication.instance()

        self.__key = get_key()

        if self.__key is None:
            self.app.quit()
        else:
            self.ui = Ui_MainWindow()
            self.ui.setupUi(self)
            self.__setup_ui()

    def __setup_ui(self):
        """Setup UI which isn't setup by self.ui"""

        self.ui.actionEncrypt_file.triggered.connect(self.__encrypt_file)
        self.ui.actionDecrypt_file.triggered.connect(self.__decrypt_file)
        self.ui.actionClose.triggered.connect(self.app.quit)
        self.ui.actionOpen_the_log.triggered.connect(self.__open_log)
        self.ui.actionClear_the_log.triggered.connect(self.__clear_log)
        self.ui.actionAbout.triggered.connect(self.__about)

        self.btn_encrypt = MyToolButton()
        self.btn_encrypt.setIcon(QIcon(icon_path['lock']))
        self.btn_encrypt.setText('加密文件')
        self.btn_encrypt.clicked.connect(self.__encrypt_file)

        self.btn_decrypt = MyToolButton()
        self.btn_decrypt.setIcon(QIcon(icon_path['unlock']))
        self.btn_decrypt.setText('解密文件')
        self.btn_decrypt.clicked.connect(self.__decrypt_file)

        self.btn_open_log = MyToolButton()
        self.btn_open_log.setIcon(QIcon(icon_path['log']))
        self.btn_open_log.setText('查看日志')
        self.btn_open_log.clicked.connect(self.__open_log)

        self.btn_about = MyToolButton()
        self.btn_about.setIcon(QIcon(icon_path['about']))
        self.btn_about.setText('关于')
        self.btn_about.clicked.connect(self.__about)

        self.btn_exit = MyToolButton()
        self.btn_exit.setIcon(QIcon(icon_path['exit']))
        self.btn_exit.setText('退出')
        self.btn_exit.clicked.connect(self.app.quit)

        self.ui.toolBar.addWidget(self.btn_encrypt)
        self.ui.toolBar.addSeparator()
        self.ui.toolBar.addWidget(self.btn_decrypt)
        self.ui.toolBar.addSeparator()
        self.ui.toolBar.addWidget(self.btn_open_log)
        self.ui.toolBar.addSeparator()
        self.ui.toolBar.addWidget(self.btn_about)
        self.ui.toolBar.addSeparator()
        self.ui.toolBar.addWidget(self.btn_exit)

        self.ui.listWidget.setSelectionMode(QListWidget.ExtendedSelection)
        self.__refresh_list()

        self.setCentralWidget(self.ui.centralwidget)

    def __refresh_list(self):
        self.ui.listWidget.clear()
        self.ui.listWidget.addItems(get_encrypted_file_names())

    def __encrypt_file(self):
        """Slot for actionEncrypt_file.triggered and btn_encrypt.clicked"""

        paths = QFileDialog.getOpenFileNames(self, caption='请选择要加密的文件')[0]
        if paths:
            r = QMessageBox.question(self, '确定加密文件',
                                     '<p>所选文件将被加密并保存至保险柜中</p>'
                                     '<p>原文件将被删除, 确定?</p>',
                                     defaultButton=QMessageBox.Yes)
            if r == QMessageBox.Yes:
                for path in paths:
                    try:
                        encrypt_file(path, self.__key)
                    except FileExistsError:
                        QMessageBox.warning(self, '加密错误',
                                            '<p>加密文件</p>'
                                            '<p>%s</p>'
                                            '<p>时发生错误, 因为保险柜中已经有和它同名的文件</p> '
                                            '<p>请将原文件重命名后再试</p>' % path)
                    except OSError:
                        QMessageBox.warning(self, '加密错误',
                                            '<p>加密文件</p>'
                                            '<p>%s</p>'
                                            '<p>时发生错误, 因为没有权限, 无法打开这个文件</p> ' % path)
                self.__refresh_list()

    def __decrypt_file(self):
        """Slot for actionDecrypt_file.triggered and btn_decrypt.clicked"""

        file_names = self.ui.listWidget.selectedItems()
        if not file_names:
            QMessageBox.warning(self, '错误',
                                '<p>没有选择文件</p>'
                                '<p>请选择要解密的文件</p>')
        else:
            QMessageBox.information(self, '提示', '请选择解密后的文件要保存在哪个文件夹')
            dec_path = QFileDialog.getExistingDirectory(self, caption='选择保存路径')
            if dec_path:
                r = QMessageBox.question(self, '确定解密文件',
                                         '<p>所选文件将被解密并保存至所选文件夹中</p>'
                                         '<p>原加密文件将被删除, 确定?</p>',
                                         defaultButton=QMessageBox.Yes)
                if r == QMessageBox.Yes:
                    success = True
                    for file_name in file_names:
                        s = file_name.text()
                        try:
                            decrypt_file(file_name.text() + '.enc', self.__key, dec_path)
                        except FileExistsError:
                            success = False
                            QMessageBox.warning(self, '解密错误',
                                                '<p>解密文件</p>'
                                                '<p>%s</p>'
                                                '<p>时发生错误, 因为所选路径中已经有和它同名的文件</p> '
                                                '<p>请将同名文件移动至别处后再试</p>' % file_name.text())
                        except ValueError:
                            success = False
                            QMessageBox.warning(self, '解密错误',
                                                '<p>解密文件</p>'
                                                '<p>%s</p>'
                                                '<p>时发生错误, 因为该文件验证失败, 可能已损坏</p> '
                                                '<p>损坏的文件已被删除</p>' % file_name.text())

                    self.__refresh_list()
                    if success:
                        QMessageBox.information(self, '完成', '文件已解密完成')

    def __clear_log(self):
        """Slot for actionClear_the_log.triggered"""

        clear_log()
        QMessageBox.information(self, '日志已清除', '日志已清除')

    def __open_log(self):
        """Slot for actionOpen_the_log.triggered and btn_open_log.clicked"""

        self.log_window = LogWindow()
        self.log_window.show()

    def __about(self):
        """Slot for btn_about.clicked"""

        QMessageBox.about(self,
                          '关于文件保险柜',
                          '<p>作者: 袁博实</p>'
                          '<p>学号: U201714853</p>'
                          '<p>使用PyQt5开发</p>'
                          '<p>电子商务与电子政务安全  期末作业</p>')
示例#5
0
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.init_UI()
        # 定义并初始化一些成员变量
        self.data_file_path = ''  # 初始化一个 数据所在的 文件路径
        self.model_file_path = ''  # 初始化一个 模型所在的 文件路径
        self.cache_path = os.getcwd() + '/cache'  # 所有图片等的缓存路径
        self.training_flag = False  # 是否有模型在训练的标志位
        self.model_name = ''  # 初始化一个模型名字
        self.model = ''  # 训练得到的模型
        self.classification_report = ''  # 初始化一个 分类报告
        self.score = ''  # 初始化一个模型得分

    def init_UI(self):
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.ui.pb_select_file.clicked.connect(
            self.select_file)  # 模型训练页面的 选择文件 按钮
        self.ui.pb_visual_data.clicked.connect(self.visual_data)
        self.ui.pb_start_training.clicked.connect(self.start_training)
        self.ui.pb_show_result.clicked.connect(self.show_result)
        self.ui.pb_save_model.clicked.connect(self.save_model)
        self.ui.pb_select_model.clicked.connect(self.select_model)
        self.ui.pb_real_time_diagnosis.clicked.connect(
            self.real_time_diagnosis)
        self.ui.pb_local_diagnosis.clicked.connect(self.local_diagnosis)

    def select_file(self):
        self.ui.pb_select_file.setEnabled(False)
        file_path, _ = QFileDialog.getOpenFileName(
            self,
            '打开文件',  # 标题
            '.',  # 默认开始打开的文件路径, . 表示在当前文件夹下
            '(*.mat)'  # 文件过滤,表示只显示后缀名为 .mat 的文件
        )
        if '' != file_path:  # 选择了文件, 则将路径更新,否则,保留原路径
            self.data_file_path = file_path
            self.ui.tb_train_result.setText('选择文件:' + self.data_file_path +
                                            '\n--------------')
        self.ui.pb_select_file.setEnabled(True)

    def visual_data(self):
        self.ui.pb_visual_data.setEnabled(False)

        if '' == self.data_file_path:  # 没有选择过文件
            reply = QMessageBox.information(self, '提示', '请先选择文件!',
                                            QMessageBox.Yes, QMessageBox.Yes)
            if reply == QMessageBox.Yes:
                self.ui.pb_visual_data.setEnabled(True)
                return  # 直接退出

        visual_data_pic_path = visual_data(self.data_file_path,
                                           self.cache_path)
        # 读取图片文件,进行显示
        img = QImage(visual_data_pic_path)
        img_result = img.scaled(
            self.ui.l_visual_data.width(),
            self.ui.l_visual_data.height(),  # 裁剪图片将图片大小
            Qt.IgnoreAspectRatio,  # 保持长宽比例
            Qt.SmoothTransformation  # 平滑处理,使图片不失真
        )
        self.ui.l_visual_data.setPixmap(QPixmap.fromImage(img_result))
        self.ui.pb_visual_data.setEnabled(True)

    def start_training(self):
        if self.training_flag:  # 有模型在训练
            reply = QMessageBox.information(self, '提示', '正在训练模型,请等待...',
                                            QMessageBox.Yes, QMessageBox.Yes)
            if reply == QMessageBox.Yes:
                return  # 退出函数

        if '' == self.data_file_path:  # 没有选择过文件
            reply = QMessageBox.information(self, '提示', '请先选择文件!',
                                            QMessageBox.Yes, QMessageBox.Yes)
            if reply == QMessageBox.Yes:
                return  # 退出函数

        # 到这里,就是 没有模型在训练,且选择了文件
        # 提示用户确认
        select_model = self.ui.comb_select_model.currentText()  # 用户选择的 模型
        reply = QMessageBox.information(
            self, '提示', '确定使用“' + select_model + '”进行训练。\n请确保所有数据在一个文件夹下!',
            QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
        if reply == QMessageBox.No:
            return  # 退出函数

        # 到这里,可以开始训练了
        self.training_flag = True  # 改变标志位
        self.ui.statusbar.showMessage('正在训练模型...', 120)

        # 不同的模型,参数设置不一样
        if '随机森林' == select_model:
            signal_length = 500
            signal_number = 1000  # 每个类别中要抽取的样本的数量
            normal = False  # 是否标准化
            rate = [0.6, 0.2, 0.2]  # 训练集、测试集、验证集划分比例
        else:
            signal_length = 2048
            signal_number = 1000  # 每个类别中要抽取的样本的数量
            normal = True  # 是否标准化
            rate = [0.7, 0.2, 0.1]  # 训练集、测试集、验证集划分比例
        # 获得数据所在的文件夹  E:/fff/hhh/iii/tt.mat --> tt.mat --> E:/fff/hhh/iii/
        data_path = self.data_file_path.split('/')[-1]  # 先获得文件名
        data_path = self.data_file_path.split(data_path)[0]  # 再去掉文件路径中的文件名

        if '1D_CNN' == select_model:
            self.model_name = '1D_CNN'
            text = self.ui.tb_train_result.toPlainText()  # 获得原本显示的文字
            if test.is_gpu_available():
                self.ui.tb_train_result.setText(
                    text + '\n模型选择:1D_CNN\n检测到GPU可用\n--------------')
            else:
                self.ui.tb_train_result.setText(
                    text + '\n模型选择:1D_CNN\n未检测到可用GPU\n--------------')
            text = self.ui.tb_train_result.toPlainText()  # 获得原本显示的文字
            self.ui.tb_train_result.setText(text +
                                            '\n正在训练模型...\n--------------')

            # 创建子线程,训练模型
            training_thread = threading.Thread(
                target=CNN_1D_training,
                args=(data_path, signal_length, signal_number, normal, rate,
                      self.cache_path, self.model_name))
            # training_thread.setDaemon(True)  # 守护线程
            training_thread.start()
            training_end_signal.send_msg.connect(
                self.training_end_slot)  # 信号与槽连接

        elif 'LSTM' == select_model:
            self.model_name = 'LSTM'
            text = self.ui.tb_train_result.toPlainText()  # 获得原本显示的文字
            if test.is_gpu_available():
                self.ui.tb_train_result.setText(
                    text + '\n模型选择:LSTM\n检测到GPU可用\n--------------')
            else:
                self.ui.tb_train_result.setText(
                    text + '\n模型选择:LSTM\n未检测到可用GPU\n--------------')
            text = self.ui.tb_train_result.toPlainText()  # 获得原本显示的文字
            self.ui.tb_train_result.setText(text +
                                            '\n正在训练模型...\n--------------')

            # 创建子线程,训练模型
            training_thread = threading.Thread(
                target=LSTM_training,
                args=(data_path, signal_length, signal_number, normal, rate,
                      self.cache_path, self.model_name))
            # training_thread.setDaemon(True)  # 守护线程
            training_thread.start()
            training_end_signal.send_msg.connect(
                self.training_end_slot)  # 信号与槽连接

        elif 'GRU' == select_model:
            self.model_name = 'GRU'
            text = self.ui.tb_train_result.toPlainText()  # 获得原本显示的文字
            if test.is_gpu_available():
                self.ui.tb_train_result.setText(
                    text + '\n模型选择:GRU\n检测到GPU可用\n--------------')
            else:
                self.ui.tb_train_result.setText(
                    text + '\n模型选择:GRU\n未检测到可用GPU\n--------------')
            text = self.ui.tb_train_result.toPlainText()  # 获得原本显示的文字
            self.ui.tb_train_result.setText(text +
                                            '\n正在训练模型...\n--------------')

            # 创建子线程,训练模型
            training_thread = threading.Thread(
                target=GRU_training,
                args=(data_path, signal_length, signal_number, normal, rate,
                      self.cache_path, self.model_name))
            # training_thread.setDaemon(True)  # 守护线程
            training_thread.start()
            training_end_signal.send_msg.connect(
                self.training_end_slot)  # 信号与槽连接

        elif '随机森林' == select_model:
            self.model_name = 'random_forest'
            text = self.ui.tb_train_result.toPlainText()  # 获得原本显示的文字
            self.ui.tb_train_result.setText(
                text + '\n模型选择:随机森林\n正在训练模型...\n--------------')

            # 创建子线程,训练模型
            training_thread = threading.Thread(
                target=random_forest_training,
                args=(data_path, signal_length, signal_number, normal, rate,
                      self.cache_path, self.model_name))
            # training_thread.setDaemon(True)  # 守护线程
            training_thread.start()
            training_end_signal.send_msg.connect(
                self.training_end_slot)  # 信号与槽连接

    def training_end_slot(self, msg):
        self.model = msg['model']
        self.classification_report = msg['classification_report']
        self.score = msg['score']

        QMessageBox.information(self, '提示', '训练完成!', QMessageBox.Yes,
                                QMessageBox.Yes)
        self.ui.statusbar.close()
        text = self.ui.tb_train_result.toPlainText()  # 获得原本显示的文字
        self.ui.tb_train_result.setText(text + '\n训练完成,模型得分:' + self.score +
                                        '\n--------------')
        self.ui.l_train_result.setText(self.classification_report)
        self.training_flag = False

    def diagnosis_end_slot(self, msg):
        pred_result = msg['pred_result']
        text = self.ui.tb_diagnosis_result.toPlainText()
        self.ui.tb_diagnosis_result.setText(text + '\n诊断结果:' + pred_result +
                                            '\n--------------')
        self.ui.pb_real_time_diagnosis.setEnabled(True)
        self.ui.pb_local_diagnosis.setEnabled(True)

    def show_result(self):
        if '' == self.model_name:  # 说明还没有训练过模型
            reply = QMessageBox.information(self, '提示', '你还没有训练模型哦!',
                                            QMessageBox.Yes, QMessageBox.Yes)
            if reply == QMessageBox.Yes:
                return

        show_mode = self.ui.buttonGroup.checkedId()
        # print(show_mode)
        # TODO: 这里的 Id 自己测出来的, 应该还有别的方法直接得到所选框的内容
        if -2 == show_mode:  # 展示 分类报告
            self.ui.l_train_result.setText(self.classification_report)
        elif -3 == show_mode:  # 展示 混淆矩阵
            # 读取图片文件,进行显示
            img = QImage(self.cache_path + '/' + self.model_name +
                         '_confusion_matrix.png')
            img_result = img.scaled(
                self.ui.l_train_result.width(),
                self.ui.l_train_result.height(),  # 裁剪图片将图片大小
                Qt.IgnoreAspectRatio,
                Qt.SmoothTransformation)
            self.ui.l_train_result.setPixmap(QPixmap.fromImage(img_result))
        elif -4 == show_mode:  # 展示 ROC曲线
            # 读取图片文件,进行显示
            img = QImage(self.cache_path + '/' + self.model_name +
                         '_ROC_Curves.png')
            img_result = img.scaled(
                self.ui.l_train_result.width(),
                self.ui.l_train_result.height(),  # 裁剪图片将图片大小
                Qt.IgnoreAspectRatio,
                Qt.SmoothTransformation)
            self.ui.l_train_result.setPixmap(QPixmap.fromImage(img_result))
        elif -5 == show_mode:  # 展示 精度召回曲线
            # 读取图片文件,进行显示
            img = QImage(self.cache_path + '/' + self.model_name +
                         '_Precision_Recall_Curves.png')
            img_result = img.scaled(
                self.ui.l_train_result.width(),
                self.ui.l_train_result.height(),  # 裁剪图片将图片大小
                Qt.IgnoreAspectRatio,
                Qt.SmoothTransformation)
            self.ui.l_train_result.setPixmap(QPixmap.fromImage(img_result))
        elif -6 == show_mode:  # 展示 损失曲线
            if 'random_forest' == self.model_name:  # 随机森林没有损失曲线
                QMessageBox.information(self, '提示', '随机森林模型没有损失曲线哦!',
                                        QMessageBox.Yes, QMessageBox.Yes)
            else:
                # 读取图片文件,进行显示
                img = QImage(self.cache_path + '/' + self.model_name +
                             '_train_valid_loss.png')
                img_result = img.scaled(
                    self.ui.l_train_result.width(),
                    self.ui.l_train_result.height(),  # 裁剪图片将图片大小
                    Qt.IgnoreAspectRatio,
                    Qt.SmoothTransformation)
                self.ui.l_train_result.setPixmap(QPixmap.fromImage(img_result))
        elif -7 == show_mode:  # 展示 正确率曲线
            if 'random_forest' == self.model_name:  # 随机森林没有正确率曲线
                QMessageBox.information(self, '提示', '随机森林模型没有正确率曲线哦!',
                                        QMessageBox.Yes, QMessageBox.Yes)
            else:
                # 读取图片文件,进行显示
                img = QImage(self.cache_path + '/' + self.model_name +
                             '_train_valid_acc.png')
                img_result = img.scaled(
                    self.ui.l_train_result.width(),
                    self.ui.l_train_result.height(),  # 裁剪图片将图片大小
                    Qt.IgnoreAspectRatio,
                    Qt.SmoothTransformation)
                self.ui.l_train_result.setPixmap(QPixmap.fromImage(img_result))

    def save_model(self):
        if '' == self.model_name:  # 说明还没有训练过模型
            reply = QMessageBox.information(self, '提示', '你还没有训练模型哦!',
                                            QMessageBox.Yes, QMessageBox.Yes)
            if reply == QMessageBox.Yes:
                return

        if 'random_forest' == self.model_name:
            save_path, _ = QFileDialog.getSaveFileName(
                self,
                '保存文件',  # 标题
                './' + self.model_name +
                '.m',  # 默认开始打开的文件路径, . 表示在当前文件夹下, 后面接的默认文件名
                '(*.m)'  # 文件过滤,表示只显示后缀名为 .mat 的文件
            )
            if '' == save_path:  # 没有确定保存。这里也可以通过 变量 _ 来判断
                return
            # print(save_path)
            joblib.dump(self.model, save_path)  # 存储
        else:
            save_path, _ = QFileDialog.getSaveFileName(
                self, '保存文件', './' + self.model_name + '.h5', '(*.h5)')
            if '' == save_path:  # 没有确定保存。这里也可以通过 变量 _ 来判断
                return
            self.model.save(save_path)
        text = self.ui.tb_train_result.toPlainText()  # 获得原本显示的文字
        self.ui.tb_train_result.setText(text + "\n模型保存成功\n--------------")

    def select_model(self):
        self.ui.pb_select_model.setEnabled(False)
        file_path, _ = QFileDialog.getOpenFileName(self, '选择模型', '.',
                                                   '(*.m *.h5)')
        if '' != file_path:  # 选择了文件, 则将路径更新,否则,保留原路径
            self.model_file_path = file_path
            self.ui.tb_diagnosis_result.setText('选择文件:' +
                                                self.model_file_path +
                                                '\n--------------')
        self.ui.pb_select_model.setEnabled(True)

    def real_time_diagnosis(self):
        self.ui.pb_real_time_diagnosis.setEnabled(False)
        self.ui.pb_local_diagnosis.setEnabled(False)  # 同一时间只能进行一种诊断

        if '' == self.model_file_path:  # 没有选择过模型
            reply = QMessageBox.information(self, '提示', '你还没有选择模型哦!',
                                            QMessageBox.Yes, QMessageBox.Yes)
            if QMessageBox.Yes == reply:
                self.ui.pb_real_time_diagnosis.setEnabled(True)
                self.ui.pb_local_diagnosis.setEnabled(True)
                return

        text = self.ui.tb_diagnosis_result.toPlainText()
        self.ui.tb_diagnosis_result.setText(text +
                                            '\n实时诊断:正在采集数据...\n--------------')

        # TODO: 这里通过读取指定的文件夹数据来模拟实时采集数据
        real_time_data_path = os.getcwd(
        ) + '/real_time_data/0HP/48k_Drive_End_B007_0_122.mat'

        # 读取完数据后,自动可视化数据
        visual_data_pic_path = visual_data(real_time_data_path,
                                           self.cache_path)
        # 读取图片文件,进行显示
        img = QImage(visual_data_pic_path)
        img_result = img.scaled(
            self.ui.l_visual_diagnosis_data.width(),
            self.ui.l_visual_diagnosis_data.height(),  # 裁剪图片将图片大小
            Qt.IgnoreAspectRatio,
            Qt.SmoothTransformation)
        self.ui.l_visual_diagnosis_data.setPixmap(
            QPixmap.fromImage(img_result))
        text = self.ui.tb_diagnosis_result.toPlainText()
        self.ui.tb_diagnosis_result.setText(text +
                                            '\n实时诊断:正在诊断..\n--------------')

        # 开个子线程进行故障诊断
        diagnosis_end_signal.send_msg.connect(
            self.diagnosis_end_slot)  # 信号与槽连接
        diagnosis_thread = threading.Thread(target=fault_diagnosis,
                                            args=(self.model_file_path,
                                                  real_time_data_path))
        diagnosis_thread.start()

    def local_diagnosis(self):
        self.ui.pb_local_diagnosis.setEnabled(False)
        self.ui.pb_real_time_diagnosis.setEnabled(False)  # 同一时间只能进行一种诊断

        file_path, _ = QFileDialog.getOpenFileName(self, '选择数据', '.',
                                                   '(*.mat)')
        if '' == file_path:  # 没有选择文件,也就是退出了本地诊断
            self.ui.pb_real_time_diagnosis.setEnabled(True)
            self.ui.pb_local_diagnosis.setEnabled(True)
            return

        text = self.ui.tb_diagnosis_result.toPlainText()
        self.ui.tb_diagnosis_result.setText(text + '\n选择文件:' + file_path +
                                            '\n--------------')

        if '' == self.model_file_path:  # 没有选择过模型
            reply = QMessageBox.information(self, '提示', '你还没有选择模型哦!',
                                            QMessageBox.Yes, QMessageBox.Yes)
            if QMessageBox.Yes == reply:
                self.ui.pb_real_time_diagnosis.setEnabled(True)
                self.ui.pb_local_diagnosis.setEnabled(True)
                return

        text = self.ui.tb_diagnosis_result.toPlainText()
        self.ui.tb_diagnosis_result.setText(text +
                                            '\n本地诊断:正在读取数据...\n--------------')

        # 读取完数据后,自动可视化数据
        visual_data_pic_path = visual_data(file_path, self.cache_path)
        # 读取图片文件,进行显示
        img = QImage(visual_data_pic_path)
        img_result = img.scaled(
            self.ui.l_visual_diagnosis_data.width(),
            self.ui.l_visual_diagnosis_data.height(),  # 裁剪图片将图片大小
            Qt.IgnoreAspectRatio,
            Qt.SmoothTransformation)
        self.ui.l_visual_diagnosis_data.setPixmap(
            QPixmap.fromImage(img_result))

        text = self.ui.tb_diagnosis_result.toPlainText()
        self.ui.tb_diagnosis_result.setText(text +
                                            '\n实时诊断:正在诊断..\n--------------')

        # 开个子线程进行故障诊断
        diagnosis_end_signal.send_msg.connect(
            self.diagnosis_end_slot)  # 信号与槽连接
        diagnosis_thread = threading.Thread(target=fault_diagnosis,
                                            args=(self.model_file_path,
                                                  file_path))
        diagnosis_thread.start()

    def closeEvent(self, event):
        '''
        重写关闭窗口函数:在点击关闭窗口后,将缓存文件夹下的文件全部删除
        :param event:
        :return:
        '''
        file_names = os.listdir(self.cache_path)
        for file_name in file_names:
            os.remove(self.cache_path + '/' + file_name)

        sys.exit()
示例#6
0
class Main_Window(QtWidgets.QMainWindow):
    def __init__(self):
        QtWidgets.QWidget.__init__(self)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        #виджеты главного окна
        self.ui.pushButton_1.clicked.connect(self.add_frequence)
        self.ui.treeWidget.itemClicked.connect(self.item_on_clicked)
        self.ui.pushButton_2.clicked.connect(self.delete_frequence)
        self.ui.pushButton_3.clicked.connect(self.choice_file)
        self.ui.pushButton_4.clicked.connect(self.save_frequence_file)
        self.ui.pushButton_5.clicked.connect(self.make_rec)  # для расчета
        self.ui.pushButton_6.clicked.connect(self.open_project)
        self.ui.pushButton_7.clicked.connect(self.save_project)
        self.ui.menu_options.triggered.connect(self.options_window)
        self.ui.menu_antena.triggered.connect(self.options_antenns)
        self.ui.eksport_word.triggered.connect(self.eksport_word_func)
        #изменение объекта древа
        self.ui.treeWidget.itemChanged.connect(self.rename_item_on_itemChanged)

    #обработка изменения переименования частоты
    #добавляет файл .txt и удаляет старый .txt
    def rename_item_on_itemChanged(self, item):
        #проверка на выделенный объект
        # try:
        items = self.ui.treeWidget.selectedItems()
        if float(item.text(0)) < 100:
            error = QtWidgets.QMessageBox(
                QtWidgets.QMessageBox.Information, 'Ошибка',
                'Частота не может быть меньше 100, задайте другую частоту: rename_item_on_itemChanged',
                QtWidgets.QMessageBox.Ok)
            error.exec_()
        name = float(item.text(0))
        # save_folder = str(sys.argv)[2:str(sys.argv).rfind('/') + 1] + 'Files/' + item.text(0) + '.txt'
        save_folder = str(sys.argv)[2:str(sys.argv).rfind('/') +
                                    1] + 'Files/' + str(name) + '.txt'
        arr = np.array([])

        if items:
            item_first = self.ui.tableWidget.item(0, 0)
            if item_first != None:
                # создаем новый файл с новой частотой
                for row in range(0, self.ui.tableWidget.rowCount()):
                    for column in range(0, self.ui.tableWidget.columnCount()):
                        item = self.ui.tableWidget.item(row, column)
                        arr = np.append(arr, item.text())
                arr = np.array(arr, dtype=np.float64)
                arr = np.reshape(arr, [self.ui.tableWidget.rowCount(), 3])
                with open(save_folder, 'w') as file:
                    for line in arr:
                        for x in line:
                            print(x, file=file, end='\t')
                        print('\n', file=file, end='')
                print('file created success')
                # удаляем прошлый файл с частотой
                mas_f = os.listdir(save_folder[:save_folder.rfind('/') + 1])
                mas_f_real = np.array([])

                # считываем по-элементно

                for x in range(0, self.ui.treeWidget.topLevelItemCount()):
                    item = self.ui.treeWidget.topLevelItem(x)
                    mas_f_real = np.append(mas_f_real,
                                           str(float(item.text(0))))

                # добавляем .txt
                for x in range(0, len(mas_f_real)):
                    mas_f_real[x] = mas_f_real[x] + '.txt'

                # вычисляем лишний файл
                file_name = str(set.difference(set(mas_f),
                                               set(mas_f_real)))[2:-2]
                try:
                    os.remove(
                        str(sys.argv)[2:str(sys.argv).rfind('/') + 1] +
                        'Files/' + file_name)
                except:
                    pass

            else:
                # создаем новый пустой файл .txt
                with open(save_folder, 'w') as file:
                    file.close()
                # удаляем прошлый файл с частотой
                mas_f = os.listdir(save_folder[:save_folder.rfind('/') + 1])
                mas_f_real = np.array([])
                # считываем по-элементно
                for x in range(0, self.ui.treeWidget.topLevelItemCount()):
                    item = self.ui.treeWidget.topLevelItem(x)
                    mas_f_real = np.append(mas_f_real,
                                           str(float(item.text(0))))
                # добавляем .txt
                for x in range(0, len(mas_f_real)):
                    mas_f_real[x] = mas_f_real[x] + '.txt'
                # вычисляем лишний файл
                file_name = str(set.difference(set(mas_f),
                                               set(mas_f_real)))[2:-2]
                os.remove(
                    str(sys.argv)[2:str(sys.argv).rfind('/') + 1] + 'Files/' +
                    file_name)

            self.ui.statusbar.showMessage('Частота успешно переименована')

        # except:
        #     error = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Information, 'Ошибка', 'Ошибка переименования частоты : rename_item_on_itemChanged',
        #                                   QtWidgets.QMessageBox.Ok)
        #     error.exec_()

    #инициализация стандартных настроект переменных, запускается один раз при старте программ
    def init_settings(self):
        #глобальный доступ к словарю с переменными
        global settings_dict
        keys = []
        values = []
        # считывает переменные из settings.txt
        settings_folder = str(
            sys.argv)[2:str(sys.argv).rfind('/') + 1] + 'setup/settings.txt'
        # создаем словарь для доступа к данным
        try:
            file = np.loadtxt(settings_folder, delimiter='=', dtype=np.unicode)
            for line in file:
                keys.append(line[0])
                values.append(line[1])
            settings_dict = dict(zip(keys, values))
            #строка состояния
            self.ui.statusbar.showMessage('Настройки загружены')
        # если не удается прочитать словарь...
        except:
            error = QtWidgets.QMessageBox(
                QtWidgets.QMessageBox.Information, 'Ошибка',
                'Ошибка инициализации словаря переменных : init_settings',
                QtWidgets.QMessageBox.Ok)
            error.exec_()

    #открывает окно настроект антенн
    def options_antenns(self):
        global antenns_dict  #массив с выбранными антеннами для расчета
        self.window = menu_antenns_options_window()
        #инициализация = файл с антеннами
        self.window.init_settings()
        self.window.show()
        # #инициализация данных в listwidget
        settings_folder = str(
            sys.argv)[2:str(sys.argv).rfind('/') + 1] + 'antens/'
        self.window.listWidget.clear()
        for file in antenn_files:
            self.window.listWidget.addItem(file)
        self.window.listWidget.update()
        #инициализация данных в combo-boxs
        self.window.comboBox.clear()
        self.window.comboBox.addItems(antenn_files)
        self.window.comboBox.update()
        self.window.comboBox_2.addItems(antenn_files)
        self.window.comboBox_2.update()
        self.window.comboBox_3.addItems(antenn_files)
        self.window.comboBox_3.update()
        self.window.comboBox_4.addItems(antenn_files)
        self.window.comboBox_4.update()
        self.window.show()

        result = self.window.exec()
        # print(result)
        if result == 1:
            #инициализация массива работающих антенн
            keys = ['PRM_NH', 'PRM_VH', 'PRD_NH', 'PRD_VH']
            values = []
            values.append(self.window.comboBox.currentText())
            values.append(self.window.comboBox_2.currentText())
            values.append(self.window.comboBox_3.currentText())
            values.append(self.window.comboBox_4.currentText())
            antenns_dict = dict(zip(keys, values))
            #заполняем поля выбранными антеннами в проекте на главном окне
            self.ui.lineEdit_3.setText(str(antenns_dict['PRM_NH']))
            self.ui.lineEdit_3.update()
            self.ui.lineEdit_5.setText(str(antenns_dict['PRM_VH']))
            self.ui.lineEdit_5.update()
            self.ui.lineEdit_4.setText(str(antenns_dict['PRD_NH']))
            self.ui.lineEdit_4.update()
            self.ui.lineEdit_6.setText(str(antenns_dict['PRD_VH']))
            self.ui.lineEdit_6.update()
            #чек бокс ставим на true
            self.ui.checkBox.setChecked(True)
            self.ui.checkBox.update()
            # print(antenns_dict)

    # открывает окно настроек_переменных из меню
    def options_window(self):
        self.window = menu_options_window()
        #путь к файлу настроек settings.txt
        settings_folder = str(
            sys.argv)[2:str(sys.argv).rfind('/') + 1] + 'setup/settings.txt'
        # print(settings_folder)
        #задaем значения полям
        try:
            self.window.doubleSpinBox.setValue(float(settings_dict['Rprd']))
            self.window.doubleSpinBox_2.setValue(float(settings_dict['Rprm']))
            self.window.doubleSpinBox_3.setValue(float(settings_dict['Gym']))
            self.window.doubleSpinBox_4.setValue(
                float(settings_dict['Pgvc_AR_stac']))
            self.window.doubleSpinBox_5.setValue(
                float(settings_dict['Pgvc_AR_port']))

            # настройка combobox-a
            if settings_dict['typeVP'] == 'ВП с СЗУ':
                self.window.comboBox.setCurrentIndex(0)  # выбрать 0ый итем
            elif settings_dict['typeVP'] == 'ВП без СЗУ':
                self.window.comboBox.setCurrentIndex(1)  # выбрать 1ый итем

            self.window.show()

            result = self.window.exec_()
            # print(result)

            if result == 1:  # это Ok
                # считываем новые данные из полей
                settings_dict['Rprd'] = self.window.doubleSpinBox.value()
                settings_dict['Rprm'] = self.window.doubleSpinBox_2.value()
                settings_dict['Gym'] = self.window.doubleSpinBox_3.value()
                settings_dict[
                    'Pgvc_AR_stac'] = self.window.doubleSpinBox_4.value()
                settings_dict[
                    'Pgvc_AR_port'] = self.window.doubleSpinBox_5.value()
                settings_dict['typeVP'] = self.window.comboBox.currentText()
                with open(settings_folder, 'w') as file:
                    for key in settings_dict.keys():
                        print(key + '=' + str(settings_dict[key]),
                              file=file,
                              end='\n')
                self.ui.statusbar.showMessage(
                    'Настройки успешно сохранены в проект')
            elif result != 0:
                print('ошибка сохранения словаря settings')
                return

        # если файл settings будет изменен, ошибка словаря
        except:
            error = QtWidgets.QMessageBox(
                QtWidgets.QMessageBox.Information, 'Ошибка',
                'Ошибка словаря переменных : options_window',
                QtWidgets.QMessageBox.Ok)
            error.exec_()

    #добавить частоту
    def add_frequence(self):
        # ok - флаг
        try:
            frequence, ok = QtWidgets.QInputDialog.getDouble(
                QtWidgets.QWidget(), 'Окно ввода', 'Введите частоту ВЧО в МГц')
            #проверка на частоту
            if frequence < 100:
                error = QtWidgets.QMessageBox(
                    QtWidgets.QMessageBox.Information, 'Ошибка',
                    'Вводимая частота не может быть меньше 100 МГц',
                    QtWidgets.QMessageBox.Ok)
                error.exec()
                return

            frequence = str(frequence)

            if not ok:
                return
            tree_row = QtWidgets.QTreeWidgetItem(self.ui.treeWidget)
            tree_row.setText(0, frequence)
            tree_row.setTextAlignment(0, QtCore.Qt.AlignCenter)
            tree_row.setFlags(tree_row.flags() | QtCore.Qt.ItemIsEditable)
            # tree_row.setFlags(tree_row.flags()| QtCore.Qt.ItemIsUserCheckable)
            tree_row.setCheckState(0, QtCore.Qt.Unchecked)
            self.ui.treeWidget.update()

            #создаем файл при создании частоты
            with open(
                    str(sys.argv)[2:str(sys.argv).rfind('/') + 1] + 'Files/' +
                    frequence + '.txt', 'w') as file:
                file.close()
            self.ui.statusbar.showMessage('Частота успешно добавлена')
        except:
            error = QtWidgets.QMessageBox(
                QtWidgets.QMessageBox.Information, 'Ошибка',
                'Ошибка добавления частоты : add_frequence',
                QtWidgets.QMessageBox.Ok)
            error.exec_()

    #удалить частоту
    def delete_frequence(self):

        items = self.ui.treeWidget.selectedItems()
        root = self.ui.treeWidget.invisibleRootItem()
        if not items: return
        for item in items:
            root.removeChild(item)
            # print(item.text(0))
            #также удаляет файл txt
            try:
                os.remove(
                    str(sys.argv)[2:str(sys.argv).rfind('/') + 1] + 'Files/' +
                    str(float(item.text(0))) + '.txt')
                self.ui.statusbar.showMessage('Частота успешно удалена')
                # print(str(sys.argv)[2:str(sys.argv).rfind('/') + 1] + 'Files/' + item.text() + '.txt')
            except:
                error = QtWidgets.QMessageBox(
                    QtWidgets.QMessageBox.Information, 'Ошибка',
                    'Ошибка удаления частоты : delete_frequence',
                    QtWidgets.QMessageBox.Ok)
                error.exec_()

    #выбрать файл для загрузки данных в таблицу по выбранной частоте
    def choice_file(self):
        masF = [125, 275, 525, 1025, 2075, 4175, 8375]
        file, _ = QtWidgets.QFileDialog.getOpenFileName(directory='')
        if not file:
            return
        self.ui.lineEdit_2.setText(file)
        try:
            file_np = np.loadtxt(file)
            row = 0
            self.ui.tableWidget.clear()
            #задаем горизонтальные хедеры после clear, так как они обнулятся
            item = QtWidgets.QTableWidgetItem()
            item.setText('F')
            self.ui.tableWidget.setHorizontalHeaderItem(0, item)
            item = QtWidgets.QTableWidgetItem()
            item.setText('Uc_w')
            self.ui.tableWidget.setHorizontalHeaderItem(1, item)
            item = QtWidgets.QTableWidgetItem()
            item.setText('Uw')
            self.ui.tableWidget.setHorizontalHeaderItem(2, item)

            #заполняем таблицу и задаем выравнивание
            for field in masF:
                item = QtWidgets.QTableWidgetItem(str(field))
                item.setTextAlignment(QtCore.Qt.AlignCenter)
                self.ui.tableWidget.setItem(row, 0, item)
                row += 1
            row = 0
            for Pc_w, Pw in file_np:
                column = 1
                item = QtWidgets.QTableWidgetItem(str(Pc_w))
                item.setTextAlignment(QtCore.Qt.AlignCenter)
                self.ui.tableWidget.setItem(row, column, item)
                column = 2
                item = QtWidgets.QTableWidgetItem(str(Pw))
                item.setTextAlignment(QtCore.Qt.AlignCenter)
                self.ui.tableWidget.setItem(row, column, item)
                row += 1
            self.ui.statusbar.showMessage('Файл данных успешно загружен')
        except:
            error = QtWidgets.QMessageBox(
                QtWidgets.QMessageBox.Information, 'Ошибка',
                'Выбран неккоректный файл с данными', QtWidgets.QMessageBox.Ok)
            error.exec()

    #сохранить частоту
    def save_frequence_file(self):
        try:
            item = self.ui.treeWidget.selectedItems()[0]
            item.setCheckState(0, QtCore.Qt.Checked)
            self.ui.treeWidget.update()
            save_folder = str(sys.argv)[2:str(sys.argv).rfind('/') +
                                        1] + 'Files/' + item.text(0) + '.txt'
            arr = np.array([])
            for row in range(0, self.ui.tableWidget.rowCount()):
                for column in range(0, self.ui.tableWidget.columnCount()):
                    item = self.ui.tableWidget.item(row, column)
                    arr = np.append(arr, item.text())
            arr = np.array(arr, dtype=np.float64)
            arr = np.reshape(arr, [self.ui.tableWidget.rowCount(), 3])
            with open(save_folder, 'w') as file:
                for line in arr:
                    for x in line:
                        print(x, file=file, end='\t')
                    print('\n', file=file, end='')
            self.ui.statusbar.showMessage(
                'Данные успешно сохранены в выбранную частоту')
        except:
            error = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Information,
                                          'Ошибка',
                                          'Необходимо выделить частоту ВЧО',
                                          QtWidgets.QMessageBox.Ok)
            error.exec()

    #действие при нажатии на частоту в древе
    def item_on_clicked(self, item):
        freq = str(float(item.text(0)))
        self.ui.tableWidget.clear()
        #задаем горизонтальные хедеры после clear, так как они обнулятся
        item = QtWidgets.QTableWidgetItem()
        item.setText('F')
        self.ui.tableWidget.setHorizontalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        item.setText('Uc_w')
        self.ui.tableWidget.setHorizontalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        item.setText('Uw')
        self.ui.tableWidget.setHorizontalHeaderItem(2, item)
        try:
            open_folder = str(sys.argv)[2:str(sys.argv).rfind('/') +
                                        1] + 'Files/' + freq + '.txt'
            a = np.loadtxt(open_folder)
            for row in range(0, len(a)):
                for column in range(0, len(a[0])):
                    item = QtWidgets.QTableWidgetItem(str(a[row][column]))
                    item.setTextAlignment(QtCore.Qt.AlignCenter)
                    self.ui.tableWidget.setItem(row, column, item)
        except:
            error = QtWidgets.QMessageBox(
                QtWidgets.QMessageBox.Information, 'Ошибка',
                'Открыт пустой файл либо не выбрана частота ВЧО',
                QtWidgets.QMessageBox.Ok)
            error.exec()

    #сохранить проект
    def save_project(self):
        Files_dir = str(sys.argv)[2:str(sys.argv).rfind('/') + 1] + 'Files/'
        frequences = os.listdir('Files/')  #массив файлов проекта
        # если забита хоть одна частота в проекте
        if frequences:
            project_name, _ = QtWidgets.QFileDialog.getSaveFileName(
                self, 'Сохранить как', '')
            if project_name[-3:] != '.ap':
                project_name = project_name + '.ap'
            if not project_name:
                return
            with open(project_name, 'w') as wfile:
                for freq in frequences:
                    with open(Files_dir + freq, 'r') as rfile:
                        print('[' + freq[:-4] + ']', file=wfile, end='\n')
                        for line in rfile:
                            print(line, file=wfile, sep='\t', end='')
                        print('\n', file=wfile, end='')
                #запись Pgvc
                print('Pgvc=',
                      str(self.ui.doubleSpinBox.value()),
                      file=wfile,
                      sep='',
                      end='')
            self.ui.statusbar.showMessage('Проект успешно сохранен')
        # если нет частот ошибка
        else:
            error = QtWidgets.QMessageBox(
                QtWidgets.QMessageBox.Information, 'Ошибка',
                'Файл проекта не содержит частот ВЧО',
                QtWidgets.QMessageBox.Ok)
            error.exec()

    #загрузить проект
    def open_project(self):
        try:
            #Очищаем папку Files
            if os.listdir('Files/'):
                for file in os.listdir('Files/'):
                    os.remove(
                        str(sys.argv)[2:str(sys.argv).rfind('/') + 1] +
                        'Files/' + file)
            #Рабочие папки
            save_folder = str(
                sys.argv)[2:str(sys.argv).rfind('/') + 1] + 'Files/'
            open_folder, ok = QtWidgets.QFileDialog.getOpenFileName(
                self, 'Выберите файл проекта', '', 'AP Files (*.ap)')
            if not ok:
                return
            #массив для частот
            masf = []
            #открываем файл проекта, разделяем на частоты и отдельные файлы для заполнения tableWidget и ListWidget
            with open(open_folder, 'r') as file:
                for line in file:
                    if line[0] == '[':
                        freq = line[1:-2]
                        masf.append(line[1:-2])
                    elif (line[0] != '\n' and line[0] != 'P'):
                        with open(save_folder + freq + '.txt', 'a') as wfile:
                            print(line, file=wfile, end='')
                    elif line[0] == 'P':
                        self.ui.doubleSpinBox.setValue(
                            float(line.strip('Pgvc=')))

        except:
            error = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Information,
                                          'Ошибка', 'Ошибка открытия проекта',
                                          QtWidgets.QMessageBox.Ok)
            error.exec()

        #заполняем ListWidget
        try:
            self.ui.treeWidget.clear()
            for x in masf:
                tree_row = QtWidgets.QTreeWidgetItem(self.ui.treeWidget)
                tree_row.setText(0, x)
                tree_row.setTextAlignment(0, QtCore.Qt.AlignCenter)
                tree_row.setFlags(tree_row.flags() | QtCore.Qt.ItemIsEditable)
                #tree_row.setFlags(tree_row.flags()| QtCore.Qt.ItemIsUserCheckable)
                tree_row.setCheckState(0, QtCore.Qt.Checked)
                self.ui.treeWidget.update()
            self.ui.statusbar.showMessage('Проект успешно загружен')
        except:
            error = QtWidgets.QMessageBox(
                QtWidgets.QMessageBox.Information, 'Ошибка',
                'Ошибка заполнения данных в таблицу из загружаемого проекта',
                QtWidgets.QMessageBox.Ok)
            error.exec()

    #проводить расчет
    def make_rec(self):
        #проверка чекбокса и задано ли значение Pgvc
        if (self.ui.checkBox.isChecked()
                and self.ui.doubleSpinBox.value() != ''):
            self.ui.statusbar.showMessage(
                'Производится расчет, дождитесь окончания процесса...')
            # try:
            # массив частот ВЧО
            mas_fj = os.listdir('Files/')
            for x in range(0, len(mas_fj)):
                mas_fj[x] = mas_fj[x].rstrip('.txt')

            mas_fj = np.array(mas_fj, dtype=np.float64)
            # print(mas_fj)
            # print(type(mas_fj))

            # переменные ТХ ВЧО противника
            # постоянные переменные из словаря settings_dict
            Pgvc_AR_stac = float(settings_dict['Pgvc_AR_stac'])
            Pgvc_AR_port = float(settings_dict['Pgvc_AR_port'])
            Rprd = float(settings_dict['Rprd'])
            Rprm = float(settings_dict['Rprm'])
            Gym = float(settings_dict['Gym'])
            typeVP = settings_dict['typeVP']

            # значение Pgvc, задается в doublespinbox пользователем
            Pgvc = self.ui.doubleSpinBox.value()

            # калибровочные коэффициенты антенн, из файлов выбранных антенн в папке antens
            # keys = ['PRM_NH', 'PRM_VH', 'PRD_NH', 'PRD_VH']
            # print(antenns_dict['PRM_NH'], antenns_dict['PRM_VH'], antenns_dict['PRD_NH'], antenns_dict['PRD_VH'])
            antenn_folder = str(
                sys.argv)[2:str(sys.argv).rfind('/') + 1] + 'antens/'
            Ka_prm_NH = np.loadtxt(antenn_folder + antenns_dict['PRM_NH'] +
                                   '.txt',
                                   delimiter='\t')
            Ka_prm_VH = np.loadtxt(antenn_folder + antenns_dict['PRM_VH'] +
                                   '.txt',
                                   delimiter='\t')
            Ka_prm_NH = Ka_prm_NH[:
                                  -1]  # обрезаем конец, чтобы взять его из антенны ВЧ
            Ka_prm = np.append(Ka_prm_NH, Ka_prm_VH).reshape(
                len(Ka_prm_NH) + len(Ka_prm_VH), 2)
            Ka_prd_NH = np.loadtxt(antenn_folder + antenns_dict['PRD_NH'] +
                                   '.txt',
                                   delimiter='\t')
            Ka_prd_VH = np.loadtxt(antenn_folder + antenns_dict['PRD_VH'] +
                                   '.txt',
                                   delimiter='\t')
            Ka_prd_NH = Ka_prd_NH[:
                                  -1]  # обрезаем конец, чтобы взять его из антенны ВЧ
            Ka_prd = np.append(Ka_prd_NH, Ka_prd_VH).reshape(
                len(Ka_prd_NH) + len(Ka_prd_VH), 2)

            # счетчик f для tablewidget_2
            count_t2 = 0
            # счетчик f для tablewindget_3
            count_t3 = 0
            # self.ui.tableWidget_2.clear()
            # self.ui.tableWidget_3.clear()
            # заполнение tablewidget_2
            # задаем кол-во строк = len(f) * 7
            self.ui.tableWidget_2.setRowCount(len(mas_fj) * 7)
            # rows_t2 = self.ui.tableWidget_2.rowCount()  # строки
            # columns_t2 = self.ui.tableWidget_2.columnCount()  # столбцы
            # заполнение tablewidget_3
            # задаем кол-во строк = len(f) * 2
            self.ui.tableWidget_3.setRowCount(len(mas_fj) * 2)
            # 1 столбец - тип; стац + порт
            item = QtWidgets.QTableWidgetItem('Стационарные')
            item.setTextAlignment(QtCore.Qt.AlignCenter)
            self.ui.tableWidget_3.setItem(0, 0, item)
            item = QtWidgets.QTableWidgetItem('Портативно-\nвозимые')
            item.setTextAlignment(QtCore.Qt.AlignCenter)
            self.ui.tableWidget_3.setItem(0 + len(mas_fj), 0, item)
            rows_t3 = self.ui.tableWidget_3.rowCount()  # строки
            # columns_t3 = self.ui.tableWidget_3.columnCount()  # столбцы

            for fj in mas_fj:
                print(fj)
                Pcw = np.zeros(7)  # 7 - так как известно, что будет 7 чисел
                Pw = np.zeros(7)
                freqs_folder = str(sys.argv)[2:str(sys.argv).rfind('/') +
                                             1] + 'Files/' + str(fj) + '.txt'
                # загрузка данных из файла
                mas = np.loadtxt(freqs_folder)
                for x in range(0, len(mas)):
                    Pcw[x] = mas[x][1]
                    Pw[x] = mas[x][2]

                result = main_copm(fj, Pcw, Pw, Pgvc, Ka_prd, Ka_prm,
                                   Pgvc_AR_stac, Pgvc_AR_port, Rprd, Rprm, Gym,
                                   typeVP)
                # print(result)
                # данные с result : R_stac, R_port, Gprd, Gprm, Fi, Pc, qokt
                # заполнение tablewidget_2

                # 1 столбец - частота
                item = QtWidgets.QTableWidgetItem(str(fj))
                item.setTextAlignment(QtCore.Qt.AlignCenter)
                self.ui.tableWidget_2.setItem(count_t2, 0, item)
                # 2 столбец - Gprd
                item = QtWidgets.QTableWidgetItem(str(np.around(result[2], 3)))
                item.setTextAlignment(QtCore.Qt.AlignCenter)
                self.ui.tableWidget_2.setItem(count_t2, 1, item)
                # 3 столбец - Gprm
                item = QtWidgets.QTableWidgetItem(str(np.around(result[3], 3)))
                item.setTextAlignment(QtCore.Qt.AlignCenter)
                self.ui.tableWidget_2.setItem(count_t2, 2, item)
                # 4 столбец - Fi
                for row in range(count_t2, count_t2 + 7):
                    item = QtWidgets.QTableWidgetItem(
                        str(np.around(result[4][row - count_t2], 1)))
                    item.setTextAlignment(QtCore.Qt.AlignCenter)
                    self.ui.tableWidget_2.setItem(row, 3, item)
                # 5 столбец - Pc
                for row in range(count_t2, count_t2 + 7):
                    item = QtWidgets.QTableWidgetItem(
                        str(np.around(result[5][row - count_t2], 3)))
                    item.setTextAlignment(QtCore.Qt.AlignCenter)
                    self.ui.tableWidget_2.setItem(row, 4, item)
                # 6 столбец - qokt
                for row in range(count_t2, count_t2 + 7):
                    item = QtWidgets.QTableWidgetItem(
                        str(np.around(result[6][row - count_t2], 3)))
                    item.setTextAlignment(QtCore.Qt.AlignCenter)
                    self.ui.tableWidget_2.setItem(row, 5, item)
                # объединяем ячейки t2 - задаем спан
                self.ui.tableWidget_2.setSpan(count_t2, 0, 7, 1)
                self.ui.tableWidget_2.setSpan(count_t2, 1, 7, 1)
                self.ui.tableWidget_2.setSpan(count_t2, 2, 7, 1)
                # заполняем tablewidget_3
                # 1 столбец заполнен
                # 2 столбец - частота; стац + порт
                item = QtWidgets.QTableWidgetItem(str(fj))
                item.setTextAlignment(QtCore.Qt.AlignCenter)
                self.ui.tableWidget_3.setItem(count_t3, 1, item)
                item = QtWidgets.QTableWidgetItem(str(fj))
                item.setTextAlignment(QtCore.Qt.AlignCenter)
                self.ui.tableWidget_3.setItem(count_t3 + len(mas_fj), 1, item)
                # 3 столбец - Rar; стац + порт
                item = QtWidgets.QTableWidgetItem(str(result[0]))
                item.setTextAlignment(QtCore.Qt.AlignCenter)
                self.ui.tableWidget_3.setItem(count_t3, 2, item)
                item = QtWidgets.QTableWidgetItem(str(result[1]))
                item.setTextAlignment(QtCore.Qt.AlignCenter)
                self.ui.tableWidget_3.setItem(count_t3 + len(mas_fj), 2, item)
                count_t3 += 1
                count_t2 += 7
            # 4 столбец - maxRar_stac;port
            mas_Rar = np.zeros(len(mas_fj) * 2)
            for row in range(0, rows_t3):
                mas_Rar[row] = self.ui.tableWidget_3.item(row, 2).text()
                # self.ui.tableWidget_3.item
            max_Rar_stac = np.amax(mas_Rar[:len(mas_fj)])
            max_Rar_port = np.amax(mas_Rar[len(mas_fj):])
            item = QtWidgets.QTableWidgetItem(str(max_Rar_stac))
            item.setTextAlignment(QtCore.Qt.AlignCenter)
            self.ui.tableWidget_3.setItem(0, 3, item)
            item = QtWidgets.QTableWidgetItem(str(max_Rar_port))
            item.setTextAlignment(QtCore.Qt.AlignCenter)
            self.ui.tableWidget_3.setItem(len(mas_fj), 3, item)
            # объединяем ячейки t3 - задаем спан
            flag = 0
            for x in range(0, 2):
                self.ui.tableWidget_3.setSpan(flag, 0, len(mas_fj), 1)
                self.ui.tableWidget_3.setSpan(flag, 3, len(mas_fj), 1)
                flag += len(mas_fj)
            # пропорции t3
            header = self.ui.tableWidget_2.horizontalHeader()
            header.setSectionResizeMode(0, QtWidgets.QHeaderView.Stretch)
            # пропорции t3
            header = self.ui.tableWidget_3.horizontalHeader()
            header.setSectionResizeMode(0, QtWidgets.QHeaderView.Stretch)
            self.ui.statusbar.showMessage('Расчет  произведен успешно')

            # except:
            #     error = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Information, 'Ошибка',
            #                               'Ошибка расчета : make_rec',
            #                               QtWidgets.QMessageBox.Ok)
            #     error.exec_()

        # print(main_copm(fj, Pcw, Pw, Pgvc, Kprd, Kprm, Pgvc_AR_stac, Pgvc_AR_port,Rprd,Rprm,Gym,1))
        else:
            error = QtWidgets.QMessageBox(
                QtWidgets.QMessageBox.Information, 'Ошибка',
                'Ошибка расчета : make_rec, проверка не пройдена либо не задано значение Pgvc',
                QtWidgets.QMessageBox.Ok)
            error.exec_()

    #экспорт расчета в Word
    def eksport_word_func(self):
        self.ui.statusbar.showMessage('Выполняется экспорт данных в Word...')
        shablons_folder = str(
            sys.argv)[2:str(sys.argv).rfind('/') + 1] + 'word_shablons/'
        #строки и столбцы таблиц 2 и 3
        rows_t2 = self.ui.tableWidget_2.rowCount()
        column_t2 = self.ui.tableWidget_2.columnCount()
        rows_t3 = self.ui.tableWidget_3.rowCount()
        column_t3 = self.ui.tableWidget_3.columnCount()

        #открываем шаблон документа Word
        #сохраняемый файл
        save_file_name, _ = QtWidgets.QFileDialog.getSaveFileName(
            self, 'Сохранить как', '')
        if save_file_name[-5:] != '.docx':
            save_file_name = save_file_name + '.docx'
        if not save_file_name:
            return

        try:
            document = Document(shablons_folder + 'VHO_shablon.docx')

            # создаем таблицу подобную tableWidget_2
            table = document.add_table(rows_t2 + 1,
                                       column_t2)  # + 1 для хедеров
            table.style = 'Table Grid'
            # table.alignment = WD_TABLE_ALIGNMENT.CENTER #таблица по центру
            table.allow_autofit = True

            # хедеры
            headers_t2 = (
                'Частота \nтестового \nэлектромагнитного \nсигнала, МГц',
                'Коэффициент \nусиления \nизлучающей антенны Gпрд(fj), дБ',
                'Коэффициент \nусиления \nприемной nантенны Gпрм(fj), дБ',
                'Частота \nтестового \nакустического сигнала Fi, Гц',
                'Уровень мощности \nмодуляционной \nкомпоненты \nотраженного сигнала \nPc(f, Fi), дБ (мВт)',
                'Октавная \nЭПР ТС \nσтс (fj, Fi), дБ(м2)')

            # заполняем хедеры таблицы
            for x in range(0, 6):
                cell = table.cell(0, x)
                cell.text = headers_t2[x]

            # 1 столбец
            t2_flag = 0
            for x in range(0, int(rows_t2 / 7)):
                cell = table.cell(t2_flag + 1, 0)
                item = self.ui.tableWidget_2.item(t2_flag, 0)
                cell.text = item.text()
                cell = table.cell(t2_flag + 1, 1)
                item = self.ui.tableWidget_2.item(t2_flag, 1)
                cell.text = item.text()
                cell = table.cell(t2_flag + 1, 2)
                item = self.ui.tableWidget_2.item(t2_flag, 2)
                cell.text = item.text()
                t2_flag += 7

            for column in range(3, column_t2):
                for row in range(0, rows_t2):
                    cell = table.cell(row + 1, column)
                    item = self.ui.tableWidget_2.item(row, column)
                    cell.text = item.text()

            # размер текста 10pt и выравнивание ячеек tableWidget_t2
            for row in table.rows:
                for cell in row.cells:
                    cell.paragraphs[
                        0].paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
                    cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
                    paragraphs = cell.paragraphs
                    for paragraph in paragraphs:
                        for run in paragraph.runs:
                            font = run.font
                            font.size = Pt(10)

            # пустая строка
            document.add_paragraph('')

            # создаем таблицу для tableWidget_3
            table = document.add_table(rows_t3 + 1,
                                       column_t3)  # + 1 для хедеров
            table.style = 'Table Grid'
            table.allow_autofit = True

            # хедеры t3
            headers_t3 = (
                'Вариант размещения \nаппаратуры \nакустической речевой \nразведки',
                'Частота облучения fj, МГц',
                'Дальность разведки Rар-р (fj), м',
                'Максимальная дальность разведки Rар-р max, м')

            # заполняем хедеры таблицы
            for x in range(0, 4):
                cell = table.cell(0, x)
                cell.text = headers_t3[x]

            # 1 столбец
            # стационарные
            cell = table.cell(1, 0)
            item = self.ui.tableWidget_3.item(0, 0)
            cell.text = item.text()
            # портативно-возимые
            cell = table.cell(int(rows_t3 / 2) + 1, 0)
            item = self.ui.tableWidget_3.item(int(rows_t3 / 2), 0)
            cell.text = item.text()
            # 2 столбец
            for row in range(0, int(rows_t3)):
                cell = table.cell(row + 1, 1)
                item = self.ui.tableWidget_3.item(row, 1)
                cell.text = item.text()
            # 3 столбец
            for row in range(0, int(rows_t3)):
                cell = table.cell(row + 1, 2)
                item = self.ui.tableWidget_3.item(row, 2)
                cell.text = item.text()
            # 4 столбец
            # стационарные
            cell = table.cell(1, 3)
            item = self.ui.tableWidget_3.item(0, 3)
            cell.text = item.text()
            # портативно-возимые
            cell = table.cell(int(rows_t3 / 2) + 1, 3)
            item = self.ui.tableWidget_3.item(int(rows_t3 / 2), 3)
            cell.text = item.text()

            # размер текста 10pt и выравнивание ячеек tableWidget_t3
            for row in table.rows:
                for cell in row.cells:
                    cell.paragraphs[
                        0].paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
                    cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
                    paragraphs = cell.paragraphs
                    for paragraph in paragraphs:
                        for run in paragraph.runs:
                            font = run.font
                            font.size = Pt(10)

            document.save(save_file_name)
            self.ui.statusbar.showMessage('Экспорт данных успешно завершен')
        except:
            error = QtWidgets.QMessageBox(
                QtWidgets.QMessageBox.Information, 'Ошибка',
                'Ошибка формирования расчетного протокола : eksport_word_func',
                QtWidgets.QMessageBox.Ok)
            error.exec_()