예제 #1
0
    def __init__(self, main_display, parent=None):
        super(ChartDataExportDisplay, self).__init__(parent=parent)
        self.main_layout = QVBoxLayout()
        self.main_layout.setAlignment(Qt.AlignTop)
        self.main_layout.setSpacing(5)
        self.main_display = main_display

        self.export_options_lbl = QLabel()
        self.export_options_lbl.setText("Export Options")
        self.export_options_cmb = QComboBox()
        self.export_options_cmb.addItems(
            ("Curve Data", "Chart Settings", "Image File"))
        self.export_options_cmb.currentIndexChanged.connect(
            self.handle_export_options_index_changed)

        # Options for Chart Settings
        self.include_pv_chk = QCheckBox("Include currently plotted PVs")
        self.include_pv_chk.setChecked(True)

        self.include_chart_settings_chk = QCheckBox(
            "Include current chart settings")
        self.include_chart_settings_chk.setChecked(True)

        # Options for Image File
        self.image_dimension_layout = QFormLayout()
        self.image_dimension_layout.setSpacing(10)

        self.image_width_lbl = QLabel("Image width")
        self.image_width_edt = QLineEdit()
        self.image_width_edt.editingFinished.connect(
            self.handle_image_dimension_value)
        self.image_width_edt.setText(DEFAULT_EXPORTED_IMAGE_WIDTH)

        self.image_height_lbl = QLabel("Image height")
        self.image_height_edt = QLineEdit()
        self.image_height_edt.editingFinished.connect(
            self.handle_image_dimension_value)
        self.image_height_edt.setText(DEFAULT_EXPORTED_IMAGE_HEIGHT)

        self.anti_alias_chk = QCheckBox("Anti-alias")
        self.anti_alias_chk.setChecked(True)

        self.export_image_background_color_lbl = QLabel("Background Color ")
        self.export_image_background_btn = QPushButton()
        self.export_image_background_btn.setMaximumWidth(20)
        self.export_image_background_btn.setStyleSheet(
            "background-color: black")
        self.export_image_background_btn.clicked.connect(
            self.handle_export_image_background_button_clicked)

        self.export_format_lbl = QLabel()
        self.export_format_lbl.setText("Export Format")
        self.file_format_cmb = QComboBox()
        self.file_format_cmb.addItems(("csv", "json", "png"))
        self.file_format = ""
        self.exported_image_background_color = QColor(Qt.black)

        self.save_file_btn = QPushButton("Export...")
        self.save_file_btn.clicked.connect(self.handle_save_file_btn_clicked)

        self.image_width = 0
        self.image_height = 0

        self.setFixedSize(QSize(300, 150))
        self.setWindowTitle("Export Chart Data")
        self.setWindowModality(Qt.ApplicationModal)
        self.setup_ui()
예제 #2
0
    def __init__(self, parent=None, *, file_path=None):

        super().__init__(parent)

        self.__file_path = ""
        self.__distance_to_sample = 0.0
        self.__overwrite_existing = False
        self.__preview = ("", {})  # str - information, dict - warnings

        self.setWindowTitle("Save Quantitative Calibration")
        self.setMinimumHeight(600)
        self.setMinimumWidth(600)
        self.resize(600, 600)

        self.text_edit = QTextEdit()
        set_tooltip(
            self.text_edit,
            "Preview the <b>quantitative calibration data</b> to be saved. The displayed "
            "warnings will not be saved, but need to be addressed in order to keep "
            "data integrity. The parameter <b>distance-to-sample</b> is optional, "
            "but desirable. If <b>distance-to-sample</b> is zero then no scaling will be "
            "applied to data to compensate for changing distance.",
        )
        self.text_edit.setReadOnly(True)

        self.le_file_path = LineEditReadOnly()
        set_tooltip(
            self.le_file_path,
            "Full path to the file used to <b>save the calibration data</b>. The path "
            "can be changed in file selection dialog box.",
        )
        self.pb_file_path = PushButtonMinimumWidth("..")
        set_tooltip(
            self.pb_file_path,
            "Change <b>file path</b> for saving the calibration data.")
        self.pb_file_path.clicked.connect(self.pb_file_path_clicked)
        self.pb_file_path.setDefault(False)
        self.pb_file_path.setAutoDefault(False)

        self.le_distance_to_sample = LineEditExtended()
        self.le_distance_to_sample.textChanged.connect(
            self.le_distance_to_sample_text_changed)
        self.le_distance_to_sample.editingFinished.connect(
            self.le_distance_to_sample_editing_finished)
        self._le_distance_to_sample_validator = DoubleValidatorStrict()
        self._le_distance_to_sample_validator.setBottom(0.0)
        set_tooltip(
            self.le_distance_to_sample,
            "<b>Distance</b> between the detector and the sample during calibration. If the value "
            "is 0, then no scaling is applied to data to correct the data if distance-to-sample "
            "is changed between calibration and measurement.",
        )

        self.cb_overwrite = QCheckBox("Overwrite Existing")
        self.cb_overwrite.stateChanged.connect(self.cb_overwrite_state_changed)
        set_tooltip(
            self.cb_overwrite,
            "Overwrite the <b>existing</b> file. This is a safety feature implemented to protect "
            "valuable results from accidental deletion.",
        )

        vbox = QVBoxLayout()

        hbox = QHBoxLayout()
        hbox.addWidget(
            QLabel("The following data will be saved to JSON file:"))
        hbox.addStretch(1)
        vbox.addLayout(hbox)

        vbox.addWidget(self.text_edit)

        hbox = QHBoxLayout()
        hbox.addWidget(QLabel("Path: "))
        hbox.addWidget(self.pb_file_path)
        hbox.addWidget(self.le_file_path)
        vbox.addLayout(hbox)

        hbox = QHBoxLayout()
        hbox.addWidget(QLabel("Distance-to-sample:"))
        hbox.addWidget(self.le_distance_to_sample)
        hbox.addStretch(1)
        hbox.addWidget(self.cb_overwrite)
        vbox.addLayout(hbox)

        button_box = QDialogButtonBox(QDialogButtonBox.Ok
                                      | QDialogButtonBox.Cancel)
        self.pb_ok = button_box.button(QDialogButtonBox.Ok)
        self.pb_ok.setDefault(False)
        self.pb_ok.setAutoDefault(False)
        self.pb_cancel = button_box.button(QDialogButtonBox.Cancel)
        self.pb_cancel.setDefault(True)
        self.pb_cancel.setAutoDefault(True)

        button_box.accepted.connect(self.accept)
        button_box.rejected.connect(self.reject)
        vbox.addWidget(button_box)

        self.setLayout(vbox)

        self._show_distance_to_sample()
        self._show_preview()
        self._show_overwrite_existing()

        # Set and display file path
        if file_path is not None:
            self.file_path = file_path
예제 #3
0
    def __init__(self, model):
        """Initialize MNELAB main window.

        Parameters
        ----------
        model : mnelab.model.Model instance
            The main window needs to connect to a model containing all data
            sets. This decouples the GUI from the data (model/view).
        """
        super().__init__()
        self.model = model  # data model
        self.setWindowTitle("MNELAB")

        # restore settings
        settings = read_settings()
        self.recent = settings["recent"]  # list of recent files
        self.resize(settings["size"])
        self.move(settings["pos"])

        # trigger theme setting
        QIcon.setThemeSearchPaths([str(Path(__file__).parent / "icons")])
        self.event(QEvent(QEvent.PaletteChange))

        self.actions = {}  # contains all actions

        # initialize menus
        file_menu = self.menuBar().addMenu("&File")
        icon = QIcon.fromTheme("open-file")
        self.actions["open_file"] = file_menu.addAction(
            icon, "&Open...", self.open_data, QKeySequence.Open)
        self.recent_menu = file_menu.addMenu("Open recent")
        self.recent_menu.aboutToShow.connect(self._update_recent_menu)
        self.recent_menu.triggered.connect(self._load_recent)
        if not self.recent:
            self.recent_menu.setEnabled(False)
        self.actions["close_file"] = file_menu.addAction(
            "&Close", self.model.remove_data, QKeySequence.Close)
        self.actions["close_all"] = file_menu.addAction(
            "Close all", self.close_all)
        file_menu.addSeparator()
        icon = QIcon.fromTheme("meta-info")
        self.actions["meta_info"] = file_menu.addAction(
            icon, "Show information...", self.meta_info)
        file_menu.addSeparator()
        self.actions["import_bads"] = file_menu.addAction(
            "Import bad channels...", lambda: self.import_file(
                model.import_bads, "Import bad channels", "*.csv"))
        self.actions["import_events"] = file_menu.addAction(
            "Import events...", lambda: self.import_file(
                model.import_events, "Import events", "*.csv"))
        self.actions["import_annotations"] = file_menu.addAction(
            "Import annotations...", lambda: self.import_file(
                model.import_annotations, "Import annotations", "*.csv"))
        self.actions["import_ica"] = file_menu.addAction(
            "Import &ICA...", lambda: self.open_file(
                model.import_ica, "Import ICA", "*.fif *.fif.gz"))
        file_menu.addSeparator()
        self.export_menu = file_menu.addMenu("Export data")
        for ext, description in writers.items():
            action = "export_data" + ext.replace(".", "_")
            self.actions[action] = self.export_menu.addAction(
                f"{ext[1:].upper()} ({description[1]})...",
                partial(self.export_file, model.export_data, "Export data",
                        ext))
        self.actions["export_bads"] = file_menu.addAction(
            "Export &bad channels...", lambda: self.export_file(
                model.export_bads, "Export bad channels", "*.csv"))
        self.actions["export_events"] = file_menu.addAction(
            "Export &events...", lambda: self.export_file(
                model.export_events, "Export events", "*.csv"))
        self.actions["export_annotations"] = file_menu.addAction(
            "Export &annotations...", lambda: self.export_file(
                model.export_annotations, "Export annotations", "*.csv"))
        self.actions["export_ica"] = file_menu.addAction(
            "Export ICA...", lambda: self.export_file(
                model.export_ica, "Export ICA", "*.fif *.fif.gz"))
        file_menu.addSeparator()
        self.actions["quit"] = file_menu.addAction("&Quit", self.close,
                                                   QKeySequence.Quit)

        edit_menu = self.menuBar().addMenu("&Edit")
        self.actions["pick_chans"] = edit_menu.addAction(
            "P&ick channels...", self.pick_channels)
        icon = QIcon.fromTheme("chan-props")
        self.actions["chan_props"] = edit_menu.addAction(
            icon, "Channel &properties...", self.channel_properties)
        self.actions["set_montage"] = edit_menu.addAction(
            "Set &montage...", self.set_montage)
        edit_menu.addSeparator()
        self.actions["set_ref"] = edit_menu.addAction("Set &reference...",
                                                      self.set_reference)
        edit_menu.addSeparator()
        self.actions["annotations"] = edit_menu.addAction(
            "&Annotations...", self.edit_annotations)
        self.actions["events"] = edit_menu.addAction("&Events...",
                                                     self.edit_events)

        edit_menu.addSeparator()
        self.actions["crop"] = edit_menu.addAction("&Crop data...", self.crop)
        self.actions["append_data"] = edit_menu.addAction(
            "Appen&d data...", self.append_data)

        plot_menu = self.menuBar().addMenu("&Plot")
        icon = QIcon.fromTheme("plot-data")
        self.actions["plot_data"] = plot_menu.addAction(
            icon, "&Data...", self.plot_data)
        icon = QIcon.fromTheme("plot-psd")
        self.actions["plot_psd"] = plot_menu.addAction(
            icon, "&Power spectral density...", self.plot_psd)
        icon = QIcon.fromTheme("plot-locations")
        self.actions["plot_locations"] = plot_menu.addAction(
            icon, "&Channel locations...", self.plot_locations)
        self.actions["plot_erds"] = plot_menu.addAction(
            "&ERDS maps...", self.plot_erds)
        plot_menu.addSeparator()
        self.actions["plot_ica_components"] = plot_menu.addAction(
            "ICA &components...", self.plot_ica_components)
        self.actions["plot_ica_sources"] = plot_menu.addAction(
            "ICA &sources...", self.plot_ica_sources)

        tools_menu = self.menuBar().addMenu("&Tools")
        icon = QIcon.fromTheme("filter-data")
        self.actions["filter"] = tools_menu.addAction(icon, "&Filter data...",
                                                      self.filter_data)
        icon = QIcon.fromTheme("find-events")
        self.actions["find_events"] = tools_menu.addAction(
            icon, "Find &events...", self.find_events)
        self.actions["events_from_annotations"] = tools_menu.addAction(
            "Create events from annotations", self.events_from_annotations)
        self.actions["annotations_from_events"] = tools_menu.addAction(
            "Create annotations from events", self.annotations_from_events)
        tools_menu.addSeparator()
        nirs_menu = tools_menu.addMenu("NIRS")
        self.actions["convert_od"] = nirs_menu.addAction(
            "Convert to &optical density", self.convert_od)
        self.actions["convert_bl"] = nirs_menu.addAction(
            "Convert to &haemoglobin", self.convert_bl)

        tools_menu.addSeparator()
        icon = QIcon.fromTheme("run-ica")
        self.actions["run_ica"] = tools_menu.addAction(icon, "Run &ICA...",
                                                       self.run_ica)
        self.actions["apply_ica"] = tools_menu.addAction(
            "Apply &ICA", self.apply_ica)
        tools_menu.addSeparator()
        self.actions["interpolate_bads"] = tools_menu.addAction(
            "Interpolate bad channels...", self.interpolate_bads)
        tools_menu.addSeparator()
        icon = QIcon.fromTheme("epoch-data")
        self.actions["epoch_data"] = tools_menu.addAction(
            icon, "Create Epochs...", self.epoch_data)

        view_menu = self.menuBar().addMenu("&View")
        self.actions["history"] = view_menu.addAction("&History...",
                                                      self.show_history)
        self.actions["toolbar"] = view_menu.addAction("&Toolbar",
                                                      self._toggle_toolbar)
        self.actions["toolbar"].setCheckable(True)
        self.actions["statusbar"] = view_menu.addAction(
            "&Statusbar", self._toggle_statusbar)
        self.actions["statusbar"].setCheckable(True)

        help_menu = self.menuBar().addMenu("&Help")
        self.actions["about"] = help_menu.addAction("&About", self.show_about)
        self.actions["about_qt"] = help_menu.addAction("About &Qt",
                                                       self.show_about_qt)

        # actions that are always enabled
        self.always_enabled = [
            "open_file", "about", "about_qt", "quit", "toolbar", "statusbar"
        ]

        # set up toolbar
        self.toolbar = self.addToolBar("toolbar")
        self.toolbar.setObjectName("toolbar")
        self.toolbar.addAction(self.actions["open_file"])
        self.toolbar.addAction(self.actions["meta_info"])
        self.toolbar.addSeparator()
        self.toolbar.addAction(self.actions["chan_props"])
        self.toolbar.addSeparator()
        self.toolbar.addAction(self.actions["plot_data"])
        self.toolbar.addAction(self.actions["plot_psd"])
        self.toolbar.addAction(self.actions["plot_locations"])
        self.toolbar.addSeparator()
        self.toolbar.addAction(self.actions["filter"])
        self.toolbar.addAction(self.actions["find_events"])
        self.toolbar.addAction(self.actions["epoch_data"])
        self.toolbar.addAction(self.actions["run_ica"])

        self.setUnifiedTitleAndToolBarOnMac(True)
        if settings["toolbar"]:
            self.toolbar.show()
            self.actions["toolbar"].setChecked(True)
        else:
            self.toolbar.hide()
            self.actions["toolbar"].setChecked(False)

        # set up data model for sidebar (list of open files)
        self.names = QStringListModel()
        self.names.dataChanged.connect(self._update_names)
        splitter = QSplitter()
        self.sidebar = QListView()
        self.sidebar.setFrameStyle(QFrame.NoFrame)
        self.sidebar.setFocusPolicy(Qt.NoFocus)
        self.sidebar.setModel(self.names)
        self.sidebar.clicked.connect(self._update_data)
        splitter.addWidget(self.sidebar)
        self.infowidget = InfoWidget()
        splitter.addWidget(self.infowidget)
        width = splitter.size().width()
        splitter.setSizes((int(width * 0.3), int(width * 0.7)))
        self.setCentralWidget(splitter)

        self.status_label = QLabel()
        self.statusBar().addPermanentWidget(self.status_label)
        if settings["statusbar"]:
            self.statusBar().show()
            self.actions["statusbar"].setChecked(True)
        else:
            self.statusBar().hide()
            self.actions["statusbar"].setChecked(False)

        self.setAcceptDrops(True)
        self.data_changed()
예제 #4
0
    def __init__(self, name=None, plugin=None, parent=None):
        super().__init__(name, plugin, parent=parent)
        self.set_conf('text_color', MAIN_TEXT_COLOR)
        self.set_conf('hist_limit', MAX_PATH_HISTORY)

        # Attributes
        self.text_color = self.get_conf('text_color')
        self.supported_encodings = self.get_conf('supported_encodings')
        self.search_thread = None
        self.running = False
        self.more_options_action = None
        self.extras_toolbar = None

        search_text = self.get_conf('search_text', '')
        path_history = self.get_conf('path_history', [])
        exclude = self.get_conf('exclude')

        if not isinstance(search_text, (list, tuple)):
            search_text = [search_text]

        if not isinstance(exclude, (list, tuple)):
            exclude = [exclude]

        if not isinstance(path_history, (list, tuple)):
            path_history = [path_history]

        # Widgets
        self.search_text_edit = PatternComboBox(
            self,
            search_text,
            id_=FindInFilesWidgetToolbarItems.SearchPatternCombo)

        self.search_text_edit.lineEdit().setPlaceholderText(
            _('Write text to search'))

        self.search_in_label = QLabel(_('Search in:'))
        self.search_in_label.ID = FindInFilesWidgetToolbarItems.SearchInLabel

        self.exclude_label = QLabel(_('Exclude:'))
        self.exclude_label.ID = FindInFilesWidgetToolbarItems.ExcludeLabel

        self.path_selection_combo = SearchInComboBox(
            path_history,
            self,
            id_=FindInFilesWidgetToolbarItems.SearchInCombo)

        self.exclude_pattern_edit = PatternComboBox(
            self,
            exclude,
            _("Exclude pattern"),
            id_=FindInFilesWidgetToolbarItems.ExcludePatternCombo)

        self.result_browser = ResultsBrowser(
            self,
            text_color=self.text_color,
            max_results=self.get_conf('max_results'),
        )

        # Setup
        self.exclude_label.setBuddy(self.exclude_pattern_edit)
        exclude_idx = self.get_conf('exclude_index', None)
        if (exclude_idx is not None and exclude_idx >= 0
                and exclude_idx < self.exclude_pattern_edit.count()):
            self.exclude_pattern_edit.setCurrentIndex(exclude_idx)

        search_in_index = self.get_conf('search_in_index', None)
        self.path_selection_combo.set_current_searchpath_index(search_in_index)

        # Layout
        layout = QHBoxLayout()
        layout.addWidget(self.result_browser)
        self.setLayout(layout)

        # Signals
        self.path_selection_combo.sig_redirect_stdio_requested.connect(
            self.sig_redirect_stdio_requested)
        self.search_text_edit.valid.connect(lambda valid: self.find())
        self.exclude_pattern_edit.valid.connect(lambda valid: self.find())
        self.result_browser.sig_edit_goto_requested.connect(
            self.sig_edit_goto_requested)
        self.result_browser.sig_max_results_reached.connect(
            self.sig_max_results_reached)
        self.result_browser.sig_max_results_reached.connect(
            self._stop_and_reset_thread)
        self.search_text_edit.sig_resized.connect(self._update_size)
예제 #5
0
파일: testrx.py 프로젝트: imagect/qtools
def addLabel(x):
    label = QLabel("A", toolbar)
    toolbar.addWidget(label)
