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()
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
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()
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)
def addLabel(x): label = QLabel("A", toolbar) toolbar.addWidget(label)
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)
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()
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()
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
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)
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)
@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()
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)
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)
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)
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)
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
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)
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)
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")
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()
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)
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)
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)
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
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
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")
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
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()