예제 #6
0
    def __init__(self):
        super().__init__()

        self.setWindowTitle("About PyXRF")
        self.setFixedSize(500, 500)

        text_name = "PyXRF"
        text_description = "X-Ray Fluorescence Analysis Tool"

        text_ver = f"Version: {pyxrf.__version__}"
        text_latest_ver = "Latest stable version:"

        text_credit = "Credits:"
        text_credit_org = (
            "Data Acquisition, Management and Analysis Group\n"
            "National Synchrontron Light Source II\n"
            "Brookhaven National Laboratory"
        )

        text_copyright = f"\u00A92015\u2014{datetime.now().year} Brookhaven National Laboratory"

        label_name = QLabel(text_name)
        label_name.setStyleSheet("QLabel {font-weight: bold; font-size: 32px}")

        label_description = QLabel(text_description)
        label_description.setStyleSheet("QLabel {font-style: italic; font-size: 18px}")

        label_ver = QLabel(text_ver)
        label_latest_ver = QLabel(text_latest_ver)
        label_credit = QLabel(text_credit)
        label_org = QLabel(text_credit_org)
        label_copyright = QLabel(text_copyright)

        button_box = QDialogButtonBox(QDialogButtonBox.Close)
        button_box.accepted.connect(self.accept)
        button_box.rejected.connect(self.reject)

        vbox = QVBoxLayout()

        vbox.addStretch(1)

        hbox = QHBoxLayout()
        hbox.addStretch(1)
        hbox.addWidget(label_name)
        hbox.addStretch(1)
        vbox.addLayout(hbox)

        hbox = QHBoxLayout()
        hbox.addStretch(1)
        hbox.addWidget(label_description)
        hbox.addStretch(1)
        vbox.addLayout(hbox)

        vbox.addStretch(1)

        hbox = QHBoxLayout()
        hbox.addSpacing(30)
        hbox.addWidget(label_ver)
        hbox.addStretch(1)
        vbox.addLayout(hbox)

        hbox = QHBoxLayout()
        hbox.addSpacing(30)
        hbox.addWidget(label_latest_ver)
        hbox.addStretch(1)
        vbox.addLayout(hbox)

        vbox.addStretch(1)

        hbox = QHBoxLayout()
        hbox.addSpacing(30)
        hbox.addWidget(label_credit, 0, Qt.AlignTop)
        hbox.addWidget(label_org, 0, Qt.AlignTop)
        hbox.addStretch(1)
        vbox.addLayout(hbox)

        vbox.addSpacing(20)

        hbox = QHBoxLayout()
        hbox.addSpacing(30)
        hbox.addWidget(label_copyright)
        hbox.addStretch(1)
        vbox.addLayout(hbox)

        vbox.addSpacing(20)

        vbox.addWidget(button_box)

        self.setLayout(vbox)
예제 #7
0
    def setup(self):
        """Setup the ShortcutEditor with the provided arguments."""
        # Widgets
        icon_info = HelperToolButton()
        icon_info.setIcon(get_std_icon('MessageBoxInformation'))
        layout_icon_info = QVBoxLayout()
        layout_icon_info.setContentsMargins(0, 0, 0, 0)
        layout_icon_info.setSpacing(0)
        layout_icon_info.addWidget(icon_info)
        layout_icon_info.addStretch(100)

        self.label_info = QLabel()
        self.label_info.setText(
            _("Press the new shortcut and select 'Ok' to confirm, "
              "click 'Cancel' to revert to the previous state, "
              "or use 'Clear' to unbind the command from a shortcut."))
        self.label_info.setAlignment(Qt.AlignTop | Qt.AlignLeft)
        self.label_info.setWordWrap(True)
        layout_info = QHBoxLayout()
        layout_info.setContentsMargins(0, 0, 0, 0)
        layout_info.addLayout(layout_icon_info)
        layout_info.addWidget(self.label_info)
        layout_info.setStretch(1, 100)

        self.label_current_sequence = QLabel(_("Current shortcut:"))
        self.text_current_sequence = QLabel(self.current_sequence)

        self.label_new_sequence = QLabel(_("New shortcut:"))
        self.text_new_sequence = ShortcutLineEdit(self)
        self.text_new_sequence.setPlaceholderText(_("Press shortcut."))

        self.helper_button = HelperToolButton()
        self.helper_button.setIcon(QIcon())
        self.label_warning = QLabel()
        self.label_warning.setWordWrap(True)
        self.label_warning.setAlignment(Qt.AlignTop | Qt.AlignLeft)

        self.button_default = QPushButton(_('Default'))
        self.button_ok = QPushButton(_('Ok'))
        self.button_ok.setEnabled(False)
        self.button_clear = QPushButton(_('Clear'))
        self.button_cancel = QPushButton(_('Cancel'))
        button_box = QHBoxLayout()
        button_box.addWidget(self.button_default)
        button_box.addStretch(100)
        button_box.addWidget(self.button_ok)
        button_box.addWidget(self.button_clear)
        button_box.addWidget(self.button_cancel)

        # New Sequence button box
        self.btn_clear_sequence = create_toolbutton(
            self,
            icon=ima.icon('editclear'),
            tip=_("Clear all entered key sequences"),
            triggered=self.clear_new_sequence)
        self.button_back_sequence = create_toolbutton(
            self,
            icon=ima.icon('ArrowBack'),
            tip=_("Remove last key sequence entered"),
            triggered=self.back_new_sequence)

        newseq_btnbar = QHBoxLayout()
        newseq_btnbar.setSpacing(0)
        newseq_btnbar.setContentsMargins(0, 0, 0, 0)
        newseq_btnbar.addWidget(self.button_back_sequence)
        newseq_btnbar.addWidget(self.btn_clear_sequence)

        # Setup widgets
        self.setWindowTitle(_('Shortcut: {0}').format(self.name))
        self.helper_button.setToolTip('')
        style = """
            QToolButton {
              margin:1px;
              border: 0px solid grey;
              padding:0px;
              border-radius: 0px;
            }"""
        self.helper_button.setStyleSheet(style)
        icon_info.setToolTip('')
        icon_info.setStyleSheet(style)

        # Layout
        layout_sequence = QGridLayout()
        layout_sequence.setContentsMargins(0, 0, 0, 0)
        layout_sequence.addLayout(layout_info, 0, 0, 1, 4)
        layout_sequence.addItem(QSpacerItem(15, 15), 1, 0, 1, 4)
        layout_sequence.addWidget(self.label_current_sequence, 2, 0)
        layout_sequence.addWidget(self.text_current_sequence, 2, 2)
        layout_sequence.addWidget(self.label_new_sequence, 3, 0)
        layout_sequence.addWidget(self.helper_button, 3, 1)
        layout_sequence.addWidget(self.text_new_sequence, 3, 2)
        layout_sequence.addLayout(newseq_btnbar, 3, 3)
        layout_sequence.addWidget(self.label_warning, 4, 2, 1, 2)
        layout_sequence.setColumnStretch(2, 100)
        layout_sequence.setRowStretch(4, 100)

        layout = QVBoxLayout()
        layout.addLayout(layout_sequence)
        layout.addSpacing(5)
        layout.addLayout(button_box)
        self.setLayout(layout)

        # Signals
        self.button_ok.clicked.connect(self.accept_override)
        self.button_clear.clicked.connect(self.unbind_shortcut)
        self.button_cancel.clicked.connect(self.reject)
        self.button_default.clicked.connect(self.set_sequence_to_default)

        # Set all widget to no focus so that we can register <Tab> key
        # press event.
        widgets = (self.label_warning, self.helper_button,
                   self.text_new_sequence, self.button_clear,
                   self.button_default, self.button_cancel, self.button_ok,
                   self.btn_clear_sequence, self.button_back_sequence)
        for w in widgets:
            w.setFocusPolicy(Qt.NoFocus)
            w.clearFocus()
예제 #8
0
    def __init__(self, file_list, calculation_plan, measurement_file_path,
                 settings, batch_manager):
        """

        :param file_list: list of files to proceed
        :type file_list: list[str]
        :param calculation_plan: calculation plan for this run
        :type calculation_plan: CalculationPlan
        :param measurement_file_path: path to measurement result file
        :type measurement_file_path: str
        :param settings: settings object
        :type settings: PartSettings
        :type batch_manager: CalculationManager
        """
        super().__init__()
        self.setWindowTitle("Calculation start")
        self.file_list = file_list
        self.calculation_plan = calculation_plan
        self.measurement_file_path = measurement_file_path
        self.settings = settings
        self.batch_manager = batch_manager
        self.info_label = QLabel(
            "Information, <i><font color='blue'>warnings</font></i>, "
            "<b><font color='red'>errors</font><b>")
        self.voxel_size = Spacing("Voxel size", settings.image.spacing,
                                  settings.get("units_value", Units.nm))
        all_prefix = os.path.commonprefix(file_list)
        if not os.path.exists(all_prefix):
            all_prefix = os.path.dirname(all_prefix)
        if not os.path.isdir(all_prefix):
            all_prefix = os.path.dirname(all_prefix)
        self.base_prefix = QLineEdit(all_prefix, self)
        self.base_prefix.setReadOnly(True)
        self.result_prefix = QLineEdit(all_prefix, self)
        self.result_prefix.setReadOnly(True)
        self.base_prefix_btn = QPushButton("Choose data prefix")
        self.base_prefix_btn.clicked.connect(self.choose_data_prefix)
        self.result_prefix_btn = QPushButton("Choose save prefix")
        self.result_prefix_btn.clicked.connect(self.choose_result_prefix)
        self.sheet_name = QLineEdit("Sheet1")
        self.sheet_name.textChanged.connect(self.verify_data)
        self.measurement_file_path_view = QLineEdit(measurement_file_path)
        self.measurement_file_path_view.setReadOnly(True)

        self.mask_path_list = []
        self.mask_mapper_list = self.calculation_plan.get_list_file_mask()
        mask_file_list = [(i, el) for i, el in enumerate(self.mask_mapper_list)
                          if isinstance(el, MaskFile)]

        mask_path_layout = QGridLayout()
        for i, (pos, mask_file) in enumerate(mask_file_list):
            if mask_file.name == "":
                mask_path_layout.addWidget(
                    right_label(f"Path to file {i + 1} with mask mapping"))
            else:
                mask_path_layout.addWidget(
                    right_label(
                        f"Path to file {i + 1} with mask mapping for name: {mask_file.name}"
                    ))
            mask_path = QLineEdit(self)
            mask_path.setReadOnly(True)
            self.mask_path_list.append(mask_path)
            set_path = QPushButton("Choose file", self)
            set_path.clicked.connect(self.set_mapping_mask(i, pos))
            mask_path_layout.addWidget(mask_path, i, 1)
            mask_path_layout.addWidget(set_path, i, 2)

        self.state_list = np.zeros(
            (len(self.file_list), len(self.mask_mapper_list)), dtype=np.uint8)

        self.file_list_widget = QTreeWidget()
        self.file_list_widget.header().close()

        self.execute_btn = QPushButton("Execute")
        self.execute_btn.clicked.connect(self.accept)
        self.cancel_btn = QPushButton("Cancel")
        self.cancel_btn.clicked.connect(self.close)

        layout = QGridLayout()
        layout.addWidget(self.info_label, 0, 0, 1, 5)
        layout.addWidget(self.voxel_size, 1, 0, 1, 5)
        layout.addWidget(right_label("Measurement sheet name:"), 3, 3)
        layout.addWidget(self.sheet_name, 3, 4)
        layout.addWidget(right_label("Measurement file path:"), 2, 3)
        layout.addWidget(self.measurement_file_path_view, 2, 4)

        layout.addWidget(right_label("Data prefix:"), 2, 0)
        layout.addWidget(self.base_prefix, 2, 1)
        layout.addWidget(self.base_prefix_btn, 2, 2)
        layout.addWidget(right_label("Save prefix:"), 3, 0)
        layout.addWidget(self.result_prefix, 3, 1)
        layout.addWidget(self.result_prefix_btn, 3, 2)
        layout.addLayout(mask_path_layout, 4, 0, 1, 0)

        layout.addWidget(self.file_list_widget, 5, 0, 3, 6)
        btn_layout = QHBoxLayout()
        btn_layout.addWidget(self.execute_btn)
        btn_layout.addStretch()
        btn_layout.addWidget(self.cancel_btn)
        layout.addLayout(btn_layout, 8, 0, 1, 0)
        self.setLayout(layout)
        self.verify_data()
예제 #9
0
    def __init__(
        self, config_folder=CONFIG_FOLDER, title="PartSeg", settings=None, signal_fun=None, initial_image=None
    ):
        super().__init__(config_folder, title, settings, signal_fun)
        self.channel_info = "result_image"
        self.files_num = 2
        self.setMinimumWidth(600)
        # thi isinstance is only for hinting in IDE
        assert isinstance(self.settings, PartSettings)  # nosec
        self.main_menu = MainMenu(self.settings, self)
        # self.channel_control1 = ChannelControl(self.settings, name="raw_control", text="Left panel:")
        self.channel_control2 = ChannelProperty(self.settings, start_name="result_control")
        self.raw_image = CompareImageView(self.settings, self.channel_control2, "raw_image")
        self.measurements = MeasurementWidget(self.settings)
        self.left_stack = StackedWidgetWithSelector()
        self.left_stack.addWidget(self.raw_image, "Image")
        self.left_stack.addWidget(self.measurements, "Measurements")
        self.result_image = ResultImageView(self.settings, self.channel_control2, "result_image")
        self.color_bar = ColorBar(self.settings, [self.raw_image, self.result_image])
        self.info_text = QLabel()
        self.info_text.setMinimumHeight(25)
        self.raw_image.text_info_change.connect(self.info_text.setText)
        self.result_image.text_info_change.connect(self.info_text.setText)
        self.synchronize_tool = SynchronizeView(self.raw_image, self.result_image, self)
        # image_view_control = self.image_view.get_control_view()
        self.options_panel = Options(
            self.settings, self.channel_control2, self.raw_image, self.result_image, self.synchronize_tool
        )
        # self.main_menu.image_loaded.connect(self.image_read)
        self.settings.image_changed.connect(self.image_read)
        self.advanced_window = SegAdvancedWindow(self.settings, reload_list=[self.reload])
        self.batch_window = None  # BatchWindow(self.settings)

        self.multiple_files = MultipleFileWidget(self.settings, load_functions.load_dict, True)

        if initial_image is None:
            reader = TiffImageReader()
            im = reader.read(self.initial_image_path)
            im.file_path = ""
            self.settings.image = im
        elif initial_image is False:
            # FIXME This is for test opening
            pass
        else:
            self.settings.image = initial_image

        icon = QIcon(os.path.join(PartSegData.icons_dir, "icon.png"))
        self.setWindowIcon(icon)

        menu_bar = self.menuBar()
        file_menu = menu_bar.addMenu("File")
        file_menu.addAction("&Open").triggered.connect(self.main_menu.load_data)
        file_menu.addAction("&Save").triggered.connect(self.main_menu.save_file)
        file_menu.addAction("Batch processing").triggered.connect(self.main_menu.batch_window)
        view_menu = menu_bar.addMenu("View")
        view_menu.addAction("Settings and Measurement").triggered.connect(self.main_menu.advanced_window_show)
        view_menu.addAction("Additional output").triggered.connect(self.additional_layers_show)
        view_menu.addAction("Additional output with data").triggered.connect(lambda: self.additional_layers_show(True))
        view_menu.addAction("Napari viewer").triggered.connect(self.napari_viewer_show)
        action = view_menu.addAction("Screenshot right panel")
        action.triggered.connect(self.screenshot(self.result_image))
        action.setShortcut(QKeySequence.Print)
        view_menu.addAction("Screenshot left panel").triggered.connect(self.screenshot(self.raw_image))
        image_menu = menu_bar.addMenu("Image operations")
        image_menu.addAction("Image adjustment").triggered.connect(self.image_adjust_exec)
        image_menu.addAction("Mask manager").triggered.connect(self.main_menu.mask_manager)
        help_menu = menu_bar.addMenu("Help")
        help_menu.addAction("State directory").triggered.connect(self.show_settings_directory)
        help_menu.addAction("About").triggered.connect(self.show_about_dialog)

        layout = QGridLayout()
        # layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)
        info_layout = QHBoxLayout()
        info_layout.addWidget(self.left_stack.selector)
        info_layout.addWidget(self.options_panel.compare_btn)
        info_layout.addWidget(self.info_text, 1, Qt.AlignHCenter)

        image_layout = EqualColumnLayout()
        image_layout.addWidget(self.left_stack)
        image_layout.addWidget(self.result_image)

        layout.setSpacing(0)
        layout.addWidget(self.main_menu, 0, 0, 1, 3)
        layout.addLayout(info_layout, 1, 1, 1, 2)
        layout.addWidget(self.multiple_files, 2, 0)
        layout.addWidget(self.color_bar, 2, 1)
        # layout.addWidget(self.left_stack, 2, 2)
        # layout.addWidget(self.result_image, 2, 3)
        layout.addLayout(image_layout, 2, 2, 1, 1)
        layout.addWidget(self.options_panel, 0, 3, 3, 1)
        layout.setColumnStretch(2, 1)
        widget = QWidget()
        widget.setLayout(layout)
        # self.multiple_files.setHidden(True)
        self.setCentralWidget(widget)
        try:
            geometry = self.settings.get_from_profile("main_window_geometry")
            self.restoreGeometry(QByteArray.fromHex(bytes(geometry, "ascii")))
        except KeyError:
            pass
예제 #10
0
    def __init__(self, layer):
        super().__init__(layer)

        self.layer.events.mode.connect(self.set_mode)
        self.layer.events.edge_width.connect(self._on_edge_width_change)
        self.layer.events.current_edge_color.connect(
            self._on_edge_color_change
        )
        self.layer.events.current_face_color.connect(
            self._on_face_color_change
        )
        self.layer.events.editable.connect(self._on_editable_change)

        sld = QSlider(Qt.Horizontal)
        sld.setFocusPolicy(Qt.NoFocus)
        sld.setMinimum(0)
        sld.setMaximum(40)
        sld.setSingleStep(1)
        value = self.layer.current_edge_width
        if isinstance(value, Iterable):
            if isinstance(value, list):
                value = np.asarray(value)
            value = value.mean()
        sld.setValue(int(value))
        sld.valueChanged.connect(self.changeWidth)
        self.widthSlider = sld

        self.select_button = QtModeRadioButton(
            layer, 'select', Mode.SELECT, tooltip='Select shapes'
        )
        self.direct_button = QtModeRadioButton(
            layer, 'direct', Mode.DIRECT, tooltip='Select vertices'
        )
        self.panzoom_button = QtModeRadioButton(
            layer, 'zoom', Mode.PAN_ZOOM, tooltip='Pan/zoom', checked=True
        )
        self.rectangle_button = QtModeRadioButton(
            layer, 'rectangle', Mode.ADD_RECTANGLE, tooltip='Add rectangles'
        )
        self.ellipse_button = QtModeRadioButton(
            layer, 'ellipse', Mode.ADD_ELLIPSE, tooltip='Add ellipses'
        )
        self.line_button = QtModeRadioButton(
            layer, 'line', Mode.ADD_LINE, tooltip='Add lines'
        )
        self.path_button = QtModeRadioButton(
            layer, 'path', Mode.ADD_PATH, tooltip='Add paths'
        )
        self.polygon_button = QtModeRadioButton(
            layer, 'polygon', Mode.ADD_POLYGON, tooltip='Add polygons'
        )
        self.vertex_insert_button = QtModeRadioButton(
            layer, 'vertex_insert', Mode.VERTEX_INSERT, tooltip='Insert vertex'
        )
        self.vertex_remove_button = QtModeRadioButton(
            layer, 'vertex_remove', Mode.VERTEX_REMOVE, tooltip='Remove vertex'
        )

        self.move_front_button = QtModePushButton(
            layer,
            'move_front',
            slot=self.layer.move_to_front,
            tooltip='Move to front',
        )
        self.move_back_button = QtModePushButton(
            layer,
            'move_back',
            slot=self.layer.move_to_back,
            tooltip='Move to back',
        )
        self.delete_button = QtModePushButton(
            layer,
            'delete_shape',
            slot=self.layer.remove_selected,
            tooltip='Delete selected shapes',
        )

        self.button_group = QButtonGroup(self)
        self.button_group.addButton(self.select_button)
        self.button_group.addButton(self.direct_button)
        self.button_group.addButton(self.panzoom_button)
        self.button_group.addButton(self.rectangle_button)
        self.button_group.addButton(self.ellipse_button)
        self.button_group.addButton(self.line_button)
        self.button_group.addButton(self.path_button)
        self.button_group.addButton(self.polygon_button)
        self.button_group.addButton(self.vertex_insert_button)
        self.button_group.addButton(self.vertex_remove_button)

        button_grid = QGridLayout()
        button_grid.addWidget(self.vertex_remove_button, 0, 2)
        button_grid.addWidget(self.vertex_insert_button, 0, 3)
        button_grid.addWidget(self.delete_button, 0, 4)
        button_grid.addWidget(self.direct_button, 0, 5)
        button_grid.addWidget(self.select_button, 0, 6)
        button_grid.addWidget(self.panzoom_button, 0, 7)
        button_grid.addWidget(self.move_back_button, 1, 1)
        button_grid.addWidget(self.move_front_button, 1, 2)
        button_grid.addWidget(self.ellipse_button, 1, 3)
        button_grid.addWidget(self.rectangle_button, 1, 4)
        button_grid.addWidget(self.polygon_button, 1, 5)
        button_grid.addWidget(self.line_button, 1, 6)
        button_grid.addWidget(self.path_button, 1, 7)
        button_grid.setContentsMargins(5, 0, 0, 5)
        button_grid.setColumnStretch(0, 1)
        button_grid.setSpacing(4)

        self.faceColorEdit = QColorSwatchEdit(
            initial_color=self.layer.current_face_color,
            tooltip='click to set current face color',
        )
        self._on_face_color_change()
        self.edgeColorEdit = QColorSwatchEdit(
            initial_color=self.layer.current_edge_color,
            tooltip='click to set current edge color',
        )
        self._on_edge_color_change()
        self.faceColorEdit.color_changed.connect(self.changeFaceColor)
        self.edgeColorEdit.color_changed.connect(self.changeEdgeColor)

        # grid_layout created in QtLayerControls
        # addWidget(widget, row, column, [row_span, column_span])
        self.grid_layout.addLayout(button_grid, 0, 0, 1, 2)
        self.grid_layout.addWidget(QLabel('opacity:'), 1, 0)
        self.grid_layout.addWidget(self.opacitySlider, 1, 1)
        self.grid_layout.addWidget(QLabel('edge width:'), 2, 0)
        self.grid_layout.addWidget(self.widthSlider, 2, 1)
        self.grid_layout.addWidget(QLabel('blending:'), 3, 0)
        self.grid_layout.addWidget(self.blendComboBox, 3, 1)
        self.grid_layout.addWidget(QLabel('face color:'), 4, 0)
        self.grid_layout.addWidget(self.faceColorEdit, 4, 1)
        self.grid_layout.addWidget(QLabel('edge color:'), 5, 0)
        self.grid_layout.addWidget(self.edgeColorEdit, 5, 1)
        self.grid_layout.setRowStretch(6, 1)
        self.grid_layout.setColumnStretch(1, 1)
        self.grid_layout.setSpacing(4)
예제 #11
0
    def __init__(self,
                 parent,
                 search_text,
                 search_text_regexp,
                 exclude,
                 exclude_idx,
                 exclude_regexp,
                 supported_encodings,
                 more_options,
                 case_sensitive,
                 external_path_history,
                 options_button=None):
        QWidget.__init__(self, parent)

        if not isinstance(search_text, (list, tuple)):
            search_text = [search_text]
        if not isinstance(exclude, (list, tuple)):
            exclude = [exclude]
        if not isinstance(external_path_history, (list, tuple)):
            external_path_history = [external_path_history]

        self.supported_encodings = supported_encodings

        # Layout 1
        hlayout1 = QHBoxLayout()
        self.search_text = PatternComboBox(self, search_text,
                                           _("Search pattern"))
        self.edit_regexp = create_toolbutton(self,
                                             icon=get_icon('regexp.svg'),
                                             tip=_('Regular expression'))
        self.case_button = create_toolbutton(self,
                                             icon=get_icon("upper_lower.png"),
                                             tip=_("Case Sensitive"))
        self.case_button.setCheckable(True)
        self.case_button.setChecked(case_sensitive)
        self.edit_regexp.setCheckable(True)
        self.edit_regexp.setChecked(search_text_regexp)
        self.more_widgets = ()
        self.more_options = create_toolbutton(self,
                                              toggled=self.toggle_more_options)
        self.more_options.setCheckable(True)
        self.more_options.setChecked(more_options)

        self.ok_button = create_toolbutton(self,
                                           text=_("Search"),
                                           icon=ima.icon('find'),
                                           triggered=lambda: self.find.emit(),
                                           tip=_("Start search"),
                                           text_beside_icon=True)
        self.ok_button.clicked.connect(self.update_combos)
        self.stop_button = create_toolbutton(
            self,
            text=_("Stop"),
            icon=ima.icon('stop'),
            triggered=lambda: self.stop.emit(),
            tip=_("Stop search"),
            text_beside_icon=True)
        self.stop_button.setEnabled(False)
        for widget in [
                self.search_text, self.edit_regexp, self.case_button,
                self.ok_button, self.stop_button, self.more_options
        ]:
            hlayout1.addWidget(widget)
        if options_button:
            hlayout1.addWidget(options_button)

        # Layout 2
        hlayout2 = QHBoxLayout()
        self.exclude_pattern = PatternComboBox(self, exclude,
                                               _("Exclude pattern"))
        if exclude_idx is not None and exclude_idx >= 0 \
           and exclude_idx < self.exclude_pattern.count():
            self.exclude_pattern.setCurrentIndex(exclude_idx)
        self.exclude_regexp = create_toolbutton(self,
                                                icon=get_icon('regexp.svg'),
                                                tip=_('Regular expression'))
        self.exclude_regexp.setCheckable(True)
        self.exclude_regexp.setChecked(exclude_regexp)
        exclude_label = QLabel(_("Exclude:"))
        exclude_label.setBuddy(self.exclude_pattern)
        for widget in [
                exclude_label, self.exclude_pattern, self.exclude_regexp
        ]:
            hlayout2.addWidget(widget)

        # Layout 3
        hlayout3 = QHBoxLayout()

        search_on_label = QLabel(_("Search in:"))
        self.path_selection_combo = SearchInComboBox(external_path_history,
                                                     parent)

        hlayout3.addWidget(search_on_label)
        hlayout3.addWidget(self.path_selection_combo)

        self.search_text.valid.connect(lambda valid: self.find.emit())
        self.exclude_pattern.valid.connect(lambda valid: self.find.emit())

        vlayout = QVBoxLayout()
        vlayout.setContentsMargins(0, 0, 0, 0)
        vlayout.addLayout(hlayout1)
        vlayout.addLayout(hlayout2)
        vlayout.addLayout(hlayout3)
        self.more_widgets = (hlayout2, )
        self.toggle_more_options(more_options)
        self.setLayout(vlayout)

        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)
예제 #12
0
    @rgba_text.setter
    def rgba_text(self, _rgba_text):
        self._rgba_text = _rgba_text
        self.updateStyleSheet()


if __name__ == "__main__":
    import sys
    from qtpy.QtWidgets import QApplication, QLabel
    from qtpy.QtGui import QCursor
    app = QApplication(sys.argv)

    main_splitter = TansuBaseWidget()
    main_splitter.handle_length = 100
    main_splitter.setObjectName("main")
    label = QLabel('a')
    main_splitter.addWidget(label)
    main_splitter.addWidget(QLabel('b'))
    main_splitter.addWidget(QLabel('c'))
    label.setStyleSheet("color: rgba(255,0,0,255)")
    splitter1 = TansuBaseWidget(orientation=Qt.Horizontal)
    splitter1.setObjectName("embed")
    for x in range(3):
        l = QLabel(str(x))
        l.setStyleSheet("color: rgba(255,0,0,255)")
        splitter1.addWidget(l)

    main_splitter.addWidget(splitter1)

    main_splitter.show()
    #main_splitter.updateStyleSheet()
예제 #13
0
    def setup_page(self):
        newcb = self.create_checkbox

        # --- Introspection ---
        # Basic features group
        basic_features_group = QGroupBox(_("Basic features"))
        completion_box = newcb(_("Enable code completion"), 'code_completion')
        enable_hover_hints_box = newcb(
            _("Enable hover hints"),
            'enable_hover_hints',
            tip=_("If enabled, hovering the mouse pointer over an object\n"
                  "name will display that object's signature and/or\n"
                  "docstring (if present)."))
        goto_definition_box = newcb(
            _("Enable Go to definition"),
            'jedi_definition',
            tip=_("If enabled, left-clicking on an object name while \n"
                  "pressing the {} key will go to that object's definition\n"
                  "(if resolved).".format(self.CTRL)))
        follow_imports_box = newcb(
            _("Follow imports when going to a "
              "definition"), 'jedi_definition/follow_imports')
        show_signature_box = newcb(_("Show calltips"), 'jedi_signature_help')

        basic_features_layout = QVBoxLayout()
        basic_features_layout.addWidget(completion_box)
        basic_features_layout.addWidget(enable_hover_hints_box)
        basic_features_layout.addWidget(goto_definition_box)
        basic_features_layout.addWidget(follow_imports_box)
        basic_features_layout.addWidget(show_signature_box)
        basic_features_group.setLayout(basic_features_layout)

        # Advanced group
        advanced_group = QGroupBox(_("Advanced"))
        modules_textedit = self.create_textedit(
            _("Preload the following modules to make completion faster "
              "and more accurate:"), 'preload_modules')
        if is_dark_interface():
            modules_textedit.textbox.setStyleSheet(
                "border: 1px solid #32414B;")

        advanced_layout = QVBoxLayout()
        advanced_layout.addWidget(modules_textedit)
        advanced_group.setLayout(advanced_layout)

        # --- Linting ---
        # Linting options
        linting_label = QLabel(
            _("Spyder can optionally highlight syntax "
              "errors and possible problems with your "
              "code in the editor."))
        linting_label.setOpenExternalLinks(True)
        linting_label.setWordWrap(True)
        linting_check = self.create_checkbox(_("Enable basic linting"),
                                             'pyflakes')

        linting_complexity_box = self.create_checkbox(
            _("Enable complexity linting with "
              "the Mccabe package"), 'mccabe')

        # Linting layout
        linting_layout = QVBoxLayout()
        linting_layout.addWidget(linting_label)
        linting_layout.addWidget(linting_check)
        linting_layout.addWidget(linting_complexity_box)
        linting_widget = QWidget()
        linting_widget.setLayout(linting_layout)

        # --- Code style tab ---
        # Code style label
        pep_url = (
            '<a href="https://www.python.org/dev/peps/pep-0008">PEP 8</a>')
        code_style_codes_url = _(
            "<a href='http://pycodestyle.pycqa.org/en/stable"
            "/intro.html#error-codes'>pycodestyle error codes</a>")
        code_style_label = QLabel(
            _("Spyder can use pycodestyle to analyze your code for "
              "conformance to the {} convention. You can also "
              "manually show or hide specific warnings by their "
              "{}.").format(pep_url, code_style_codes_url))
        code_style_label.setOpenExternalLinks(True)
        code_style_label.setWordWrap(True)

        # Code style checkbox
        code_style_check = self.create_checkbox(_("Enable code style linting"),
                                                'pycodestyle')

        # Code style options
        self.code_style_filenames_match = self.create_lineedit(
            _("Only check filenames matching these patterns:"),
            'pycodestyle/filename',
            alignment=Qt.Horizontal,
            word_wrap=False,
            placeholder=_("Check Python files: *.py"))
        self.code_style_exclude = self.create_lineedit(
            _("Exclude files or directories matching these patterns:"),
            'pycodestyle/exclude',
            alignment=Qt.Horizontal,
            word_wrap=False,
            placeholder=_("Exclude all test files: (?!test_).*\\.py"))
        code_style_select = self.create_lineedit(
            _("Show the following errors or warnings:").format(
                code_style_codes_url),
            'pycodestyle/select',
            alignment=Qt.Horizontal,
            word_wrap=False,
            placeholder=_("Example codes: E113, W391"))
        code_style_ignore = self.create_lineedit(
            _("Ignore the following errors or warnings:"),
            'pycodestyle/ignore',
            alignment=Qt.Horizontal,
            word_wrap=False,
            placeholder=_("Example codes: E201, E303"))
        code_style_max_line_length = self.create_spinbox(
            _("Maximum allowed line length:"),
            None,
            'pycodestyle/max_line_length',
            min_=10,
            max_=500,
            step=1,
            tip=_("Default is 79"))

        # Code style layout
        code_style_g_layout = QGridLayout()
        code_style_g_layout.addWidget(self.code_style_filenames_match.label, 1,
                                      0)
        code_style_g_layout.addWidget(self.code_style_filenames_match.textbox,
                                      1, 1)
        code_style_g_layout.addWidget(self.code_style_exclude.label, 2, 0)
        code_style_g_layout.addWidget(self.code_style_exclude.textbox, 2, 1)
        code_style_g_layout.addWidget(code_style_select.label, 3, 0)
        code_style_g_layout.addWidget(code_style_select.textbox, 3, 1)
        code_style_g_layout.addWidget(code_style_ignore.label, 4, 0)
        code_style_g_layout.addWidget(code_style_ignore.textbox, 4, 1)
        code_style_g_layout.addWidget(code_style_max_line_length.plabel, 5, 0)
        code_style_g_layout.addWidget(code_style_max_line_length.spinbox, 5, 1)

        # Set Code style options enabled/disabled
        code_style_g_widget = QWidget()
        code_style_g_widget.setLayout(code_style_g_layout)
        code_style_g_widget.setEnabled(self.get_option('pycodestyle'))
        code_style_check.toggled.connect(code_style_g_widget.setEnabled)

        # Code style layout
        code_style_layout = QVBoxLayout()
        code_style_layout.addWidget(code_style_label)
        code_style_layout.addWidget(code_style_check)
        code_style_layout.addWidget(code_style_g_widget)

        code_style_widget = QWidget()
        code_style_widget.setLayout(code_style_layout)

        # --- Docstring tab ---
        # Docstring style label
        numpy_url = ("<a href='https://numpydoc.readthedocs.io/en/"
                     "latest/format.html'>Numpy</a>")
        pep257_url = (
            "<a href='https://www.python.org/dev/peps/pep-0257/'>PEP 257</a>")
        docstring_style_codes = _(
            "<a href='http://www.pydocstyle.org/en/stable"
            "/error_codes.html'>page</a>")
        docstring_style_label = QLabel(
            _("Here you can decide if you want to perform style analysis on "
              "your docstrings according to the {} or {} conventions. You can "
              "also decide if you want to show or ignore specific errors, "
              "according to the codes found on this {}.").format(
                  numpy_url, pep257_url, docstring_style_codes))
        docstring_style_label.setOpenExternalLinks(True)
        docstring_style_label.setWordWrap(True)

        # Docstring style checkbox
        docstring_style_check = self.create_checkbox(
            _("Enable docstring style linting"), 'pydocstyle')

        # Docstring style options
        docstring_style_convention = self.create_combobox(
            _("Choose the convention used to lint docstrings: "),
            (("Numpy", 'numpy'), ("PEP 257", 'pep257'), ("Custom", 'custom')),
            'pydocstyle/convention')
        self.docstring_style_select = self.create_lineedit(
            _("Show the following errors:"),
            'pydocstyle/select',
            alignment=Qt.Horizontal,
            word_wrap=False,
            placeholder=_("Example codes: D413, D414"))
        self.docstring_style_ignore = self.create_lineedit(
            _("Ignore the following errors:"),
            'pydocstyle/ignore',
            alignment=Qt.Horizontal,
            word_wrap=False,
            placeholder=_("Example codes: D107, D402"))
        self.docstring_style_match = self.create_lineedit(
            _("Only check filenames matching these patterns:"),
            'pydocstyle/match',
            alignment=Qt.Horizontal,
            word_wrap=False,
            placeholder=_("Skip test files: (?!test_).*\\.py"))
        self.docstring_style_match_dir = self.create_lineedit(
            _("Only check in directories matching these patterns:"),
            'pydocstyle/match_dir',
            alignment=Qt.Horizontal,
            word_wrap=False,
            placeholder=_("Skip dot directories: [^\\.].*"))

        # Custom option handling
        docstring_style_convention.combobox.currentTextChanged.connect(
            self.setup_docstring_style_convention)
        current_convention = docstring_style_convention.combobox.currentText()
        self.setup_docstring_style_convention(current_convention)

        # Docstring style layout
        docstring_style_g_layout = QGridLayout()
        docstring_style_g_layout.addWidget(docstring_style_convention.label, 1,
                                           0)
        docstring_style_g_layout.addWidget(docstring_style_convention.combobox,
                                           1, 1)
        docstring_style_g_layout.addWidget(self.docstring_style_select.label,
                                           2, 0)
        docstring_style_g_layout.addWidget(self.docstring_style_select.textbox,
                                           2, 1)
        docstring_style_g_layout.addWidget(self.docstring_style_ignore.label,
                                           3, 0)
        docstring_style_g_layout.addWidget(self.docstring_style_ignore.textbox,
                                           3, 1)
        docstring_style_g_layout.addWidget(self.docstring_style_match.label, 4,
                                           0)
        docstring_style_g_layout.addWidget(self.docstring_style_match.textbox,
                                           4, 1)
        docstring_style_g_layout.addWidget(
            self.docstring_style_match_dir.label, 5, 0)
        docstring_style_g_layout.addWidget(
            self.docstring_style_match_dir.textbox, 5, 1)

        # Set Docstring style options enabled/disabled
        docstring_style_g_widget = QWidget()
        docstring_style_g_widget.setLayout(docstring_style_g_layout)
        docstring_style_g_widget.setEnabled(self.get_option('pydocstyle'))
        docstring_style_check.toggled.connect(
            docstring_style_g_widget.setEnabled)

        # Docstring style layout
        docstring_style_layout = QVBoxLayout()
        docstring_style_layout.addWidget(docstring_style_label)
        docstring_style_layout.addWidget(docstring_style_check)
        docstring_style_layout.addWidget(docstring_style_g_widget)

        docstring_style_widget = QWidget()
        docstring_style_widget.setLayout(docstring_style_layout)

        # --- Advanced tab ---
        # Advanced label
        advanced_label = QLabel(
            _("<b>Warning</b>: Only modify these values if "
              "you know what you're doing!"))
        advanced_label.setWordWrap(True)
        advanced_label.setAlignment(Qt.AlignJustify)

        # Advanced options
        self.advanced_command_launch = self.create_lineedit(
            _("Command to launch the Python language server: "),
            'advanced/command_launch',
            alignment=Qt.Horizontal,
            word_wrap=False)
        self.advanced_host = self.create_lineedit(
            _("IP Address and port to bind the server to: "),
            'advanced/host',
            alignment=Qt.Horizontal,
            word_wrap=False)
        self.advanced_port = self.create_spinbox(":",
                                                 "",
                                                 'advanced/port',
                                                 min_=1,
                                                 max_=65535,
                                                 step=1)
        self.external_server = self.create_checkbox(
            _("This is an external server"), 'advanced/external')
        self.use_stdio = self.create_checkbox(
            _("Use stdio pipes to communicate with server"), 'advanced/stdio')
        self.use_stdio.stateChanged.connect(self.disable_tcp)
        self.external_server.stateChanged.connect(self.disable_stdio)

        # Advanced layout
        advanced_g_layout = QGridLayout()
        advanced_g_layout.addWidget(self.advanced_command_launch.label, 1, 0)
        advanced_g_layout.addWidget(self.advanced_command_launch.textbox, 1, 1)
        advanced_g_layout.addWidget(self.advanced_host.label, 2, 0)

        advanced_host_port_g_layout = QGridLayout()
        advanced_host_port_g_layout.addWidget(self.advanced_host.textbox, 1, 0)
        advanced_host_port_g_layout.addWidget(self.advanced_port.plabel, 1, 1)
        advanced_host_port_g_layout.addWidget(self.advanced_port.spinbox, 1, 2)
        advanced_g_layout.addLayout(advanced_host_port_g_layout, 2, 1)

        advanced_widget = QWidget()
        advanced_layout = QVBoxLayout()
        advanced_layout.addWidget(advanced_label)
        advanced_layout.addSpacing(12)
        advanced_layout.addLayout(advanced_g_layout)
        advanced_layout.addWidget(self.external_server)
        advanced_layout.addWidget(self.use_stdio)
        advanced_widget.setLayout(advanced_layout)

        # --- Other servers tab ---
        # Section label
        servers_label = QLabel(
            _("Spyder uses the <a href=\"{lsp_url}\">Language Server "
              "Protocol</a> to provide code completion and linting "
              "for its Editor. Here, you can setup and configure LSP servers "
              "for languages other than Python, so Spyder can provide such "
              "features for those languages as well.").format(lsp_url=LSP_URL))
        servers_label.setOpenExternalLinks(True)
        servers_label.setWordWrap(True)
        servers_label.setAlignment(Qt.AlignJustify)

        # Servers table
        table_group = QGroupBox(_('Available servers:'))
        self.table = LSPServerTable(self, text_color=ima.MAIN_FG_COLOR)
        self.table.setMaximumHeight(150)
        table_layout = QVBoxLayout()
        table_layout.addWidget(self.table)
        table_group.setLayout(table_layout)

        # Buttons
        self.reset_btn = QPushButton(_("Reset to default values"))
        self.new_btn = QPushButton(_("Set up a new server"))
        self.delete_btn = QPushButton(_("Delete currently selected server"))
        self.delete_btn.setEnabled(False)

        # Slots connected to buttons
        self.new_btn.clicked.connect(self.create_new_server)
        self.reset_btn.clicked.connect(self.reset_to_default)
        self.delete_btn.clicked.connect(self.delete_server)

        # Buttons layout
        btns = [self.new_btn, self.delete_btn, self.reset_btn]
        buttons_layout = QGridLayout()
        for i, btn in enumerate(btns):
            buttons_layout.addWidget(btn, i, 1)
        buttons_layout.setColumnStretch(0, 1)
        buttons_layout.setColumnStretch(1, 2)
        buttons_layout.setColumnStretch(2, 1)

        # Combined layout
        servers_widget = QWidget()
        servers_layout = QVBoxLayout()
        servers_layout.addSpacing(-10)
        servers_layout.addWidget(servers_label)
        servers_layout.addWidget(table_group)
        servers_layout.addSpacing(10)
        servers_layout.addLayout(buttons_layout)
        servers_widget.setLayout(servers_layout)

        # --- Tabs organization ---
        tabs = QTabWidget()
        tabs.addTab(self.create_tab(basic_features_group, advanced_group),
                    _('Introspection'))
        tabs.addTab(self.create_tab(linting_widget), _('Linting'))
        tabs.addTab(self.create_tab(code_style_widget), _('Code style'))
        tabs.addTab(self.create_tab(docstring_style_widget),
                    _('Docstring style'))
        tabs.addTab(self.create_tab(advanced_widget), _('Advanced'))
        tabs.addTab(self.create_tab(servers_widget), _('Other languages'))

        vlayout = QVBoxLayout()
        vlayout.addWidget(tabs)
        self.setLayout(vlayout)
예제 #14
0
    def __init__(self,
                 parent,
                 language=None,
                 cmd='',
                 host='127.0.0.1',
                 port=2084,
                 args='',
                 external=False,
                 stdio=False,
                 configurations={},
                 **kwargs):
        super(LSPServerEditor, self).__init__(parent)

        description = _(
            "To create a new server configuration, you need to select a "
            "programming language, set the command to start its associated "
            "server and enter any arguments that should be passed to it on "
            "startup. Additionally, you can set the server's hostname and "
            "port if connecting to an external server, "
            "or to a local one using TCP instead of stdio pipes."
            "<br><br>"
            "<i>Note</i>: You can use the placeholders <tt>{host}</tt> and "
            "<tt>{port}</tt> in the server arguments field to automatically "
            "fill in the respective values.<br>")
        self.parent = parent
        self.external = external

        # Widgets
        self.server_settings_description = QLabel(description)
        self.lang_cb = QComboBox(self)
        self.external_cb = QCheckBox(_('External server'), self)
        self.host_label = QLabel(_('Host:'))
        self.host_input = QLineEdit(self)
        self.port_label = QLabel(_('Port:'))
        self.port_spinner = QSpinBox(self)
        self.cmd_label = QLabel(_('Command:'))
        self.cmd_input = QLineEdit(self)
        self.args_label = QLabel(_('Arguments:'))
        self.args_input = QLineEdit(self)
        self.json_label = QLabel(self.JSON_VALID, self)
        self.conf_label = QLabel(_('<b>Server Configuration:</b>'))
        self.conf_input = CodeEditor(None)

        self.bbox = QDialogButtonBox(QDialogButtonBox.Ok
                                     | QDialogButtonBox.Cancel)
        self.button_ok = self.bbox.button(QDialogButtonBox.Ok)
        self.button_cancel = self.bbox.button(QDialogButtonBox.Cancel)

        # Widget setup
        self.setMinimumSize(self.MIN_SIZE)
        self.setWindowTitle(_('LSP server editor'))

        self.server_settings_description.setWordWrap(True)

        self.lang_cb.setToolTip(
            _('Programming language provided by the LSP server'))
        self.lang_cb.addItem(_('Select a language'))
        self.lang_cb.addItems(LSP_LANGUAGES)

        self.button_ok.setEnabled(False)
        if language is not None:
            idx = LSP_LANGUAGES.index(language)
            self.lang_cb.setCurrentIndex(idx + 1)
            self.button_ok.setEnabled(True)

        self.host_input.setPlaceholderText('127.0.0.1')
        self.host_input.setText(host)
        self.host_input.textChanged.connect(lambda x: self.validate())

        self.port_spinner.setToolTip(_('TCP port number of the server'))
        self.port_spinner.setMinimum(1)
        self.port_spinner.setMaximum(60000)
        self.port_spinner.setValue(port)

        self.cmd_input.setText(cmd)
        self.cmd_input.setPlaceholderText('/absolute/path/to/command')

        self.args_input.setToolTip(
            _('Additional arguments required to start the server'))
        self.args_input.setText(args)
        self.args_input.setPlaceholderText(r'--host {host} --port {port}')

        self.conf_input.setup_editor(language='json',
                                     color_scheme=CONF.get(
                                         'appearance', 'selected'),
                                     wrap=False,
                                     edge_line=True,
                                     highlight_current_line=True,
                                     highlight_current_cell=True,
                                     occurrence_highlighting=True,
                                     auto_unindent=True,
                                     font=get_font(),
                                     filename='config.json',
                                     folding=False)
        self.conf_input.set_language('json', 'config.json')
        self.conf_input.setToolTip(
            _('Additional LSP server configuration '
              'set at runtime. JSON required'))
        try:
            conf_text = json.dumps(configurations, indent=4, sort_keys=True)
        except Exception:
            conf_text = '{}'
        self.conf_input.set_text(conf_text)

        self.external_cb.setToolTip(
            _('Check if the server runs on a remote location'))
        self.external_cb.setChecked(external)

        self.stdio_cb = QCheckBox(_('Use stdio pipes for communication'), self)
        self.stdio_cb.setToolTip(
            _('Check if the server communicates '
              'using stdin/out pipes'))
        self.stdio_cb.setChecked(stdio)

        # Layout setup
        hlayout = QHBoxLayout()
        general_vlayout = QVBoxLayout()
        general_vlayout.addWidget(self.server_settings_description)

        vlayout = QVBoxLayout()

        lang_group = QGroupBox(_('Language'))
        lang_layout = QVBoxLayout()
        lang_layout.addWidget(self.lang_cb)
        lang_group.setLayout(lang_layout)
        vlayout.addWidget(lang_group)

        server_group = QGroupBox(_('Language server'))
        server_layout = QGridLayout()
        server_layout.addWidget(self.cmd_label, 0, 0)
        server_layout.addWidget(self.cmd_input, 0, 1)
        server_layout.addWidget(self.args_label, 1, 0)
        server_layout.addWidget(self.args_input, 1, 1)
        server_group.setLayout(server_layout)
        vlayout.addWidget(server_group)

        address_group = QGroupBox(_('Server address'))
        host_layout = QVBoxLayout()
        host_layout.addWidget(self.host_label)
        host_layout.addWidget(self.host_input)

        port_layout = QVBoxLayout()
        port_layout.addWidget(self.port_label)
        port_layout.addWidget(self.port_spinner)

        conn_info_layout = QHBoxLayout()
        conn_info_layout.addLayout(host_layout)
        conn_info_layout.addLayout(port_layout)
        address_group.setLayout(conn_info_layout)
        vlayout.addWidget(address_group)

        advanced_group = QGroupBox(_('Advanced'))
        advanced_layout = QVBoxLayout()
        advanced_layout.addWidget(self.external_cb)
        advanced_layout.addWidget(self.stdio_cb)
        advanced_group.setLayout(advanced_layout)
        vlayout.addWidget(advanced_group)

        conf_layout = QVBoxLayout()
        conf_layout.addWidget(self.conf_label)
        conf_layout.addWidget(self.conf_input)
        conf_layout.addWidget(self.json_label)

        vlayout.addStretch()
        hlayout.addLayout(vlayout, 2)
        hlayout.addLayout(conf_layout, 3)
        general_vlayout.addLayout(hlayout)

        general_vlayout.addWidget(self.bbox)
        self.setLayout(general_vlayout)
        self.form_status(False)

        # Signals
        if not external:
            self.cmd_input.textChanged.connect(lambda x: self.validate())
        self.external_cb.stateChanged.connect(self.set_local_options)
        self.stdio_cb.stateChanged.connect(self.set_stdio_options)
        self.lang_cb.currentIndexChanged.connect(self.lang_selection_changed)
        self.conf_input.textChanged.connect(self.validate)
        self.bbox.accepted.connect(self.accept)
        self.bbox.rejected.connect(self.reject)

        # Final setup
        if language is not None:
            self.form_status(True)
            self.validate()
            if stdio:
                self.set_stdio_options(True)
            if external:
                self.set_local_options(True)
예제 #15
0
    def _setupui(self):
        self.setLayout(QFormLayout())
        self.layout().setSpacing(0)

        self.layout().addRow(QLabel(
            '<h4>Image Processing Detailed Controls</h4>', self,
            alignment=Qt.AlignTop | Qt.AlignHCenter))

        wid = QWidget(self)
        wid.setLayout(QHBoxLayout())
        sttbtn = PyDMEnumComboBox(
            wid, init_channel=self._dev+':ReadingOrder-Sel')
        lbl = SiriusLabel(wid, init_channel=self._dev+':ReadingOrder-Sts')
        wid.layout().addWidget(sttbtn)
        wid.layout().addWidget(lbl)
        self.layout().addRow(QLabel(
            'Reading Order', self, alignment=Qt.AlignBottom), wid)

        wid = QWidget(self)
        wid.setLayout(QHBoxLayout())
        sttbtn = PyDMStateButton(wid, init_channel=self._dev+':ImgFlipX-Sel')
        lbl = SiriusLedState(wid, init_channel=self._dev+':ImgFlipX-Sts')
        wid.layout().addWidget(sttbtn)
        wid.layout().addWidget(lbl)
        self.layout().addRow(QLabel(
            'Flip Horintal', self, alignment=Qt.AlignBottom), wid)

        wid = QWidget(self)
        wid.setLayout(QHBoxLayout())
        sttbtn = PyDMStateButton(wid, init_channel=self._dev+':ImgFlipY-Sel')
        lbl = SiriusLedState(wid, init_channel=self._dev+':ImgFlipY-Sts')
        wid.layout().addWidget(sttbtn)
        wid.layout().addWidget(lbl)
        self.layout().addRow(QLabel(
            'Flip Vertical', self, alignment=Qt.AlignBottom), wid)

        wid = QWidget(self)
        wid.setLayout(QHBoxLayout())
        spnbox = SiriusSpinbox(wid, init_channel=self._dev+':ImgCropLow-SP')
        lbl = SiriusLabel(wid, init_channel=self._dev+':ImgCropLow-RB')
        spnbox.showStepExponent = False
        wid.layout().addWidget(spnbox)
        wid.layout().addWidget(lbl)
        self.layout().addRow(QLabel(
            'Min. Pixel Val.', self, alignment=Qt.AlignBottom), wid)

        wid = QWidget(self)
        wid.setLayout(QHBoxLayout())
        sttbtn = PyDMStateButton(wid, init_channel=self._dev+':ImgCropUse-Sel')
        lbl = SiriusLedState(wid, init_channel=self._dev+':ImgCropUse-Sts')
        wid.layout().addWidget(sttbtn)
        wid.layout().addWidget(lbl)
        self.layout().addRow(QLabel(
            'Crop Image Levels', self, alignment=Qt.AlignBottom), wid)

        wid = QWidget(self)
        wid.setLayout(QHBoxLayout())
        spnbox = SiriusSpinbox(wid, init_channel=self._dev+':ImgCropHigh-SP')
        lbl = SiriusLabel(wid, init_channel=self._dev+':ImgCropHigh-RB')
        spnbox.showStepExponent = False
        wid.layout().addWidget(spnbox)
        wid.layout().addWidget(lbl)
        self.layout().addRow(QLabel(
            'Max. Pixel Val.', self, alignment=Qt.AlignBottom), wid)

        wid = QWidget(self)
        wid.setLayout(QHBoxLayout())
        if self._conv_set:
            spb = SiriusSpinbox(wid, init_channel=self._dev+':Px2mmScaleX-SP')
            lbl = SiriusLabel(wid, init_channel=self._dev+':Px2mmScaleX-RB')
            spb.showStepExponent = False
            wid.layout().addWidget(spb)
            wid.layout().addWidget(lbl)
        else:
            lbl = SiriusLabel(wid, init_channel=self._dev+':Px2mmScaleX-Cte')
            wid.layout().addWidget(lbl)
        self.layout().addRow(QLabel(
            'Pxl 2 mm Scale X', self, alignment=Qt.AlignBottom), wid)

        wid = QWidget(self)
        wid.setLayout(QHBoxLayout())
        if self._conv_set:
            spb = SiriusSpinbox(wid, init_channel=self._dev+':Px2mmScaleY-SP')
            lbl = SiriusLabel(wid, init_channel=self._dev+':Px2mmScaleY-RB')
            spb.showStepExponent = False
            wid.layout().addWidget(spb)
            wid.layout().addWidget(lbl)
        else:
            lbl = SiriusLabel(wid, init_channel=self._dev+':Px2mmScaleY-Cte')
            wid.layout().addWidget(lbl)
        self.layout().addRow(QLabel(
            'Pxl 2 mm Scale Y', self, alignment=Qt.AlignBottom), wid)

        wid = QWidget(self)
        wid.setLayout(QHBoxLayout())
        sttbtn = PyDMStateButton(
            wid, init_channel=self._dev+':Px2mmAutoCenter-Sel')
        lbl = SiriusLedState(
            wid, init_channel=self._dev+':Px2mmAutoCenter-Sts')
        wid.layout().addWidget(sttbtn)
        wid.layout().addWidget(lbl)
        self.layout().addRow(QLabel(
            'Auto Center', self, alignment=Qt.AlignBottom), wid)

        wid = QWidget(self)
        wid.setLayout(QHBoxLayout())
        spnbox = SiriusSpinbox(wid, init_channel=self._dev+':Px2mmCenterX-SP')
        lbl = SiriusLabel(wid, init_channel=self._dev+':Px2mmCenterX-RB')
        spnbox.showStepExponent = False
        wid.layout().addWidget(spnbox)
        wid.layout().addWidget(lbl)
        self.layout().addRow(QLabel(
            'Pxl 2 mm Center X', self, alignment=Qt.AlignBottom), wid)

        wid = QWidget(self)
        wid.setLayout(QHBoxLayout())
        spnbox = SiriusSpinbox(wid, init_channel=self._dev+':Px2mmCenterY-SP')
        lbl = SiriusLabel(wid, init_channel=self._dev+':Px2mmCenterY-RB')
        spnbox.showStepExponent = False
        wid.layout().addWidget(spnbox)
        wid.layout().addWidget(lbl)
        self.layout().addRow(QLabel(
            'Pxl 2 mm Center Y', self, alignment=Qt.AlignBottom), wid)
예제 #16
0
    def __init__(self,
                 name=None,
                 plugin=None,
                 parent=None,
                 options=DEFAULT_OPTIONS):
        super().__init__(name, plugin, parent=parent, options=options)

        # Attributes
        self.text_color = self.get_option('text_color')
        self.supported_encodings = self.get_option('supported_encodings')
        self.search_thread = None
        self.running = False
        self.more_options_action = None
        self.extras_toolbar = None

        search_text = self.get_option('search_text')
        path_history = self.get_option('path_history')
        exclude = self.get_option('exclude')

        if not isinstance(search_text, (list, tuple)):
            search_text = [search_text]

        if not isinstance(exclude, (list, tuple)):
            exclude = [exclude]

        if not isinstance(path_history, (list, tuple)):
            path_history = [path_history]

        # Widgets
        self.search_text_edit = PatternComboBox(
            self,
            search_text,
            _("Search pattern"),
        )
        self.search_label = QLabel(_('Search:'))
        self.search_in_label = QLabel(_('Location:'))
        self.exclude_label = QLabel(_('Exclude:'))
        self.path_selection_combo = SearchInComboBox(path_history, self)
        self.exclude_pattern_edit = PatternComboBox(
            self,
            exclude,
            _("Exclude pattern"),
        )
        self.result_browser = ResultsBrowser(
            self,
            text_color=self.text_color,
            max_results=self.get_option('max_results'),
        )

        # Setup
        self.search_label.setBuddy(self.search_text_edit)
        self.exclude_label.setBuddy(self.exclude_pattern_edit)

        fm = self.search_label.fontMetrics()
        base_size = int(fm.width(_('Location:')) * 1.2)
        self.search_label.setMinimumWidth(base_size)
        self.search_in_label.setMinimumWidth(base_size)
        self.exclude_label.setMinimumWidth(base_size)

        exclude_idx = self.get_option('exclude_index')
        if (exclude_idx is not None and exclude_idx >= 0
                and exclude_idx < self.exclude_pattern_edit.count()):
            self.exclude_pattern_edit.setCurrentIndex(exclude_idx)

        search_in_index = self.get_option('search_in_index')
        self.path_selection_combo.set_current_searchpath_index(search_in_index)

        # Layout
        layout = QHBoxLayout()
        layout.addWidget(self.result_browser)
        self.setLayout(layout)

        # Signals
        self.path_selection_combo.sig_redirect_stdio_requested.connect(
            self.sig_redirect_stdio_requested)
        self.search_text_edit.valid.connect(lambda valid: self.find())
        self.exclude_pattern_edit.valid.connect(lambda valid: self.find())
        self.result_browser.sig_edit_goto_requested.connect(
            self.sig_edit_goto_requested)
        self.result_browser.sig_max_results_reached.connect(
            self.sig_max_results_reached)
        self.result_browser.sig_max_results_reached.connect(
            self._stop_and_reset_thread)
        self.search_text_edit.sig_resized.connect(self._update_size)
예제 #17
0
    def _get_config_widget(self, parent):
        gb_pos = QGroupBox('Image Processing ', parent)

        meth_sp = PyDMEnumComboBox(
            gb_pos, init_channel=self._dev+':CalcMethod-Sel')
        meth_lb = SiriusLabel(gb_pos, init_channel=self._dev+':CalcMethod-Sts')
        meth_ld = QLabel('Method', gb_pos)

        nrpt_ld = QLabel('Num. Pts.', gb_pos)
        nrpt_sp = SiriusSpinbox(
            gb_pos, init_channel=self._dev+':NrAverages-SP')
        nrpt_sp.showStepExponent = False
        rdb = PyDMLabel(gb_pos, init_channel=self._dev+':NrAverages-RB')
        rdb.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        slsh = QLabel('/', gb_pos, alignment=Qt.AlignCenter)
        slsh.setStyleSheet('min-width:0.7em; max-width:0.7em;')
        cnt = PyDMLabel(gb_pos, init_channel=self._dev+':BufferSize-Mon')
        cnt.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
        cnt.setToolTip('Current Buffer Size')
        pbt = PyDMPushButton(
            gb_pos, init_channel=self._dev+':ResetBuffer-Cmd', pressValue=1)
        pbt.setToolTip('Reset Buffer')
        pbt.setIcon(qta.icon('mdi.delete-empty'))
        pbt.setObjectName('rst')
        pbt.setStyleSheet(
            '#rst{min-width:25px; max-width:25px; icon-size:20px;}')
        nrpt_wd = QWidget(gb_pos)
        hbl = QHBoxLayout(nrpt_wd)
        hbl.addWidget(pbt)
        hbl.addStretch()
        hbl.addWidget(cnt)
        hbl.addWidget(slsh)
        hbl.addWidget(rdb)

        rsx_sp = SiriusSpinbox(gb_pos, init_channel=self._dev+':ROISizeX-SP')
        rsx_sp.showStepExponent = False
        rsx_lb = SiriusLabel(gb_pos, init_channel=self._dev+':ROISizeX-RB')
        rsx_ld = QLabel('ROI Size X', gb_pos)

        rsy_sp = SiriusSpinbox(gb_pos, init_channel=self._dev+':ROISizeY-SP')
        rsy_sp.showStepExponent = False
        rsy_lb = SiriusLabel(gb_pos, init_channel=self._dev+':ROISizeY-RB')
        rsy_ld = QLabel('ROI Size Y', gb_pos)

        ra_bt = PyDMStateButton(
            gb_pos, init_channel=self._dev+':ROIAutoCenter-Sel')
        ra_lb = SiriusLabel(
            gb_pos, init_channel=self._dev+':ROIAutoCenter-Sts')
        ra_ld = QLabel('Auto Center:', gb_pos)

        rcx_sp = SiriusSpinbox(gb_pos, init_channel=self._dev+':ROICenterX-SP')
        rcx_sp.showStepExponent = False
        rcx_lb = SiriusLabel(gb_pos, init_channel=self._dev+':ROICenterX-RB')
        rcx_ld = QLabel('ROI Center X', gb_pos)

        rcy_sp = SiriusSpinbox(gb_pos, init_channel=self._dev+':ROICenterY-SP')
        rcy_sp.showStepExponent = False
        rcy_lb = SiriusLabel(gb_pos, init_channel=self._dev+':ROICenterY-RB')
        rcy_ld = QLabel('ROI Center Y', gb_pos)

        sts_bt = QPushButton(qta.icon('fa5s.ellipsis-h'), '', gb_pos)
        sts_bt.setToolTip('Open Detailed Configs')
        sts_bt.setObjectName('sts')
        sts_bt.setStyleSheet(
            '#sts{min-width:25px; max-width:25px; icon-size:20px;}')
        Window = create_window_from_widget(
            _DetailedWidget, title='Image Processing Detailed Configs')
        connect_window(
            sts_bt, Window, gb_pos, device=self._dev,
            convertion_set=self._conv_set)
        hlay = QHBoxLayout()
        hlay.addWidget(sts_bt, alignment=Qt.AlignRight)

        lay = QGridLayout(gb_pos)
        if self._ori == 'V':
            lay.addWidget(meth_ld, 0, 0, 2, 1, alignment=Qt.AlignLeft)
            lay.addWidget(meth_sp, 0, 1)
            lay.addWidget(meth_lb, 1, 1)
            lay.addWidget(nrpt_ld, 2, 0, alignment=Qt.AlignLeft)
            lay.addWidget(nrpt_sp, 2, 1)
            lay.addWidget(nrpt_wd, 3, 0, 1, 2)
            lay.addWidget(rsx_ld, 4+0, 0, 2, 1, alignment=Qt.AlignLeft)
            lay.addWidget(rsx_sp, 4+0, 1)
            lay.addWidget(rsx_lb, 4+1, 1)
            lay.addWidget(rsy_ld, 6+0, 0, 2, 1, alignment=Qt.AlignLeft)
            lay.addWidget(rsy_sp, 6+0, 1)
            lay.addWidget(rsy_lb, 6+1, 1)
            lay.addWidget(sts_bt, 0, 0+4, alignment=Qt.AlignRight)
            lay.addWidget(ra_ld, 2+0, 0+3, 2, 1, alignment=Qt.AlignLeft)
            lay.addWidget(ra_bt, 2+0, 1+3)
            lay.addWidget(ra_lb, 2+1, 1+3, alignment=Qt.AlignLeft)
            lay.addWidget(rcx_ld, 4+0, 0+3, 2, 1, alignment=Qt.AlignLeft)
            lay.addWidget(rcx_sp, 4+0, 1+3)
            lay.addWidget(rcx_lb, 4+1, 1+3)
            lay.addWidget(rcy_ld, 6+0, 0+3, 2, 1, alignment=Qt.AlignLeft)
            lay.addWidget(rcy_sp, 6+0, 1+3)
            lay.addWidget(rcy_lb, 6+1, 1+3)
        else:
            lay.addWidget(meth_ld, 0, 0, 2, 1, alignment=Qt.AlignLeft)
            lay.addWidget(meth_sp, 0, 1)
            lay.addWidget(meth_lb, 1, 1)
            lay.addWidget(nrpt_ld, 2, 0, alignment=Qt.AlignLeft)
            lay.addWidget(nrpt_sp, 2, 1)
            lay.addWidget(nrpt_wd, 3, 0, 1, 2)
            lay.addWidget(rsx_ld, 4+0, 0, 2, 1, alignment=Qt.AlignLeft)
            lay.addWidget(rsx_sp, 4+0, 1)
            lay.addWidget(rsx_lb, 4+1, 1)
            lay.addWidget(rsy_ld, 6+0, 0, 2, 1, alignment=Qt.AlignLeft)
            lay.addWidget(rsy_sp, 6+0, 1)
            lay.addWidget(rsy_lb, 6+1, 1)
            lay.addWidget(ra_ld, 8+0, 0, 2, 1, alignment=Qt.AlignLeft)
            lay.addWidget(ra_bt, 8+0, 1)
            lay.addWidget(ra_lb, 8+1, 1, alignment=Qt.AlignLeft)
            lay.addWidget(rcx_ld, 10+0, 0, 2, 1, alignment=Qt.AlignLeft)
            lay.addWidget(rcx_sp, 10+0, 1)
            lay.addWidget(rcx_lb, 10+1, 1)
            lay.addWidget(rcy_ld, 12+0, 0, 2, 1, alignment=Qt.AlignLeft)
            lay.addWidget(rcy_sp, 12+0, 1)
            lay.addWidget(rcy_lb, 12+1, 1)
            lay.addWidget(sts_bt, 14, 0, alignment=Qt.AlignLeft)
            lay.setRowStretch(15, 5)

        return gb_pos
예제 #18
0
    def setup_page(self):
        newcb = self.create_checkbox

        # Python executable Group
        pyexec_group = QGroupBox(_("Python interpreter"))
        pyexec_bg = QButtonGroup(pyexec_group)
        pyexec_label = QLabel(
            _("Select the Python interpreter for all Spyder "
              "consoles"))
        self.def_exec_radio = self.create_radiobutton(
            _("Default (i.e. the same as Spyder's)"),
            'default',
            button_group=pyexec_bg,
        )
        self.cus_exec_radio = self.create_radiobutton(
            _("Use the following Python interpreter:"),
            'custom',
            button_group=pyexec_bg,
        )

        if os.name == 'nt':
            filters = _("Executables") + " (*.exe)"
        else:
            filters = None

        pyexec_layout = QVBoxLayout()
        pyexec_layout.addWidget(pyexec_label)
        pyexec_layout.addWidget(self.def_exec_radio)
        pyexec_layout.addWidget(self.cus_exec_radio)
        self.validate_custom_interpreters_list()
        self.cus_exec_combo = self.create_file_combobox(
            _('Recent custom interpreters'),
            self.get_option('custom_interpreters_list'),
            'custom_interpreter',
            filters=filters,
            default_line_edit=True,
            adjust_to_contents=True,
            validate_callback=programs.is_python_interpreter,
        )
        self.def_exec_radio.toggled.connect(self.cus_exec_combo.setDisabled)
        self.cus_exec_radio.toggled.connect(self.cus_exec_combo.setEnabled)
        pyexec_layout.addWidget(self.cus_exec_combo)
        pyexec_group.setLayout(pyexec_layout)

        self.pyexec_edit = self.cus_exec_combo.combobox.lineEdit()

        # UMR Group
        umr_group = QGroupBox(_("User Module Reloader (UMR)"))
        umr_label = QLabel(
            _("UMR forces Python to reload modules which were "
              "imported when executing a file in a Python or "
              "IPython console with the <i>runfile</i> "
              "function."))
        umr_label.setWordWrap(True)
        umr_enabled_box = newcb(
            _("Enable UMR"),
            'umr/enabled',
            msg_if_enabled=True,
            msg_warning=_(
                "This option will enable the User Module Reloader (UMR) "
                "in Python/IPython consoles. UMR forces Python to "
                "reload deeply modules during import when running a "
                "Python file using the Spyder's builtin function "
                "<b>runfile</b>."
                "<br><br><b>1.</b> UMR may require to restart the "
                "console in which it will be called "
                "(otherwise only newly imported modules will be "
                "reloaded when executing files)."
                "<br><br><b>2.</b> If errors occur when re-running a "
                "PyQt-based program, please check that the Qt objects "
                "are properly destroyed (e.g. you may have to use the "
                "attribute <b>Qt.WA_DeleteOnClose</b> on your main "
                "window, using the <b>setAttribute</b> method)"),
        )
        umr_verbose_box = newcb(
            _("Show reloaded modules list"),
            'umr/verbose',
            msg_info=_("Please note that these changes will "
                       "be applied only to new consoles"),
        )
        umr_namelist_btn = QPushButton(
            _("Set UMR excluded (not reloaded) modules"))
        umr_namelist_btn.clicked.connect(self.set_umr_namelist)

        umr_layout = QVBoxLayout()
        umr_layout.addWidget(umr_label)
        umr_layout.addWidget(umr_enabled_box)
        umr_layout.addWidget(umr_verbose_box)
        umr_layout.addWidget(umr_namelist_btn)
        umr_group.setLayout(umr_layout)

        vlayout = QVBoxLayout()
        vlayout.addWidget(pyexec_group)
        vlayout.addWidget(umr_group)
        vlayout.addStretch(1)
        self.setLayout(vlayout)
예제 #19
0
    def initialize(self):

        self.resize(_main_window_geometry["initial_width"], _main_window_geometry["initial_height"])

        self.setMinimumWidth(_main_window_geometry["min_width"])
        self.setMinimumHeight(_main_window_geometry["min_height"])

        self.setWindowTitle(self.gpc.get_window_title())

        self.central_widget = TwoPanelWidget(gpc=self.gpc, gui_vars=self.gui_vars)
        self.setCentralWidget(self.central_widget)

        # Status bar
        self.statusLabel = QLabel()
        self.statusBar().addWidget(self.statusLabel)
        self.statusProgressBar = QProgressBar()
        self.statusProgressBar.setFixedWidth(200)
        self.statusBar().addPermanentWidget(self.statusProgressBar)

        self.statusLabelDefaultText = "No data is loaded"
        self.statusLabel.setText(self.statusLabelDefaultText)

        # 'Scan Data' menu item
        self.action_read_file = QAction("&Read File...", self)
        self.action_read_file.setStatusTip("Load data from HDF5 file")
        self.action_read_file.triggered.connect(self.central_widget.left_panel.load_data_widget.pb_file.clicked)

        self.action_load_run = QAction("&Load Run...", self)
        self.action_load_run.setEnabled(self.gui_vars["gui_state"]["databroker_available"])
        self.action_load_run.setStatusTip("Load data from database (Databroker)")
        self.action_load_run.triggered.connect(self.central_widget.left_panel.load_data_widget.pb_dbase.clicked)

        self.action_view_metadata = QAction("View Metadata...", self)
        self.action_view_metadata.setEnabled(self.gpc.is_scan_metadata_available())
        self.action_view_metadata.setStatusTip("View metadata for loaded run")
        self.action_view_metadata.triggered.connect(
            self.central_widget.left_panel.load_data_widget.pb_view_metadata.clicked
        )

        # Main menu
        menubar = self.menuBar()
        # Disable native menu bar (it doesn't work on MacOS 10.15 with PyQt<=5.11)
        #   It may work with later versions of PyQt when they become available.
        menubar.setNativeMenuBar(False)
        loadData = menubar.addMenu("Scan &Data")
        loadData.addAction(self.action_read_file)
        loadData.addAction(self.action_load_run)
        loadData.addSeparator()
        loadData.addAction(self.action_view_metadata)

        # 'Fitting Model' menu item
        self.action_lines_find_automatically = QAction("Find &Automatically...", self)
        self.action_lines_find_automatically.setStatusTip("Automatically find emission lines in total spectrum")
        self.action_lines_find_automatically.triggered.connect(
            self.central_widget.left_panel.model_widget.pb_find_elines.clicked
        )

        self.action_lines_load_from_file = QAction("Load From &File...", self)
        self.action_lines_load_from_file.setStatusTip(
            "Load processing parameters, including selected emission lines, from JSON file"
        )
        self.action_lines_load_from_file.triggered.connect(
            self.central_widget.left_panel.model_widget.pb_load_elines.clicked
        )

        self.action_lines_load_quant_standard = QAction("Load &Quantitative Standards...", self)
        self.action_lines_load_quant_standard.setStatusTip(
            "Load quantitative standard. The emission lines from the standard are automatically selected"
        )
        self.action_lines_load_quant_standard.triggered.connect(
            self.central_widget.left_panel.model_widget.pb_load_qstandard.clicked
        )

        self.action_add_remove_emission_lines = QAction("&Add/Remove Emission Lines...", self)
        self.action_add_remove_emission_lines.setStatusTip("Manually add and remove emission lines")
        self.action_add_remove_emission_lines.triggered.connect(
            self.central_widget.left_panel.model_widget.pb_manage_emission_lines.clicked
        )

        self.action_save_model_params = QAction("&Save Model Parameters...", self)
        self.action_save_model_params.setStatusTip("Save model parameters to JSON file")
        self.action_save_model_params.triggered.connect(
            self.central_widget.left_panel.model_widget.pb_save_elines.clicked
        )

        self.action_add_remove_emission_lines = QAction("Start Model &Fitting", self)
        self.action_add_remove_emission_lines.setStatusTip("Run computations: start fitting for total spectrum")
        self.action_add_remove_emission_lines.triggered.connect(
            self.central_widget.left_panel.model_widget.pb_start_fitting.clicked
        )

        fittingModel = menubar.addMenu("Fitting &Model")
        emissionLines = fittingModel.addMenu("&Emission Lines")
        emissionLines.addAction(self.action_lines_find_automatically)
        emissionLines.addAction(self.action_lines_load_from_file)
        emissionLines.addAction(self.action_lines_load_quant_standard)
        fittingModel.addAction(self.action_add_remove_emission_lines)
        fittingModel.addSeparator()
        fittingModel.addAction(self.action_save_model_params)
        fittingModel.addSeparator()
        fittingModel.addAction(self.action_add_remove_emission_lines)

        # "XRF Maps" menu item
        self.action_start_xrf_map_fitting = QAction("Start XRF Map &Fitting", self)
        self.action_start_xrf_map_fitting.setStatusTip("Run computations: start fitting for XRF maps")
        self.action_start_xrf_map_fitting.triggered.connect(
            self.central_widget.left_panel.fit_maps_widget.pb_start_map_fitting.clicked
        )

        self.action_compute_rois = QAction("Compute &ROIs...", self)
        self.action_compute_rois.setStatusTip("Compute XRF Maps based on spectral ROIs")
        self.action_compute_rois.triggered.connect(
            self.central_widget.left_panel.fit_maps_widget.pb_compute_roi_maps.clicked
        )

        self.action_load_quant_calibration = QAction("&Load Quantitative Calibration...", self)
        self.action_load_quant_calibration.setStatusTip(
            "Load quantitative calibration from JSON file. Calibration is used for scaling of XRF Maps"
        )
        self.action_load_quant_calibration.triggered.connect(
            self.central_widget.left_panel.fit_maps_widget.pb_load_quant_calib.clicked
        )

        self.action_save_quant_calibration = QAction("&Save Quantitative Calibration...", self)
        self.action_save_quant_calibration.setStatusTip(
            "Save Quantitative Calibration based on XRF map of the standard sample"
        )
        self.action_save_quant_calibration.triggered.connect(
            self.central_widget.left_panel.fit_maps_widget.pb_save_q_calibration.clicked
        )

        self.action_export_to_tiff_and_txt = QAction("&Export to TIFF and TXT...", self)
        self.action_export_to_tiff_and_txt.setStatusTip("Export XRF Maps as TIFF and/or TXT files")
        self.action_export_to_tiff_and_txt.triggered.connect(
            self.central_widget.left_panel.fit_maps_widget.pb_export_to_tiff_and_txt.clicked
        )

        xrfMaps = menubar.addMenu("XRF &Maps")
        xrfMaps.addAction(self.action_start_xrf_map_fitting)
        xrfMaps.addAction(self.action_compute_rois)
        xrfMaps.addSeparator()
        xrfMaps.addAction(self.action_load_quant_calibration)
        xrfMaps.addSeparator()
        xrfMaps.addAction(self.action_save_quant_calibration)
        xrfMaps.addAction(self.action_export_to_tiff_and_txt)

        # "View" menu item
        self.action_show_matplotlib_toolbar = QAction("Show &Matplotlib Toolbar", self)
        self.action_show_matplotlib_toolbar.setCheckable(True)
        self.action_show_matplotlib_toolbar.setChecked(True)
        self.action_show_matplotlib_toolbar.setStatusTip("Show Matplotlib Toolbar on the plots")
        self.action_show_matplotlib_toolbar.toggled.connect(self.action_show_matplotlib_toolbar_toggled)

        self.action_show_widget_tooltips = QAction("Show &Tooltips", self)
        self.action_show_widget_tooltips.setCheckable(True)
        self.action_show_widget_tooltips.setChecked(self.gui_vars["show_tooltip"])
        self.action_show_widget_tooltips.setStatusTip("Show widget tooltips")
        self.action_show_widget_tooltips.toggled.connect(self.action_show_widget_tooltips_toggled)

        options = menubar.addMenu("&Options")
        options.addAction(self.action_show_widget_tooltips)
        options.addAction(self.action_show_matplotlib_toolbar)

        # "Help" menu item
        self.action_online_docs = QAction("Online &Documentation", self)
        self.action_online_docs.setStatusTip("Open online documentation in the default browser")
        self.action_online_docs.triggered.connect(self.action_online_docs_triggered)

        self.action_about = QAction("&About PyXRF", self)
        self.action_about.setStatusTip("Show information about this program")
        self.action_about.triggered.connect(self.action_about_triggered)

        help = menubar.addMenu("&Help")
        help.addAction(self.action_online_docs)
        help.addSeparator()
        help.addAction(self.action_about)

        self.update_widget_state()

        # Connect signals
        self.central_widget.left_panel.load_data_widget.update_preview_map_range.connect(
            self.central_widget.right_panel.tab_preview_plots.preview_plot_count.update_map_range
        )

        # Before loading a new file or run
        self.central_widget.left_panel.load_data_widget.signal_loading_new_run.connect(
            self.central_widget.right_panel.slot_activate_tab_preview
        )

        # Open a new file or run
        self.central_widget.left_panel.load_data_widget.signal_new_run_loaded.connect(
            self.central_widget.left_panel.slot_activate_load_data_tab
        )
        self.central_widget.left_panel.load_data_widget.signal_new_run_loaded.connect(
            self.central_widget.right_panel.slot_activate_tab_preview
        )
        self.central_widget.left_panel.load_data_widget.signal_new_run_loaded.connect(self.slot_new_run_loaded)
        self.central_widget.left_panel.load_data_widget.signal_new_run_loaded.connect(
            self.wnd_image_wizard.slot_update_table
        )
        self.central_widget.left_panel.load_data_widget.signal_new_run_loaded.connect(
            self.central_widget.right_panel.tab_plot_xrf_maps.slot_update_dataset_info
        )
        self.central_widget.left_panel.load_data_widget.signal_new_run_loaded.connect(
            self.central_widget.right_panel.tab_plot_rgb_maps.slot_update_dataset_info
        )
        self.central_widget.left_panel.load_data_widget.signal_new_run_loaded.connect(
            self.wnd_load_quantitative_calibration.update_all_data
        )
        self.central_widget.left_panel.load_data_widget.signal_new_run_loaded.connect(
            self.central_widget.left_panel.fit_maps_widget.slot_update_for_new_loaded_run
        )

        # New model is loaded or processing parameters (incident energy) was changed
        self.central_widget.left_panel.model_widget.signal_incident_energy_or_range_changed.connect(
            self.central_widget.right_panel.tab_preview_plots.preview_plot_spectrum.redraw_preview_plot
        )
        self.central_widget.left_panel.model_widget.signal_incident_energy_or_range_changed.connect(
            self.wnd_manage_emission_lines.update_widget_data
        )
        self.central_widget.left_panel.model_widget.signal_incident_energy_or_range_changed.connect(
            self.central_widget.right_panel.tab_plot_fitting_model.redraw_plot_fit
        )

        self.central_widget.left_panel.model_widget.signal_model_loaded.connect(
            self.central_widget.right_panel.tab_preview_plots.preview_plot_spectrum.redraw_preview_plot
        )
        self.central_widget.left_panel.model_widget.signal_model_loaded.connect(
            self.central_widget.right_panel.slot_activate_tab_fitting_model
        )
        self.central_widget.left_panel.model_widget.signal_model_loaded.connect(
            self.central_widget.right_panel.tab_plot_fitting_model.update_controls
        )
        self.central_widget.left_panel.model_widget.signal_model_loaded.connect(
            self.wnd_manage_emission_lines.update_widget_data
        )

        # XRF Maps dataset changed
        self.central_widget.right_panel.tab_plot_xrf_maps.signal_maps_dataset_selection_changed.connect(
            self.wnd_image_wizard.slot_update_table
        )

        self.central_widget.right_panel.tab_plot_xrf_maps.signal_maps_dataset_selection_changed.connect(
            self.central_widget.right_panel.tab_plot_rgb_maps.combo_select_dataset_update_current_index
        )
        self.central_widget.right_panel.tab_plot_rgb_maps.signal_rgb_maps_dataset_selection_changed.connect(
            self.central_widget.right_panel.tab_plot_xrf_maps.combo_select_dataset_update_current_index
        )

        self.central_widget.right_panel.tab_plot_xrf_maps.signal_maps_norm_changed.connect(
            self.wnd_image_wizard.slot_update_ranges
        )

        # Quantitative calibration changed
        self.wnd_load_quantitative_calibration.signal_quantitative_calibration_changed.connect(
            self.central_widget.right_panel.tab_plot_rgb_maps.slot_update_ranges
        )
        self.wnd_load_quantitative_calibration.signal_quantitative_calibration_changed.connect(
            self.wnd_image_wizard.slot_update_ranges
        )

        # Selected element is changed (tools for emission line selection)
        self.wnd_manage_emission_lines.signal_selected_element_changed.connect(
            self.central_widget.right_panel.tab_plot_fitting_model.slot_selection_item_changed
        )
        self.central_widget.right_panel.tab_plot_fitting_model.signal_selected_element_changed.connect(
            self.wnd_manage_emission_lines.slot_selection_item_changed
        )
        self.central_widget.right_panel.tab_plot_fitting_model.signal_add_line.connect(
            self.wnd_manage_emission_lines.pb_add_eline_clicked
        )
        self.central_widget.right_panel.tab_plot_fitting_model.signal_remove_line.connect(
            self.wnd_manage_emission_lines.pb_remove_eline_clicked
        )
        self.wnd_manage_emission_lines.signal_update_element_selection_list.connect(
            self.central_widget.right_panel.tab_plot_fitting_model.slot_update_eline_selection_list
        )
        self.wnd_manage_emission_lines.signal_update_add_remove_btn_state.connect(
            self.central_widget.right_panel.tab_plot_fitting_model.slot_update_add_remove_btn_state
        )

        self.wnd_manage_emission_lines.signal_selected_element_changed.connect(
            self.central_widget.left_panel.model_widget.slot_selection_item_changed
        )
        self.central_widget.right_panel.tab_plot_fitting_model.signal_selected_element_changed.connect(
            self.central_widget.left_panel.model_widget.slot_selection_item_changed
        )

        # Total spectrum fitting completed
        self.central_widget.left_panel.model_widget.signal_total_spectrum_fitting_completed.connect(
            self.wnd_manage_emission_lines.update_eline_table
        )
        # Total spectrum invalidated
        self.wnd_manage_emission_lines.signal_parameters_changed.connect(
            self.central_widget.left_panel.model_widget.update_fit_status
        )
        # New dataset loaded or different channel selected. Compute fit parameters.
        self.central_widget.left_panel.load_data_widget.signal_data_channel_changed.connect(
            self.central_widget.left_panel.model_widget.clear_fit_status
        )
        self.central_widget.left_panel.load_data_widget.signal_new_run_loaded.connect(
            self.central_widget.left_panel.model_widget.clear_fit_status
        )
        self.central_widget.left_panel.model_widget.signal_incident_energy_or_range_changed.connect(
            self.central_widget.left_panel.model_widget.clear_fit_status
        )

        # Update map datasets (Fitted maps)
        self.central_widget.left_panel.fit_maps_widget.signal_map_fitting_complete.connect(
            self.central_widget.right_panel.tab_plot_xrf_maps.slot_update_dataset_info
        )
        self.central_widget.left_panel.fit_maps_widget.signal_map_fitting_complete.connect(
            self.central_widget.right_panel.tab_plot_rgb_maps.slot_update_dataset_info
        )
        self.central_widget.left_panel.fit_maps_widget.signal_activate_tab_xrf_maps.connect(
            self.central_widget.right_panel.slot_activate_tab_xrf_maps
        )

        # Update map datasets (ROI maps)
        self.wnd_compute_roi_maps.signal_roi_computation_complete.connect(
            self.central_widget.right_panel.tab_plot_xrf_maps.slot_update_dataset_info
        )
        self.wnd_compute_roi_maps.signal_roi_computation_complete.connect(
            self.central_widget.right_panel.tab_plot_rgb_maps.slot_update_dataset_info
        )
        self.wnd_compute_roi_maps.signal_activate_tab_xrf_maps.connect(
            self.central_widget.right_panel.slot_activate_tab_xrf_maps
        )

        self.signal_fitting_parameters_changed.connect(self.wnd_general_fitting_settings.update_form_data)
        self.signal_fitting_parameters_changed.connect(self.wnd_fitting_parameters_shared.update_form_data)
        self.signal_fitting_parameters_changed.connect(self.wnd_fitting_parameters_lines.update_form_data)
        self.signal_fitting_parameters_changed.connect(self.wnd_manage_emission_lines.update_widget_data)
예제 #20
0
    def create_widgets(self, show_animation_button=True):
        """creates the menu objects"""
        # title
        self.title_label = QLabel("Title:")
        self.title_edit = QLineEdit(str(self._default_title))
        self.title_button = QPushButton("Default")

        # Min
        self.min_label = QLabel("Min:")
        self.min_edit = QLineEdit(str(self._default_min))
        self.min_button = QPushButton("Default")

        # Max
        self.max_label = QLabel("Max:")
        self.max_edit = QLineEdit(str(self._default_max))
        self.max_button = QPushButton("Default")

        #---------------------------------------
        # Format
        self.format_label = QLabel("Format (e.g. %.3f, %g, %.6e):")
        self.format_edit = QLineEdit(str(self._format))
        self.format_button = QPushButton("Default")

        #---------------------------------------
        # Scale
        self.scale_label = QLabel("True Scale:")
        self.scale_edit = QLineEdit(str(self._scale))
        self.scale_button = QPushButton("Default")
        if self._icase_disp is None:
            self.scale_label.setVisible(False)
            self.scale_edit.setVisible(False)
            self.scale_button.setVisible(False)

        # Phase
        self.phase_label = QLabel("Phase (deg):")
        self.phase_edit = QLineEdit(str(self._phase))
        self.phase_button = QPushButton("Default")
        if self._icase_disp is None or self._default_phase is None:
            self.phase_label.setVisible(False)
            self.phase_edit.setVisible(False)
            self.phase_button.setVisible(False)
            self.phase_edit.setText('0.0')

        #---------------------------------------
        self.arrow_scale_label = QLabel("Arrow Scale:")
        self.arrow_scale_edit = QLineEdit(str(self._arrow_scale))
        self.arrow_scale_button = QPushButton("Default")
        if self._icase_vector is None:
            self.arrow_scale_label.setVisible(False)
            self.arrow_scale_edit.setVisible(False)
            self.arrow_scale_button.setVisible(False)

        #tip = QtGui.QToolTip()
        #tip.setTe
        #self.format_edit.toolTip(tip)

        #---------------------------------------
        # nlabels
        self.nlabels_label = QLabel("Number of Labels:")
        self.nlabels_edit = QLineEdit(str(self._nlabels))
        self.nlabels_button = QPushButton("Default")

        self.labelsize_label = QLabel("Label Size:")
        self.labelsize_edit = QLineEdit(str(self._labelsize))
        self.labelsize_button = QPushButton("Default")

        self.ncolors_label = QLabel("Number of Colors:")
        self.ncolors_edit = QLineEdit(str(self._ncolors))
        self.ncolors_button = QPushButton("Default")

        self.colormap_label = QLabel("Color Map:")
        self.colormap_edit = QComboBox(self)
        self.colormap_button = QPushButton("Default")
        for key in colormap_keys:
            self.colormap_edit.addItem(key)
        self.colormap_edit.setCurrentIndex(colormap_keys.index(self._colormap))

        # --------------------------------------------------------------
        # the header
        self.grid2_title = QLabel("Color Scale:")

        # red/blue or blue/red
        self.low_to_high_radio = QRadioButton('Low -> High')
        self.high_to_low_radio = QRadioButton('High -> Low')
        widget = QWidget(self)
        low_to_high_group = QButtonGroup(widget)
        low_to_high_group.addButton(self.low_to_high_radio)
        low_to_high_group.addButton(self.high_to_low_radio)
        self.low_to_high_radio.setChecked(self._default_is_low_to_high)
        self.high_to_low_radio.setChecked(not self._default_is_low_to_high)

        # horizontal / vertical
        self.horizontal_radio = QRadioButton("Horizontal")
        self.vertical_radio = QRadioButton("Vertical")
        widget = QWidget(self)
        horizontal_vertical_group = QButtonGroup(widget)
        horizontal_vertical_group.addButton(self.horizontal_radio)
        horizontal_vertical_group.addButton(self.vertical_radio)
        self.horizontal_radio.setChecked(self._default_is_horizontal)
        self.vertical_radio.setChecked(not self._default_is_horizontal)

        # on / off
        self.show_radio = QRadioButton("Show")
        self.hide_radio = QRadioButton("Hide")
        widget = QWidget(self)
        show_hide_group = QButtonGroup(widget)
        show_hide_group.addButton(self.show_radio)
        show_hide_group.addButton(self.hide_radio)
        self.show_radio.setChecked(self._default_is_shown)
        self.hide_radio.setChecked(not self._default_is_shown)

        # --------------------------------------------------------------

        if self._icase_fringe is None:
            self.title_label.setVisible(False)
            self.title_edit.setVisible(False)
            self.title_button.setVisible(False)

        if not self._is_fringe:
            self.max_label.hide()
            self.min_label.hide()
            self.max_edit.hide()
            self.min_edit.hide()
            self.max_button.hide()
            self.min_button.hide()

            self.format_label.hide()
            self.format_edit.hide()
            self.format_button.hide()

            self.nlabels_label.hide()
            self.nlabels_edit.hide()
            self.nlabels_button.hide()

            self.ncolors_label.hide()
            self.ncolors_edit.hide()
            self.ncolors_button.hide()

            self.grid2_title.hide()
            self.vertical_radio.hide()
            self.horizontal_radio.hide()
            self.show_radio.hide()
            self.hide_radio.hide()
            self.low_to_high_radio.hide()
            self.high_to_low_radio.hide()

            self.colormap_label.hide()
            self.colormap_edit.hide()
            self.colormap_button.hide()

        self.animate_button = QPushButton('Create Animation')
        self.animate_button.setVisible(show_animation_button)
        #self.advanced_button = QPushButton('Advanced')

        if self._default_icase_disp is None:  # or self._default_icase_vector is None:
            self.animate_button.setEnabled(False)
            self.animate_button.setToolTip(ANIMATE_TOOLTIP_OFF)
        else:
            self.animate_button.setEnabled(True)
            self.animate_button.setToolTip(ANIMATE_TOOLTIP_ON)

        # closing
        self.apply_button = QPushButton("Apply")
        self.ok_button = QPushButton("OK")
        self.cancel_button = QPushButton("Cancel")
예제 #21
0
    def _init_selection_ui(self):
        # LINE 1: Radio box spatial vs spectral axis
        self.axes_prompt = QLabel("Smoothing Axis:")
        self.axes_prompt.setMinimumWidth(150)

        self.spatial_radio = QRadioButton("Spatial")
        self.spatial_radio.setChecked(True)
        self.current_axis = "spatial"
        self.spatial_radio.toggled.connect(self.spatial_radio_checked)

        self.spectral_radio = QRadioButton("Spectral")
        self.spectral_radio.toggled.connect(self.spectral_radio_checked)

        # hbl is short for Horizontal Box Layout
        hbl1 = QHBoxLayout()
        hbl1.addWidget(self.axes_prompt)
        hbl1.addWidget(self.spatial_radio)
        hbl1.addWidget(self.spectral_radio)

        # LINE 2: Kernel Type prompt
        self.k_type_prompt = QLabel("Kernel Type:")
        self.k_type_prompt.setMinimumWidth(150)
        # Load kernel types + names and add to drop down
        self._load_options()
        self.combo = QComboBox()
        self.combo.setMinimumWidth(150)
        self.combo.addItems(self.options[self.current_axis])

        hbl2 = QHBoxLayout()
        hbl2.addWidget(self.k_type_prompt)
        hbl2.addWidget(self.combo)

        # LINE 3: Kernel size
        self.size_prompt = QLabel(
            self.smooth_cube.get_kernel_size_prompt(self.current_kernel_type))
        self.size_prompt.setWordWrap(True)
        self.size_prompt.setMinimumWidth(150)
        self.unit_label = QLabel(
            self.smooth_cube.get_kernel_unit(self.current_kernel_type))
        self.k_size = QLineEdit("1")  # Default Kernel size set here

        hbl3 = QHBoxLayout()
        hbl3.addWidget(self.size_prompt)
        hbl3.addWidget(self.k_size)
        hbl3.addWidget(self.unit_label)

        # LINE 4: Data component drop down
        self.component_prompt = QLabel("Data Component:")
        self.component_prompt.setWordWrap(True)
        self.component_prompt.setMinimumWidth(150)
        # Load component_ids and add to drop down

        # Add the data component labels to the drop down, with the ComponentID
        # set as the userData:

        if self.parent is not None and hasattr(self.parent, 'data_components'):
            labeldata = [(str(cid), cid)
                         for cid in self.parent.data_components]
        else:
            labeldata = [(str(cid), cid)
                         for cid in self.data.main_components()]

        self.component_combo = QComboBox()
        update_combobox(self.component_combo, labeldata)

        self.component_combo.setMaximumWidth(150)
        self.component_combo.setCurrentIndex(0)
        if self.allow_preview:
            self.component_combo.currentIndexChanged.connect(
                self.update_preview_button)

        hbl4 = QHBoxLayout()
        hbl4.addWidget(self.component_prompt)
        hbl4.addWidget(self.component_combo)

        # Line 5: Preview Message
        message = "Info: Smoothing previews are displayed on " \
                  "CubeViz's left and single image viewers."
        self.preview_message = QLabel(message)
        self.preview_message.setWordWrap(True)
        self.preview_message.hide()
        hbl5 = QHBoxLayout()
        hbl5.addWidget(self.preview_message)

        # LINE 6: preview ok cancel buttons
        self.previewButton = QPushButton("Preview Slice")
        self.previewButton.clicked.connect(self.call_preview)

        self.okButton = QPushButton("Smooth Cube")
        self.okButton.clicked.connect(self.call_main)
        self.okButton.setDefault(True)

        self.cancelButton = QPushButton("Cancel")
        self.cancelButton.clicked.connect(self.cancel)

        hbl6 = QHBoxLayout()
        hbl6.addStretch(1)
        if self.allow_preview:
            hbl6.addWidget(self.previewButton)
        hbl6.addWidget(self.cancelButton)
        hbl6.addWidget(self.okButton)

        # Add Lines to Vertical Layout
        # vbl is short for Vertical Box Layout
        vbl = QVBoxLayout()
        if self.allow_spectral_axes:
            vbl.addLayout(hbl1)
        vbl.addLayout(hbl2)
        vbl.addLayout(hbl3)
        vbl.addLayout(hbl4)
        vbl.addLayout(hbl5)
        vbl.addLayout(hbl6)

        self.setLayout(vbl)
        self.setMaximumWidth(330)

        # Connect kernel combo box to event handler
        self.combo.currentIndexChanged.connect(self.selection_changed)
        self.selection_changed(0)

        self.show()
예제 #22
0
    def create_widgets(self):
        """creates the menu objects"""
        icase_max = 1000  # TODO: update 1000

        self.icase_fringe = QLabel("iCase:")
        self.icase_fringe_edit = QSpinBox(self)
        self.icase_fringe_edit.setRange(1, icase_max)
        self.icase_fringe_edit.setSingleStep(1)
        self.icase_fringe_edit.setValue(self._icase_fringe)
        self.icase_fringe_edit.setToolTip(
            'Case Number for the Scale/Phase Animation Type.\n'
            'Defaults to the result you had shown when you clicked "Create Animation".\n'
            'iCase can be seen by clicking "Apply" on a result.')

        self.scale = QLabel("True Scale:")
        self.scale_edit = QLineEdit(str(self._scale))
        self.scale_button = QPushButton("Default")
        self.scale_edit.setToolTip('Scale factor of the "deflection"')
        self.scale_button.setToolTip('Sets the scale factor of the gif to %s' %
                                     self._scale)

        self.arrow_scale = QLabel("Arrow Scale:")
        self.arrow_scale_edit = QLineEdit(str(self._scale))
        self.arrow_scale_button = QPushButton("Default")
        self.arrow_scale_edit.setToolTip('Scale factor of the "arrows"')
        self.arrow_scale_button.setToolTip(
            'Sets the arrow scale factor of the gif to %s' % self._arrow_scale)

        self.arrow_scale.setVisible(False)
        self.arrow_scale_edit.setVisible(False)
        self.arrow_scale_button.setVisible(False)

        self.time = QLabel("Total Time (sec):")
        self.time_edit = QDoubleSpinBox(self)
        self.time_edit.setValue(self._default_time)
        self.time_edit.setRange(0.1, 10.0)
        self.time_edit.setDecimals(2)
        self.time_edit.setSingleStep(0.1)
        self.time_button = QPushButton("Default")
        self.time_edit.setToolTip("Total time of the gif")
        self.time_button.setToolTip('Sets the total time of the gif to %.2f' %
                                    self._default_time)

        self.fps = QLabel("Frames/Second:")
        self.fps_edit = QSpinBox(self)
        self.fps_edit.setRange(1, 60)
        self.fps_edit.setSingleStep(1)
        self.fps_edit.setValue(self._default_fps)
        self.fps_button = QPushButton("Default")
        self.fps_edit.setToolTip(
            "A higher FPS is smoother, but may not play well for large gifs")
        self.fps_button.setToolTip('Sets the FPS to %s' % self._default_fps)

        self.resolution = QLabel("Resolution Scale:")
        self.resolution_edit = QSpinBox(self)
        self.resolution_edit.setRange(1, 5)
        self.resolution_edit.setSingleStep(1)
        self.resolution_edit.setValue(self._default_resolution)
        self.resolution_button = QPushButton("Default")
        self.resolution_edit.setToolTip(
            'Scales the window resolution by an integer factor')
        self.resolution_button.setToolTip('Sets the resolution to %s' %
                                          self._default_resolution)

        #-----------------
        # Time plot
        self.icase_start = QLabel("iCase Start:")
        self.icase_start_edit = QSpinBox(self)
        self.icase_start_edit.setRange(0, icase_max)
        self.icase_start_edit.setSingleStep(1)
        self.icase_start_edit.setValue(self._icase_fringe)
        self.icase_start_button = QPushButton("Default")

        self.icase_end = QLabel("iCase End:")
        self.icase_end_edit = QSpinBox(self)
        self.icase_end_edit.setRange(0, icase_max)
        self.icase_end_edit.setSingleStep(1)
        self.icase_end_edit.setValue(self._icase_fringe)
        self.icase_end_button = QPushButton("Default")

        self.icase_delta = QLabel("iCase Delta:")
        self.icase_delta_edit = QSpinBox(self)
        self.icase_delta_edit.setRange(1, icase_max)
        self.icase_delta_edit.setSingleStep(1)
        self.icase_delta_edit.setValue(1)
        self.icase_delta_button = QPushButton("Default")

        self.min_value_enable = QCheckBox()
        self.min_value = QLabel("Min Value:")
        self.min_value_edit = QLineEdit('')
        #self.min_value_edit.setRange(1, 1000)
        #self.min_value_edit.setSingleStep(1)
        #self.min_value_edit.setValue(1)
        self.min_value_button = QPushButton("Default")

        self.max_value_enable = QCheckBox()
        self.max_value = QLabel("Max Value:")
        self.max_value_edit = QLineEdit('')
        #self.min_value_edit.setRange(1, 1000)  # TODO: update 1000
        #self.min_value_edit.setSingleStep(1)
        #self.min_value_edit.setValue(1)
        self.max_value_button = QPushButton("Default")

        # TODO: enable this (uncomment) ------------------------------------------
        #self.min_value_enable.hide()
        #self.min_value.hide()
        #self.min_value_edit.hide()
        #self.min_value_button.hide()

        #self.max_value_enable.hide()
        #self.max_value.hide()
        #self.max_value_edit.hide()
        #self.max_value_button.hide()
        # TODO: enable this (uncomment) ------------------------------------------

        self.icase_start_edit.setToolTip('The first frame of the animation')
        self.icase_end_edit.setToolTip(
            'The last frame of the animation\n'
            'Assumes icase_start + nframes * icase_delta = icase_end')
        self.icase_delta_edit.setToolTip(
            'The frame step size (to skip non-consecutive results).\n'
            'Frame skipping can be used to:\n'
            "  - skip across results that you don't want to plot\n"
            '  - adjust the FPS')

        self.min_value_edit.setToolTip(
            'Min value of the legend (not supported)')
        self.max_value_edit.setToolTip(
            'Max value of the legend (not supported)')
        #'time' : 0.,
        #'default_time' : 0,
        #'icase_start' : 10,
        #'icase_delta' : 3,
        #'min_value' : 0.,
        #'max_value' : 1000.,

        self.browse_folder = QLabel('Output Directory:')
        self.browse_folder_edit = QLineEdit(str(self._default_dirname))
        self.browse_folder_button = QPushButton('Browse')
        self.browse_folder_edit.setToolTip(
            'Location to save the png/gif files')

        self.gif = QLabel("Gif Filename:")
        self.gif_edit = QLineEdit(str(self._default_name + '.gif'))
        self.gif_button = QPushButton('Default')
        self.gif_edit.setToolTip('Name of the gif')
        self.gif_button.setToolTip('Sets the name of the gif to %s.gif' %
                                   self._default_name)

        # scale / phase
        self.animate_scale_radio = QRadioButton("Animate Scale")
        self.animate_phase_radio = QRadioButton("Animate Phase")
        self.animate_time_radio = QRadioButton("Animate Time")
        self.animate_freq_sweeep_radio = QRadioButton(
            "Animate Frequency Sweep")
        self.animate_scale_radio.setToolTip(
            'Animates the scale factor based on the "Animation Type"')
        self.animate_time_radio.setToolTip('Animates the time/load/mode step')

        self.animate_scale_radio.setChecked(self._default_is_scale)
        self.animate_phase_radio.setChecked(not self._default_is_scale)
        self.animate_time_radio.setChecked(False)

        msg = 'Scale : Animates the scale factor based on the "Animation Profile"\n'
        if self._default_phase is None:
            self.animate_phase_radio.setDisabled(True)
            self.animate_phase_radio.setToolTip('Animates the phase angle '
                                                '(only for complex results)')
            msg += 'Phase : Animates the phase angle (only for complex results)\n'
        else:
            self.animate_phase_radio.setToolTip("Animates the phase angle")
            msg += 'Phase : Animates the phase angle\n'
        msg += (
            'Time : Animates the time/load/mode step\n'
            'Freq Sweep : Animates a complex result across a range of frequencies '
            '(not supported)\n')

        self.animate_freq_sweeep_radio.setDisabled(True)
        self.animate_freq_sweeep_radio.setToolTip(
            'Animates a complex result across a range of frequencies (not supported)'
        )
        self.animation_type = QLabel("Animation Type:")
        animation_type = OrderedDict()
        #scale_msg = 'Scale\n'
        #phase_msg = 'Phase\n'
        #time_msg = 'Time\n'
        #animation_types = [
        #('Animate Scale', scale_msg),
        #('Animate Phase', phase_msg),
        #('Animate Time', time_msg),
        ##'Animate Frequency Sweep'
        #]

        if self._phase is not None:
            self.animation_types.append('Animate Phase')
        self.animation_types.append('Animate Time')

        self.animation_profile = QLabel("Animation Profile:")

        self.animation_profile_edit = QComboBox()
        for animation_profile in ANIMATION_PROFILES:
            self.animation_profile_edit.addItem(animation_profile)
        self.animation_profile_edit.setToolTip('The profile for a scaled GIF')

        self.animation_type_edit = QComboBox()
        # TODO: add a tooltip for each item
        for animation_type in self.animation_types:
            self.animation_type_edit.addItem(animation_type)
        #self.animation_type_edit.setToolTip('The profile for a scaled GIF')
        self.animation_type_edit.setToolTip(msg)

        self.csv_profile = QLabel("CSV profile:")
        self.csv_profile_edit = QLineEdit()
        self.csv_profile_browse_button = QPushButton('Browse')
        self.csv_profile_edit.setToolTip(
            'The path to the CSV file of (Scale1, Scale2, Scale3, ...)')

        widget = QWidget(self)
        horizontal_vertical_group = QButtonGroup(widget)
        horizontal_vertical_group.addButton(self.animate_scale_radio)
        horizontal_vertical_group.addButton(self.animate_phase_radio)
        horizontal_vertical_group.addButton(self.animate_time_radio)
        horizontal_vertical_group.addButton(self.animate_freq_sweeep_radio)

        # animate in gui
        self.animate_in_gui_checkbox = QCheckBox("Animate In GUI?")
        self.animate_in_gui_checkbox.setChecked(True)

        # make images
        self.make_images_checkbox = QCheckBox("Make images?")
        self.make_images_checkbox.setChecked(True)

        # make images
        self.overwrite_images_checkbox = QCheckBox("Overwrite images?")
        self.overwrite_images_checkbox.setChecked(True)

        # delete images when finished
        self.delete_images_checkbox = QCheckBox("Delete images when finished?")
        self.delete_images_checkbox.setChecked(True)

        # endless loop
        self.repeat_checkbox = QCheckBox("Repeat?")
        self.repeat_checkbox.setChecked(True)
        self.repeat_checkbox.setToolTip(
            "Repeating creates an infinitely looping gif")

        # endless loop
        self.make_gif_checkbox = QCheckBox("Make Gif?")
        if IS_IMAGEIO:
            self.make_gif_checkbox.setChecked(True)
        else:
            self.make_gif_checkbox.setChecked(False)
            self.make_gif_checkbox.setEnabled(False)
            self.make_gif_checkbox.setToolTip(
                'imageio is not available; install it')

        # bottom buttons
        self.step_button = QPushButton("Step")
        self.wipe_button = QPushButton("Wipe Deformed Shape")
        self.stop_button = QPushButton("Stop")
        self.run_button = QPushButton("Run All")

        self.step_button.setToolTip(
            'Steps through the animation (for testing)')
        self.wipe_button.setToolTip(
            'Removes the existing "deflecton" from the animation')
        self.stop_button.setToolTip('Stops the animation')
        self.run_button.setToolTip('Creates the animation')

        self.wipe_button.setEnabled(False)
        #self.wipe_button.hide()
        self.stop_button.setEnabled(False)

        #self.apply_button = QPushButton("Apply")
        #self.ok_button = QPushButton("OK")
        self.cancel_button = QPushButton("Close")

        #self.set_grid_time(enabled=False)
        #self.set_grid_scale(enabled=self._default_is_scale)
        if self._default_phase:
            self.on_animate_phase(force=True)
        else:
            self.on_animate_scale(force=True)
예제 #23
0
    def _setupUi(self):
        # status
        label_status = QLabel('Status: ',
                              self,
                              alignment=Qt.AlignRight | Qt.AlignVCenter)
        channels2values = {
            self.device.substitute(propty='ForceComplete-Mon'): 1,
            self.device.substitute(propty='NegativeDoneMov-Mon'): 1,
            self.device.substitute(propty='PositiveDoneMov-Mon'): 1
        }
        self.multiled_status = PyDMLedMultiChannel(self, channels2values)
        self.multiled_status.setStyleSheet('max-width: 1.29em;')

        self.pb_details = QPushButton(qta.icon('fa5s.ellipsis-h'), '', self)
        self.pb_details.setToolTip('Open details')
        self.pb_details.setObjectName('detail')
        self.pb_details.setStyleSheet(
            "#detail{min-width:25px; max-width:25px; icon-size:20px;}")
        util.connect_window(self.pb_details,
                            _DiffCtrlDetails,
                            parent=self,
                            prefix=self.prefix,
                            device=self.device)

        self.lb_descCtrl1 = QLabel('',
                                   self,
                                   alignment=Qt.AlignRight | Qt.AlignVCenter)
        self.sb_Ctrl1 = PyDMSpinbox(self)
        self.sb_Ctrl1.showStepExponent = False
        self.lb_Ctrl1 = PyDMLabel(self)
        self.lb_descCtrl2 = QLabel('',
                                   self,
                                   alignment=Qt.AlignRight | Qt.AlignVCenter)
        self.sb_Ctrl2 = PyDMSpinbox(self)
        self.sb_Ctrl2.showStepExponent = False
        self.lb_Ctrl2 = PyDMLabel(self)

        self.pb_open = PyDMPushButton(
            parent=self,
            label='Open',
            pressValue=1,
            init_channel=self.device.substitute(propty='Home-Cmd'))

        tmp_file = _substitute_in_file(
            _os.path.abspath(_os.path.dirname(__file__)) + '/ui_as_ap_dev' +
            self.orientation.lower() + 'mon.ui', {'PREFIX': self.prefix})
        self.dev_widget = loadUi(tmp_file)
        self.dev_widget.setObjectName('dev')
        self.dev_widget_scrarea = QScrollArea()
        self.dev_widget_scrarea.setObjectName('scrarea')
        self.dev_widget_scrarea.setStyleSheet(
            '#scrarea{background-color: transparent; max-width: 15em;}'
            '#dev{background-color:transparent;}')
        self.dev_widget_scrarea.setWidget(self.dev_widget)

        lay = QGridLayout(self)
        lay.setAlignment(Qt.AlignTop)
        lay.addWidget(label_status, 0, 0)
        lay.addWidget(self.multiled_status, 0, 1)
        lay.addWidget(self.pb_details, 0, 2, alignment=Qt.AlignRight)
        lay.addWidget(self.lb_descCtrl1, 1, 0)
        lay.addWidget(self.sb_Ctrl1, 1, 1)
        lay.addWidget(self.lb_Ctrl1, 1, 2)
        lay.addWidget(self.lb_descCtrl2, 2, 0)
        lay.addWidget(self.sb_Ctrl2, 2, 1)
        lay.addWidget(self.lb_Ctrl2, 2, 2)
        lay.addWidget(self.pb_open, 3, 1, 1, 2)
        lay.addWidget(self.dev_widget_scrarea, 0, 3, 4, 1)
예제 #24
0
    def create_layout(self):
        """displays the menu objects"""
        grid = QGridLayout()

        grid.addWidget(self.icase_fringe, 0, 0)
        grid.addWidget(self.icase_fringe_edit, 0, 1)

        grid.addWidget(self.scale, 1, 0)
        grid.addWidget(self.scale_edit, 1, 1)
        grid.addWidget(self.scale_button, 1, 2)

        grid.addWidget(self.arrow_scale, 2, 0)
        grid.addWidget(self.arrow_scale_edit, 2, 1)
        grid.addWidget(self.arrow_scale_button, 2, 2)

        grid.addWidget(self.time, 3, 0)
        grid.addWidget(self.time_edit, 3, 1)
        grid.addWidget(self.time_button, 3, 2)

        # spacer
        spacer = QLabel('')

        grid.addWidget(self.fps, 4, 0)
        grid.addWidget(self.fps_edit, 4, 1)
        grid.addWidget(self.fps_button, 4, 2)

        grid.addWidget(self.resolution, 5, 0)
        grid.addWidget(self.resolution_edit, 5, 1)
        grid.addWidget(self.resolution_button, 5, 2)

        grid.addWidget(self.browse_folder, 6, 0)
        grid.addWidget(self.browse_folder_edit, 6, 1)
        grid.addWidget(self.browse_folder_button, 6, 2)

        grid.addWidget(self.gif, 7, 0)
        grid.addWidget(self.gif_edit, 7, 1)
        grid.addWidget(self.gif_button, 7, 2)

        grid.addWidget(self.animation_type, 8, 0)
        grid.addWidget(self.animation_type_edit, 8, 1)

        grid.addWidget(spacer, 9, 0)

        #----------
        #Time
        grid_time = QGridLayout()
        grid_time.addWidget(self.icase_start, 0, 0)
        grid_time.addWidget(self.icase_start_edit, 0, 1)
        #grid_time.addWidget(self.icase_start_button, 0, 2)

        grid_time.addWidget(self.icase_end, 1, 0)
        grid_time.addWidget(self.icase_end_edit, 1, 1)
        #grid_time.addWidget(self.icase_end_button, 1, 2)

        grid_time.addWidget(self.icase_delta, 2, 0)
        grid_time.addWidget(self.icase_delta_edit, 2, 1)
        #grid_time.addWidget(self.icase_delta_button, 2, 2)

        hbox = QHBoxLayout()
        hbox.addWidget(self.min_value_enable)
        hbox.addWidget(self.min_value)
        grid_time.addLayout(hbox, 3, 0)
        grid_time.addWidget(self.min_value_edit, 3, 1)
        grid_time.addWidget(self.min_value_button, 3, 2)

        hbox = QHBoxLayout()
        hbox.addWidget(self.max_value_enable)
        hbox.addWidget(self.max_value)
        grid_time.addLayout(hbox, 4, 0)
        grid_time.addWidget(self.max_value_edit, 4, 1)
        grid_time.addWidget(self.max_value_button, 4, 2)
        grid_time.addWidget(spacer, 5, 0)

        #--------------
        grid_scale = QGridLayout()
        grid_scale.addWidget(self.animation_profile, 0, 0)
        grid_scale.addWidget(self.animation_profile_edit, 0, 1)

        #grid_scale.addWidget(self.csv_profile, 1, 0)
        #grid_scale.addWidget(self.csv_profile_edit, 1, 1)
        #grid_scale.addWidget(self.csv_profile_browse_button, 1, 2)

        self.csv_profile = QLabel("CSV profile:")
        self.csv_profile_edit = QLineEdit()
        self.csv_profile_button = QPushButton('Browse')

        #box_time = QVBoxLayout()
        # TODO: It's super annoying that the animate time box doesn't
        #       line up with the previous box
        box_scale = QGroupBox('Animate Scale')
        box_scale.setLayout(grid_scale)

        box_time = QGroupBox('Animate Time')
        box_time.setLayout(grid_time)
        #----------

        grid2 = QGridLayout()
        #grid2.addWidget(self.animate_scale_radio, 8, 0)
        #grid2.addWidget(self.animate_phase_radio, 8, 1)
        #grid2.addWidget(self.animate_time_radio, 8, 2)
        #grid2.addWidget(self.animate_freq_sweeep_radio, 8, 3)

        grid2.addWidget(self.animate_in_gui_checkbox, 10, 0)
        grid2.addWidget(self.make_images_checkbox, 11, 0)
        #grid2.addWidget(self.overwrite_images_checkbox, 11, 0)
        grid2.addWidget(self.delete_images_checkbox, 11, 1)
        grid2.addWidget(self.make_gif_checkbox, 11, 2)
        grid2.addWidget(self.repeat_checkbox, 12, 0)

        grid2.addWidget(spacer, 13, 0)
        grid_hbox = QHBoxLayout()
        grid_hbox.addWidget(spacer)
        grid_hbox.addLayout(grid2)
        grid_hbox.addWidget(spacer)

        # bottom buttons
        step_run_box = QHBoxLayout()
        step_run_box.addWidget(self.step_button)
        step_run_box.addWidget(self.wipe_button)
        step_run_box.addWidget(self.stop_button)
        step_run_box.addWidget(self.run_button)

        ok_cancel_box = QHBoxLayout()
        ok_cancel_box.addWidget(self.cancel_button)

        vbox = QVBoxLayout()
        vbox.addLayout(grid)
        vbox.addWidget(box_scale)
        vbox.addWidget(box_time)
        #vbox.addLayout(checkboxes)
        vbox.addLayout(grid_hbox)
        vbox.addStretch()
        vbox.addLayout(step_run_box)
        vbox.addLayout(ok_cancel_box)
        self.setLayout(vbox)
예제 #25
0
    def __init__(self, type_, error='', title='', text='', learn_more=None):
        """Base message box dialog."""
        super(MessageBox, self).__init__()
        from anaconda_navigator.utils.analytics import GATracker

        self.tracker = GATracker()
        self.label_text = QLabel(to_text_string(text))
        self.textbox_error = QTextEdit()
        self.button_ok = ButtonPrimary('Ok')
        self.button_yes = ButtonPrimary('Yes')
        self.button_no = ButtonNormal('No')
        self.button_copy = ButtonNormal('Copy text')
        self.button_learn = ButtonNormal('Learn more')
        self.button_remove = ButtonDanger('Remove')
        self.button_cancel = ButtonNormal('Cancel')
        self.button_send = ButtonNormal('Report Issue', parent=self)

        self.label_text.setOpenExternalLinks(False)
        self.label_text.setWordWrap(True)
        self.label_text.linkActivated.connect(self.url_clicked)
        self.textbox_error.setReadOnly(True)
        self.textbox_error.setFrameStyle(QTextEdit.Plain)
        self.textbox_error.setFrameShape(QTextEdit.NoFrame)
        self.setMinimumWidth(260)
        self.textbox_error.verticalScrollBar().show()
        self.setWindowTitle(to_text_string(title))

        error = to_text_string(error).split('\n')
        error = '<br>'.join(error)
        self.textbox_error.setText(error)

        # Layouts
        layout = QVBoxLayout()
        layout.addWidget(self.label_text)
        layout.addWidget(SpacerVertical())
        if error:
            layout.addWidget(self.textbox_error)
            layout.addWidget(SpacerVertical())
            layout.addWidget(self.button_copy)
            layout.addWidget(SpacerVertical())
        layout.addWidget(SpacerVertical())

        layout_buttons = QHBoxLayout()
        layout_buttons.addStretch()

        layout.addLayout(layout_buttons)

        self.layout = layout
        self.setLayout(layout)

        # Signals
        self.button_copy.clicked.connect(self.copy_text)
        self.button_ok.clicked.connect(self.accept)
        self.button_yes.clicked.connect(self.accept)
        self.button_no.clicked.connect(self.reject)
        self.button_remove.clicked.connect(self.accept)
        self.button_cancel.clicked.connect(self.reject)
        self.button_send.clicked.connect(self.send)

        # Setup
        self.button_learn.setVisible(bool(learn_more))
        if bool(learn_more):
            layout_buttons.addWidget(self.button_learn)
            layout_buttons.addWidget(SpacerHorizontal())
            self.button_learn.clicked.connect(
                lambda: self.show_url(learn_more))

        if type_ == self.ERROR_BOX:
            layout_buttons.addWidget(self.button_send)
            layout_buttons.addWidget(SpacerHorizontal())
            layout_buttons.addWidget(self.button_ok)
            self.button_yes.setVisible(False)
            self.button_no.setVisible(False)
            self.button_remove.setVisible(False)
            self.button_cancel.setVisible(False)
        elif type_ == self.INFORMATION_BOX:
            layout_buttons.addWidget(self.button_ok)
            self.button_yes.setVisible(False)
            self.button_no.setVisible(False)
            self.textbox_error.setVisible(False)
            self.button_copy.setVisible(False)
            self.button_remove.setVisible(False)
            self.button_cancel.setVisible(False)
        elif type_ == self.QUESTION_BOX:
            layout_buttons.addStretch()
            layout_buttons.addWidget(self.button_no)
            layout_buttons.addWidget(SpacerHorizontal())
            layout_buttons.addWidget(self.button_yes)
            layout_buttons.addWidget(SpacerHorizontal())
            self.textbox_error.setVisible(False)
            self.button_ok.setVisible(False)
            self.button_copy.setVisible(False)
            self.button_remove.setVisible(False)
            self.button_cancel.setVisible(False)
        elif type_ == self.REMOVE_BOX:
            layout_buttons.addStretch()
            layout_buttons.addWidget(self.button_cancel)
            layout_buttons.addWidget(SpacerHorizontal())
            layout_buttons.addWidget(self.button_remove)
            layout_buttons.addWidget(SpacerHorizontal())
            self.textbox_error.setVisible(False)
            self.button_ok.setVisible(False)
            self.button_copy.setVisible(False)
            self.button_yes.setVisible(False)
            self.button_no.setVisible(False)

        self.button_send.setVisible(False)
        self.layout_buttons = layout_buttons
예제 #26
0
    def create_layout(self):
        grid = QGridLayout()
        self.method_label = QLabel('Method:')
        self.location_method_label = QLabel('Method:')

        self.location_label = QLabel('Location:')
        self.zaxis_method_label = QLabel('Z-Axis Method:')
        self.method_projected_label1 = QLabel('Projected')
        self.method_projected_label2 = QLabel('Projected')
        self.cid_label = QLabel('Coordinate System:')
        self.x_label = QLabel('X')
        self.y_label = QLabel('Y')
        self.z_label = QLabel('Z')

        self.location_label.setAlignment(Qt.AlignCenter)
        self.cid_label.setAlignment(Qt.AlignCenter)
        self.method_label.setAlignment(Qt.AlignCenter)
        self.location_method_label.setAlignment(Qt.AlignCenter)

        self.method_projected_label1.setAlignment(Qt.AlignCenter)
        self.method_projected_label2.setAlignment(Qt.AlignCenter)

        self.x_label.setAlignment(Qt.AlignCenter)
        self.y_label.setAlignment(Qt.AlignCenter)
        self.z_label.setAlignment(Qt.AlignCenter)
        irow = 0
        grid.addWidget(self.method_label, irow, 0)
        grid.addWidget(self.method_pulldown, irow, 1)
        irow += 1
        self._add_grid_layout(grid, irow, is_cord2r=True)

        #----------------------------------------------
        grid2 = QGridLayout()
        irow = 0
        grid2.addWidget(self.method_label, irow, 0)
        grid2.addWidget(self.method_pulldown, irow, 1)
        irow += 1
        self._add_grid_layout(grid2, irow, is_cord2r=False)

        self.export_checkbox = QCheckBox()
        self.csv_label = QLabel('CSV Filename:')
        self.csv_edit = QLineEdit()
        self.csv_button = QPushButton('Browse...')
        self.export_checkbox.clicked.connect(self.on_export_checkbox)
        self.csv_button.clicked.connect(self.on_browse_csv)
        self.csv_label.setEnabled(False)
        self.csv_edit.setEnabled(False)
        self.csv_button.setEnabled(False)

        hbox = QHBoxLayout()
        hbox.addWidget(self.export_checkbox)
        hbox.addWidget(self.csv_label)
        hbox.addWidget(self.csv_edit)
        hbox.addWidget(self.csv_button)
        #----------------------------------------------

        ok_cancel_box = QHBoxLayout()
        ok_cancel_box.addWidget(self.apply_button)
        ok_cancel_box.addWidget(self.ok_button)
        ok_cancel_box.addWidget(self.cancel_button)

        vbox = QVBoxLayout()

        #if 0:
        #button_frame = QFrame()
        ##button_frame.setFrameStyle(QFrame.Plain | QFrame.Box)
        #button_frame.setFrameStyle(QFrame.Box)
        #button_frame.setLayout(grid)
        #else:
        #button_frame = QGroupBox()
        #button_frame.setLayout(grid)
        #vbox.addWidget(button_frame)

        vbox.addLayout(grid)
        #vbox.addStretch()
        #vbox.addLayout(grid2)
        vbox.addLayout(hbox)
        vbox.addStretch()

        #-----------------------
        vbox.addLayout(ok_cancel_box)
        self.on_method(0)
        self.on_zaxis_method(0)
        self.setLayout(vbox)
    def _create_sweep_ui(self) -> List[FormRow]:
        """
        Populate the sweep widget with this workflow step's parameters and their default values as well as other
        UI elements needed to run a sweep.

         Params:
            none
        """
        rows: List[FormRow] = list()
        # add ui elements in order
        rows.append(FormRow("", widget=self.create_sweep_headers()))

        # convert parameter set to form rows
        default_params: Dict = self.controller.model.active_workflow.workflow_definition.steps[
            self.step_number].function.parameters
        if self.param_set:
            for key, value in self.param_set.items():
                # sometimes multiple unique params are in one list, need to separate out for UI
                if isinstance(value, list):
                    if not isinstance(value[0], str):
                        i = 1
                        for _ in value:
                            sweep_inputs: QFrame = QFrame()
                            sweep_inputs.setLayout(QHBoxLayout())
                            # get default value
                            min_value: int = default_params[key][i -
                                                                 1].min_value
                            max_value: int = default_params[key][i -
                                                                 1].max_value
                            step_size: float = (max_value - min_value) / 2

                            # Create UI Elements and populate with default values
                            min_input: QLineEdit = QLineEdit()
                            min_input.setText(str(min_value))
                            min_input.editingFinished.connect(
                                self._on_change_textbox)
                            sweep_inputs.layout().addWidget(min_input)

                            max_input: QLineEdit = QLineEdit()
                            max_input.setText(str(max_value))
                            max_input.editingFinished.connect(
                                self._on_change_textbox)
                            sweep_inputs.layout().addWidget(max_input)

                            step_input = QLineEdit()
                            step_input.setText(str(step_size))
                            step_input.editingFinished.connect(
                                self._on_change_textbox)
                            sweep_inputs.layout().addWidget(step_input)

                            # Reset button for row (reset to default values)
                            reset_button: QPushButton = QPushButton("reset")
                            reset_button.setStyleSheet("border: none;")
                            # pass the key and value as values for calling function later on
                            reset_button.clicked.connect(
                                partial(
                                    lambda k, val: self._reset_row_to_default(
                                        k, val), key, i))
                            sweep_inputs.layout().addWidget(reset_button)

                            # store the index of this parameter in its list appended to the parameter key
                            self.inputs[key + str(i)] = sweep_inputs
                            rows.append(
                                FormRow(f"{key} {i}", widget=sweep_inputs))
                            i = i + 1
                else:
                    # most params are single entries in the param dictionary
                    # for params that are a dropdown
                    if default_params[key][0].widget_type.name == "DROPDOWN":
                        dropdown = QComboBox()
                        dropdown.setStyleSheet(
                            "QComboBox { combobox-popup: 0; }")
                        dropdown.addItems(default_params[key][0].options)
                        self.inputs[key] = dropdown
                        rows.append(FormRow(key, widget=dropdown))
                    else:
                        # for typical sweep params
                        sweep_inputs: QFrame = QFrame()
                        sweep_inputs.setLayout(QHBoxLayout())
                        # get the default values
                        min_value: int = default_params[key][0].min_value
                        max_value: int = default_params[key][0].max_value
                        step_size: float = (max_value - min_value) / 2

                        # Create UI elements and populate with default values
                        min_input: QLineEdit = QLineEdit()
                        min_input.setText(str(min_value))
                        min_input.editingFinished.connect(
                            self._on_change_textbox)
                        sweep_inputs.layout().addWidget(min_input)

                        max_input: QLineEdit = QLineEdit()
                        max_input.setText(str(max_value))
                        max_input.editingFinished.connect(
                            self._on_change_textbox)
                        sweep_inputs.layout().addWidget(max_input)

                        step_input: QLineEdit = QLineEdit()
                        step_input.setText(str(step_size))
                        step_input.editingFinished.connect(
                            self._on_change_textbox)
                        sweep_inputs.layout().addWidget(step_input)
                        self.inputs[key] = sweep_inputs

                        # Create button to reset back to default values
                        reset_button: QPushButton = QPushButton("reset")
                        reset_button.setStyleSheet("border: none;")
                        reset_button.clicked.connect(
                            lambda: self._reset_row_to_default(key))
                        sweep_inputs.layout().addWidget(reset_button)
                        rows.append(FormRow(key, widget=sweep_inputs))

        # Grab user input as str
        def_params_values: List[List[str]] = self.grab_ui_values(
            grab_combo=False)

        # Display how many images will be create with this sweep
        def_count: int = self.get_live_count(def_params_values)
        self.live_count = QLabel(f"{def_count} images will be created")
        self.live_count.setAlignment(qtpy.QtCore.Qt.AlignCenter)

        # Create progress bar with length of sweep
        self.create_progress_bar(bar_len=def_count)

        rows.append(FormRow("", widget=self.live_count))
        rows.append(FormRow("", widget=self.progress_bar))
        rows.append(FormRow("", widget=self._create_buttons()))
        return rows
예제 #28
0
    def create_widgets(self, show_tol):
        """creates the display window"""
        # CORD2R
        #self.origin_label = QLabel("Origin:")
        #self.zaxis_label = QLabel("Z Axis:")
        #self.xz_plane_label = QLabel("XZ Plane:")

        # Z-Axis Projection
        self.p1_label = QLabel("Origin/P1:")
        self.p2_label = QLabel("P2:")
        self.zaxis_label = QLabel("Z Axis:")

        self.method_pulldown = QComboBox()
        for method in self.methods:
            self.method_pulldown.addItem(method)

        self.zaxis_method_pulldown = QComboBox()
        for method in self.zaxis_methods:
            self.zaxis_method_pulldown.addItem(method)

        self.cid_label = QLabel("Coordinate System:")
        self.p1_cid_pulldown = QComboBox()
        self.p2_cid_pulldown = QComboBox()
        self.zaxis_cid_pulldown = QComboBox()

        cid_global_str = '0/Global'
        for cid in sorted(self.cids):
            if cid == 0:
                cid_str = cid_global_str
            else:
                cid_str = str(cid)
            #print('cid_str = %r' % cid_str)
            self.p1_cid_pulldown.addItem(cid_str)
            self.p2_cid_pulldown.addItem(cid_str)
            self.zaxis_cid_pulldown.addItem(cid_str)

        self.p1_cid_pulldown.setCurrentIndex(0)
        self.p2_cid_pulldown.setCurrentIndex(0)
        self.zaxis_cid_pulldown.setCurrentIndex(0)
        if len(self.cids) == 1:
            self.p1_cid_pulldown.setEnabled(False)
            self.p2_cid_pulldown.setEnabled(False)
            self.zaxis_cid_pulldown.setEnabled(False)

        #self.p1_cid_pulldown.setItemText(0, cid_str)
        #self.p2_cid_pulldown.setItemText(0, cid_str)
        #self.zaxis_cid_pulldown.setItemText(0, cid_str)

        self.p1_cid_pulldown.setToolTip(
            'Defines the coordinate system for the Point P1')
        self.p2_cid_pulldown.setToolTip(
            'Defines the coordinate system for the Point P2')
        self.zaxis_cid_pulldown.setToolTip(
            'Defines the coordinate system for the Z Axis')

        self.p1_x_edit = QLineEdit('')
        self.p1_y_edit = QLineEdit('')
        self.p1_z_edit = QLineEdit('')

        self.p2_x_edit = QLineEdit('')
        self.p2_y_edit = QLineEdit('')
        self.p2_z_edit = QLineEdit('')

        self.zaxis_x_edit = QLineEdit('')
        self.zaxis_y_edit = QLineEdit('')
        self.zaxis_z_edit = QLineEdit('')

        self.ytol_label = QLabel('Y Tolerance:')
        self.zero_tol_label = QLabel('Zero Tolerance:')

        self.ytol_edit = QLineEdit('10.0')
        self.zero_tol_edit = QLineEdit('1e-5')

        if not show_tol:
            self.ytol_label.setVisible(False)
            self.zero_tol_label.setVisible(False)
            self.ytol_edit.setVisible(False)
            self.zero_tol_edit.setVisible(False)

        self.p2_label = QLabel("P2:")

        # Plane Color
        self.plane_color_label = QLabel("Plane Color:")
        self.plane_color_edit = QPushButtonColor(self.plane_color_int)

        self.corner_coord_label = QLabel("Show Corner Coordinate System:")
        self.corner_coord_checkbox = QCheckBox()
        #self.corner_coord_checkbox.setChecked(self._show_corner_coord)

        #-----------------------------------------------------------------------
        # closing
        self.apply_button = QPushButton("Apply")
        self.ok_button = QPushButton("OK")
        self.cancel_button = QPushButton("Cancel")
예제 #29
0
def get_image_label(name, default="not_found.png"):
    """Return image inside a QLabel object"""
    label = QLabel()
    label.setPixmap(QPixmap(get_image_path(name, default)))
    return label
예제 #30
0
    def __init__(self, parent):
        super(AppUpdateDialog, self).__init__()

        self.parent = parent
        self.setWindowTitle(config.thisTranslation["App_Updater"])
        self.layout = QVBoxLayout()

        self.latestVersion = UpdateUtil.getLatestVersion()
        self.currentVersion = UpdateUtil.getCurrentVersion()

        if not config.internet:
            error = QLabel(
                config.thisTranslation["Could_not_connect_to_internet"])
            error.setStyleSheet("color: rgb(253, 128, 8);")
            self.layout.addWidget(error)
        else:
            if UpdateUtil.currentIsLatest(self.currentVersion,
                                          self.latestVersion):
                self.uptodate = True
            else:
                self.uptodate = False

            if not self.uptodate:
                self.layout.addWidget(
                    QLabel("{0}: {1}".format(
                        config.thisTranslation["Latest_version"],
                        self.latestVersion)))
            self.layout.addWidget(
                QLabel("{0}: {1}".format(
                    config.thisTranslation["Current_version"],
                    self.currentVersion)))

            self.updateNowButton = QPushButton(
                config.thisTranslation["Update_now"])
            self.updateNowButton.setEnabled(True)
            self.updateNowButton.clicked.connect(self.updateNow)
            if self.uptodate:
                ubaUptodate = QLabel(config.thisTranslation["UBA_is_uptodate"])
                if config.theme in ("dark", "night"):
                    ubaUptodate.setStyleSheet("color: green;")
                else:
                    ubaUptodate.setStyleSheet("color: blue;")
                self.layout.addWidget(ubaUptodate)
            else:
                self.layout.addWidget(self.updateNowButton)

        self.layout.addWidget(
            QLabel("{0}: {1}".format(
                config.thisTranslation["Last_check"],
                DateUtil.formattedLocalDate(
                    UpdateUtil.lastAppUpdateCheckDateObject()))))
        self.layout.addWidget(
            QLabel("{0}: {1}".format(
                config.thisTranslation["Next_check"],
                DateUtil.formattedLocalDate(
                    DateUtil.addDays(
                        UpdateUtil.lastAppUpdateCheckDateObject(),
                        int(config.daysElapseForNextAppUpdateCheck))))))

        row = QHBoxLayout()
        row.addWidget(
            QLabel("{0}:".format(
                config.thisTranslation["Days_between_checks"])))
        self.daysInput = QLineEdit()
        self.daysInput.setText(str(config.daysElapseForNextAppUpdateCheck))
        self.daysInput.setMaxLength(3)
        self.daysInput.setMaximumWidth(60)
        row.addWidget(self.daysInput)
        self.layout.addLayout(row)

        buttons = QDialogButtonBox.Ok
        self.buttonBox = QDialogButtonBox(buttons)
        self.buttonBox.accepted.connect(self.setDaysElapse)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)
        self.layout.addWidget(self.buttonBox)
        self.setLayout(self.layout)

        if config.internet:
            self.updateNowButton.setFocus()

            if self.uptodate:
                self.daysInput.setFocus()
            else:
                # self.setTabOrder(self.updateNowButton, self.daysInput)
                # self.setTabOrder(self.daysInput, self.updateNowButton)
                self.updateNowButton.setFocus()