def createCheckBox(self, variable_name, variable_value, variable_type): spinner = QCheckBox() spinner.setChecked(variable_value) spinner.clicked.connect( partial(self.valueChanged, variable_name, variable_type, spinner) ) return spinner
def show_ext_filter_selection_dialog(self): self.dlg = QDialog(self) self.dlg.setWindowTitle(self.tr('Extension Name To Show')) self.dlg.setLayout(QVBoxLayout()) self.dlg.layout().addWidget(QLabel('过滤文件名')) check_box = QCheckBox() self.dlg.check_box = check_box check_box.setChecked(self.filter_exts) self.dlg.layout().addWidget(check_box) check_box.stateChanged.connect( lambda stat: self.signal_ext_filter_adapt.emit(stat)) check_widget = PMCheckTree(data=self.exts_to_filter) self.dlg.check_widget = check_widget self.dlg.layout().addWidget(check_widget) buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) buttonBox.accepted.connect(self.on_ext_filter_changed) buttonBox.rejected.connect(self.dlg.deleteLater) # 清除选择功能不完善目前禁用 # button_clear = buttonBox.addButton(self.tr('Clear Filter'), QDialogButtonBox.ApplyRole) # button_clear.clicked.connect(self.clear_ext_filter) self.dlg.layout().addWidget(buttonBox) self.dlg.exec_()
def _get_actor_widget(actor: vtkActor) -> QWidget: widget = QWidget() layout = QVBoxLayout() prop = actor.GetProperty() # visibility visibility = QCheckBox("Visibility") visibility.setChecked(actor.GetVisibility()) visibility.toggled.connect(actor.SetVisibility) layout.addWidget(visibility) if prop is not None: # opacity tmp_layout = QHBoxLayout() opacity = QDoubleSpinBox() opacity.setMaximum(1.0) opacity.setValue(prop.GetOpacity()) opacity.valueChanged.connect(prop.SetOpacity) tmp_layout.addWidget(QLabel("Opacity")) tmp_layout.addWidget(opacity) layout.addLayout(tmp_layout) widget.setLayout(layout) return widget
class TermsFrame(ConfigBaseFrame): def __init__(self, parent=None): super(TermsFrame, self).__init__(parent) self.setObjectName("botnet_termsframe_start") self.disable_next_on_enter = True self.widget_layout = QVBoxLayout(self) self.setLayout(self.widget_layout) self.terms = QTextEdit(self) self.terms.setReadOnly(True) self.terms.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.terms.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.terms.setLineWrapMode(QTextEdit.WidgetWidth) self.terms.setWordWrapMode(QTextOption.WrapAnywhere) with open(os.path.join(sys.path[0], "../LICENSE")) as f: self.terms.setText(f.read()) self.widget_layout.addWidget(self.terms) self.accept = QCheckBox(self) self.accept.setChecked(False) self.accept.setText("Accept license") self.accept.setObjectName("license_checkbox") self.widget_layout.addWidget(self.accept) QMetaObject.connectSlotsByName(self) @Slot(bool) def on_license_checkbox_clicked(self, checked): self.set_next_enabled.emit(checked) self.disable_next_on_enter = not checked @Slot() def collect_info(self): return {"terms_accepted": self.accept.isChecked()}
class FolderBrowserDockWidget(QDockWidget): def __init__(self, parent, ide, path): super(FolderBrowserDockWidget, self).__init__(parent) self.main_window = parent self._ide = ide self.path = path self._gitignore_checkbox = QCheckBox(_('Use .gitignore')) self._gitignore_checkbox.setChecked(True) self._folder_browser = FolderBrowser(parent, ide, path, self) self._container_layout = QVBoxLayout() self._container_widget = QWidget(self) self._container_layout.setContentsMargins(6, 6, 6, 6) self._container_layout.addWidget(self._folder_browser) self._container_layout.addWidget(self._gitignore_checkbox) self._container_widget.setLayout(self._container_layout) self.setWidget(self._container_widget) self.setWindowTitle(os.path.basename(path)) self.setObjectName(os.path.basename(path)) def select_path(self, path): self._folder_browser.select_path(path) def closeEvent(self, e): self._folder_browser.shutdown() self._ide.remove_folder_browser_dock_widget(self) self.close() @property def file_list(self): return self._folder_browser.file_list
class ParamCheckBox(ParamWidget): """ QCheckBox for operator control of boolean values. Parameters ---------- parameter : str Name of parameter this widget controls. default : bool, optional Default state of the box. parent : QWidget, optional """ def __init__(self, parameter, default=inspect._empty, parent=None): super().__init__(parameter, default=default, parent=parent) self.param_control = QCheckBox(parent=self) self.layout().addWidget(self.param_control) # Configure default QCheckBox position if default != inspect._empty: self.param_control.setChecked(default) def get_param_value(self): """ Return the checked state of the QCheckBox. """ return self.param_control.isChecked()
def add_level_to_table(self, level): row_count = self.levelsTable.rowCount() self.levelsTable.setRowCount(row_count + 1) checkbox_widget = QWidget(self.levelsTable) checkbox_widget.setStyleSheet("QWidget { background-color:none;}") checkbox = QCheckBox() checkbox.setStyleSheet( "QCheckBox::indicator { width: 15px; height: 15px;}") checkbox.setChecked(level.enabled) checkbox.clicked.connect(level.set_enabled) checkbox.clicked.connect(self.level_show_changed) checkbox.toggled.connect(level.set_enabled) checkbox_layout = QHBoxLayout() checkbox_layout.setAlignment(Qt.AlignCenter) checkbox_layout.setContentsMargins(0, 0, 0, 0) checkbox_layout.addWidget(checkbox) checkbox_widget.setLayout(checkbox_layout) self.levelsTable.setCellWidget(row_count, 0, checkbox_widget) self.levelsTable.setItem(row_count, 1, QTableWidgetItem(level.levelname)) self.levelsTable.resizeColumnToContents(1)
def __clean_and_load_bookings__(self, working_date: str=None): """ Cleans booking table when switch working day. :param working_date: :return: """ row = 0 t: QTableWidget = self.ui.table_bookings clean_table(t) bookings = list() if working_date is not None: bookings = self.time_capture_service.load_bookings(working_date) else: bookings = self.__convert_entities_to_bookings__() for b in bookings: t.insertRow(row) qcb = QCheckBox(self.ui.table_bookings) qcb.setChecked(b[bk.BOOKED]) t.setCellWidget(row, B_BOOKED, qcb) qcb = QCheckBox(self.ui.table_bookings) qcb.setChecked(b[bk.LOGGED]) t.setCellWidget(row, B_LOGGED, qcb) qdsb = QDoubleSpinBox(self.ui.table_bookings) qdsb.setValue(b[bk.HOURS]) t.setCellWidget(row, B_HOURS, qdsb) t.setItem(row, B_ORDER, QTableWidgetItem(b[bk.ORDER])) t.setItem(row, B_COMMENT, QTableWidgetItem(b[bk.COMMENT])) t.resizeRowsToContents() row += 1
def add_kicklimits_curves(self): grpbx = QGroupBox('Show Kick Limits', self) vbl = QHBoxLayout(grpbx) self.hbl_namev.addWidget(grpbx) chcbox1 = QCheckBox('Kicks', grpbx) chcbox2 = QCheckBox('Delta Kicks', grpbx) chcbox1.setChecked(True) chcbox2.setChecked(True) vbl.addWidget(chcbox1) vbl.addWidget(chcbox2) chcboxs = (chcbox1, chcbox2) names = ('Max Kicks', 'Max dKickx') pvs = ('MaxKick', 'MaxDeltaKick') stys = (4, 2) wids = (3, 2) plns = ('x', 'y') corrs = ('CH', 'CV') for chb, name, pvi, sty, wid in zip(chcboxs, names, pvs, stys, wids): pen = mkPen(QColor(0, 0, 0)) pen.setStyle(sty) pen.setWidth(wid) for pln, corr in zip(plns, corrs): maxkick = InfLine( conv=1e-6, pos=0.0, pen=pen, angle=0, name=name) minkick = InfLine(conv=-1e-6, pos=0.0, pen=pen, angle=0) self.graph[pln].addItem(maxkick) self.graph[pln].addItem(minkick) chan = _ConnSig( self.devpref.substitute(propty=pvi + corr + '-RB')) self._chans.append(chan) chan.new_value_signal[float].connect(maxkick.setValue) chan.new_value_signal[float].connect(minkick.setValue) chb.toggled.connect(maxkick.setVisible) chb.toggled.connect(minkick.setVisible)
class ResultImageView(ImageView): """ :type _settings PartSettings: """ def __init__(self, settings: PartSettings, channel_property: ChannelProperty, name: str): super().__init__(settings, channel_property, name) self._channel_control_top = True self.only_border = QCheckBox("") self.image_state.only_borders = False self.only_border.setChecked(self.image_state.only_borders) self.only_border.stateChanged.connect(self.image_state.set_borders) self.opacity = QDoubleSpinBox() self.opacity.setRange(0, 1) self.opacity.setValue(self.image_state.opacity) self.opacity.setSingleStep(0.1) self.opacity.valueChanged.connect(self.image_state.set_opacity) self.opacity.setMinimumWidth(500) self.label1 = QLabel("Borders:") self.label2 = QLabel("Opacity:") self.btn_layout.insertWidget(3, self.label1) self.btn_layout.insertWidget(4, self.only_border) self.btn_layout.insertWidget(5, self.label2) self.btn_layout.insertWidget(6, self.opacity) self.label1.setVisible(False) self.label2.setVisible(False) self.opacity.setVisible(False) self.only_border.setVisible(False) def any_segmentation(self): for image_info in self.image_info.values(): if image_info.segmentation is not None: return True return False @Slot() @Slot(SegmentationInfo) def set_segmentation(self, segmentation_info: Optional[SegmentationInfo] = None, image: Optional[Image] = None) -> None: super().set_segmentation(segmentation_info, image) show = self.any_segmentation() self.label1.setVisible(show) self.label2.setVisible(show) self.opacity.setVisible(show) self.only_border.setVisible(show) def resizeEvent(self, event: QResizeEvent): if event.size().width() > 700 and not self._channel_control_top: w = self.btn_layout2.takeAt(0).widget() self.btn_layout.takeAt(2) # noinspection PyArgumentList self.btn_layout.insertWidget(2, w) self._channel_control_top = True elif event.size().width() <= 700 and self._channel_control_top: w = self.btn_layout.takeAt(2).widget() self.btn_layout.insertStretch(2, 1) # noinspection PyArgumentList self.btn_layout2.insertWidget(0, w) self._channel_control_top = False
def setup_and_check(self, data, title=''): """ Setup DataFrameEditor: return False if data is not supported, True otherwise """ self.layout = QGridLayout() self.setLayout(self.layout) self.setWindowIcon(ima.icon('arredit')) if title: title = to_text_string(title) + " - %s" % data.__class__.__name__ else: title = _("%s editor") % data.__class__.__name__ if isinstance(data, Series): self.is_series = True data = data.to_frame() self.setWindowTitle(title) self.resize(600, 500) self.dataModel = DataFrameModel(data, parent=self) self.dataTable = DataFrameView(self, self.dataModel) self.layout.addWidget(self.dataTable) self.setLayout(self.layout) self.setMinimumSize(400, 300) # Make the dialog act as a window self.setWindowFlags(Qt.Window) btn_layout = QHBoxLayout() btn = QPushButton(_("Format")) # disable format button for int type btn_layout.addWidget(btn) btn.clicked.connect(self.change_format) btn = QPushButton(_('Resize')) btn_layout.addWidget(btn) btn.clicked.connect(self.resize_to_contents) bgcolor = QCheckBox(_('Background color')) bgcolor.setChecked(self.dataModel.bgcolor_enabled) bgcolor.setEnabled(self.dataModel.bgcolor_enabled) bgcolor.stateChanged.connect(self.change_bgcolor_enable) btn_layout.addWidget(bgcolor) self.bgcolor_global = QCheckBox(_('Column min/max')) self.bgcolor_global.setChecked(self.dataModel.colum_avg_enabled) self.bgcolor_global.setEnabled(not self.is_series and self.dataModel.bgcolor_enabled) self.bgcolor_global.stateChanged.connect(self.dataModel.colum_avg) btn_layout.addWidget(self.bgcolor_global) btn_layout.addStretch() bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) bbox.accepted.connect(self.accept) bbox.rejected.connect(self.reject) btn_layout.addWidget(bbox) self.layout.addLayout(btn_layout, 2, 0) return True
def autoCloseCheckBox(self): checkbox = QCheckBox() checkbox.setText(config.thisTranslation["autoClose"]) checkbox.setToolTip(config.thisTranslation["autoCloseToolTip"]) checkbox.setChecked(config.closeControlPanelAfterRunningCommand) checkbox.stateChanged.connect( self.closeControlPanelAfterRunningCommandChanged) return checkbox
def __init__(self, theme='dark', emphasized=False): super().__init__(None) self.setProperty('emphasized', emphasized) self.setStyleSheet(template(raw_stylesheet, **palettes[theme])) lay = QVBoxLayout() self.setLayout(lay) lay.addWidget(QPushButton('push button')) box = QComboBox() box.addItems(['a', 'b', 'c', 'cd']) lay.addWidget(box) lay.addWidget(QFontComboBox()) hbox = QHBoxLayout() chk = QCheckBox('tristate') chk.setToolTip('I am a tooltip') chk.setTristate(True) chk.setCheckState(Qt.PartiallyChecked) chk3 = QCheckBox('checked') chk3.setChecked(True) hbox.addWidget(QCheckBox('unchecked')) hbox.addWidget(chk) hbox.addWidget(chk3) lay.addLayout(hbox) lay.addWidget(TabDemo(emphasized=emphasized)) sld = QSlider(Qt.Horizontal) sld.setValue(50) lay.addWidget(sld) scroll = QScrollBar(Qt.Horizontal) scroll.setValue(50) lay.addWidget(scroll) lay.addWidget(QHRangeSlider(parent=self)) text = QTextEdit() text.setMaximumHeight(100) text.setHtml(blurb) lay.addWidget(text) lay.addWidget(QTimeEdit()) edit = QLineEdit() edit.setPlaceholderText('LineEdit placeholder...') lay.addWidget(edit) lay.addWidget(QLabel('label')) prog = QProgressBar() prog.setValue(50) lay.addWidget(prog) groupBox = QGroupBox("Exclusive Radio Buttons") radio1 = QRadioButton("&Radio button 1") radio2 = QRadioButton("R&adio button 2") radio3 = QRadioButton("Ra&dio button 3") radio1.setChecked(True) hbox = QHBoxLayout() hbox.addWidget(radio1) hbox.addWidget(radio2) hbox.addWidget(radio3) hbox.addStretch(1) groupBox.setLayout(hbox) lay.addWidget(groupBox)
def add_buttons_to_layout(self, layout): """Add tool buttons to layout""" # Show crop rectangle checkbox show_crop = QCheckBox(_("Show cropping rectangle"), self) show_crop.setChecked(True) show_crop.toggled.connect(self.show_crop_rect) layout.addWidget(show_crop) layout.addSpacing(15) base.BaseTransformMixin.add_buttons_to_layout(self, layout)
def _add_channel(self, name): cdta = self.graph.curveAtIndex(-1) cbx = QCheckBox(name, self) plt = cbx.palette() plt.setColor(plt.WindowText, cdta.color) cbx.setPalette(plt) cbx.setChecked(True) self.vbl.addWidget(cbx) self.vbl.addStretch() cbx.toggled.connect(cdta.setVisible)
def __init__(self, layer): super().__init__() self.layer = layer self.layer.events.select.connect(self._on_select_change) self.layer.events.deselect.connect(self._on_deselect_change) self.layer.events.name.connect(self._on_name_change) self.layer.events.visible.connect(self._on_visible_change) self.layer.events.thumbnail.connect(self._on_thumbnail_change) self.setAttribute(Qt.WA_DeleteOnClose) self.setObjectName('layer') self.layout = QHBoxLayout() self.layout.setContentsMargins(0, 0, 0, 0) self.setLayout(self.layout) tb = QLabel(self) tb.setObjectName('thumbnail') tb.setToolTip(trans._('Layer thumbnail')) self.thumbnailLabel = tb self._on_thumbnail_change() self.layout.addWidget(tb) cb = QCheckBox(self) cb.setObjectName('visibility') cb.setToolTip(trans._('Layer visibility')) cb.setChecked(self.layer.visible) cb.setProperty('mode', 'visibility') cb.stateChanged.connect(self.changeVisible) self.visibleCheckBox = cb self.layout.addWidget(cb) textbox = QLineEdit(self) textbox.setText(layer.name) textbox.home(False) textbox.setToolTip(self.layer.name) textbox.setAcceptDrops(False) textbox.setEnabled(True) textbox.editingFinished.connect(self.changeText) self.nameTextBox = textbox self.layout.addWidget(textbox) ltb = QLabel(self) layer_type = type(layer).__name__ ltb.setObjectName(layer_type) ltb.setProperty('layer_type_label', True) ltb.setToolTip(trans._('Layer type')) self.typeLabel = ltb self.layout.addWidget(ltb) msg = trans._('Click to select\nDrag to rearrange') self.setToolTip(msg) self.setSelected(self.layer.selected)
class InterpolateBadsDialog(QDialog): def __init__(self, parent): super().__init__(parent) self.setWindowTitle("Interpolate bad channels") vbox = QVBoxLayout(self) grid = QGridLayout() grid.addWidget(QLabel("Reset bads:"), 0, 0) self.reset_bads_checkbox = QCheckBox() self.reset_bads_checkbox.setChecked(True) grid.addWidget(self.reset_bads_checkbox, 0, 1) grid.addWidget(QLabel("Mode:"), 1, 0) self.mode_select = QComboBox() self.modes = {"Accurate": "accurate", "Fast": "fast"} self.mode_select.addItems(self.modes.keys()) self.mode_select.setCurrentText("Accurate") grid.addWidget(self.mode_select, 1, 1) grid.addWidget(QLabel("Origin (x, y, z):"), 2, 0) hbox = QHBoxLayout() self.x = QDoubleSpinBox() self.x.setValue(0) self.x.setDecimals(3) hbox.addWidget(self.x) self.y = QDoubleSpinBox() self.y.setValue(0) self.y.setDecimals(3) hbox.addWidget(self.y) self.z = QDoubleSpinBox() self.z.setValue(0.04) self.z.setDecimals(3) hbox.addWidget(self.z) grid.addLayout(hbox, 2, 1) vbox.addLayout(grid) buttonbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) vbox.addWidget(buttonbox) buttonbox.accepted.connect(self.accept) buttonbox.rejected.connect(self.reject) vbox.setSizeConstraint(QVBoxLayout.SetFixedSize) @property def origin(self): x = float(self.x.value()) y = float(self.y.value()) z = float(self.z.value()) return x, y, z @property def mode(self): return self.mode_select.currentText() @property def reset_bads(self): return self.reset_bads_checkbox.isChecked()
class QtTestImageLayout(QVBoxLayout): """Controls to a create a new test image layer. Parameters ---------- on_create : Callable[[], None] Called when the create test image button is pressed. """ def __init__(self, on_create: Callback): super().__init__() self.addStretch(1) # Dimension controls. self.width = QtLabeledSpinBox("Image Width", IMAGE_SIZE_DEFAULT[0], IMAGE_SIZE_RANGE) self.height = QtLabeledSpinBox("Image Height", IMAGE_SIZE_DEFAULT[1], IMAGE_SIZE_RANGE) self.addLayout(self.width) self.addLayout(self.height) self.tile_size = QtLabeledSpinBox("Tile Size", TILE_SIZE_DEFAULT, TILE_SIZE_RANGE) self.addLayout(self.tile_size) # Checkbox so we can choose between OctreeImage and regular Image. self.octree = QCheckBox("Octree Image") self.octree.setChecked(1) self.addWidget(self.octree) # The create button. button = QPushButton("Create Test Image") button.setToolTip("Create a new test image") button.clicked.connect(on_create) self.addWidget(button) def get_image_size(self) -> Tuple[int, int]: """Return the configured image size. Return ------ Tuple[int, int] The [width, height] requested by the user. """ return (self.width.spin.value(), self.height.spin.value()) def get_tile_size(self) -> int: """Return the configured tile size. Return ------ int The requested tile size. """ return self.tile_size.spin.value()
def refresh_measurements(self): selected = self._clean_measurements() for val in MEASUREMENT_DICT.values(): area = val.get_starting_leaf().area pc = val.get_starting_leaf().per_component if (val.get_fields() or (area is not None and area != AreaType.ROI) or (pc is not None and pc != PerComponent.Yes)): continue text = val.get_name() chk = QCheckBox(text) if text in selected: chk.setChecked(True) self.measurement_layout.addWidget(chk)
def addFilterItem(self, name, id, value=True): self.filter_items[id] = value check_box = QCheckBox(name) check_box.setChecked(value) def toggleItem(checked): self.filter_items[id] = checked self.filterSettingsChanged.emit(self.filter_items) check_box.toggled.connect(toggleItem) self.__layout.addWidget(check_box)
def _dock_add_check_box(self, name, value, callback, *, tooltip=None, layout=None): layout = self._dock_layout if layout is None else layout widget = QCheckBox(name) _set_widget_tooltip(widget, tooltip) widget.setChecked(value) widget.stateChanged.connect(callback) self._layout_add_widget(layout, widget) return _QtWidget(widget)
class QuitApplicationDialog(DialogBase): """ """ def __init__(self, *args, **kwargs): super(QuitApplicationDialog, self).__init__(*args, **kwargs) self.label_icon = QLabel() self.label_about = QLabel('Quit Anaconda Navigator?') self.button_ok = QPushButton('Yes') self.button_cancel = ButtonCancel('No') self.buttonbox = QDialogButtonBox(Qt.Horizontal) self.checkbox = QCheckBox("Don't show again") # Widget setup if CONF.get('main', 'hide_quit_dialog'): hide_dialog = Qt.Checked else: hide_dialog = Qt.Unchecked self.checkbox.setChecked(hide_dialog) self.buttonbox.addButton(self.button_ok, QDialogButtonBox.ActionRole) self.buttonbox.addButton(self.button_cancel, QDialogButtonBox.ActionRole) self.label_icon.setPixmap(QPixmap(images.ANACONDA_ICON_64_PATH)) self.setWindowTitle("Quit application") # Layouts h_layout = QHBoxLayout() h_layout.addWidget(self.label_icon, 0, Qt.AlignTop) h_layout.addSpacing(10) h_layout.addWidget(self.label_about) main_layout = QVBoxLayout() main_layout.addLayout(h_layout) main_layout.addWidget(self.checkbox, 0, Qt.AlignRight) main_layout.addSpacing(24) main_layout.addWidget(self.buttonbox) self.setLayout(main_layout) # Signals self.button_ok.clicked.connect(self.accept) self.button_cancel.clicked.connect(self.reject) # Setup self.update_style_sheet() def accept(self): hide_dialog = self.checkbox.checkState() == Qt.Checked CONF.set('main', 'hide_quit_dialog', hide_dialog) super(QuitApplicationDialog, self).accept()
def get_level_show_checkbox(self, level): checkbox_widget = QWidget(self.table) checkbox_widget.setStyleSheet("QWidget { background-color:none;}") checkbox = QCheckBox() checkbox.setStyleSheet( "QCheckBox::indicator { width: 15px; height: 15px;}") checkbox.setChecked(level.enabled) checkbox_layout = QHBoxLayout() checkbox_layout.setAlignment(Qt.AlignCenter) checkbox_layout.setContentsMargins(0, 0, 0, 0) checkbox_layout.addWidget(checkbox) checkbox_widget.setLayout(checkbox_layout) return checkbox_widget
def __init__(self, parent, data, readonly=False, xlabels=None, ylabels=None): QWidget.__init__(self, parent) self.data = data print(type(self.data)) self.old_data_shape = None if len(self.data.shape) == 1: self.old_data_shape = self.data.shape self.data.shape = (self.data.shape[0], 1) elif len(self.data.shape) == 0: self.old_data_shape = self.data.shape self.data.shape = (1, 1) format = SUPPORTED_FORMATS.get(data.dtype.name, '%s') self.model = ArrayModel(self.data, format=format, xlabels=xlabels, ylabels=ylabels, readonly=readonly, parent=self) self.view = ArrayView(self, self.model, data.dtype, data.shape) btn_layout = QHBoxLayout() btn_layout.setAlignment(Qt.AlignLeft) btn = QPushButton("Format") # disable format button for int type btn.setEnabled(is_float(data.dtype)) btn_layout.addWidget(btn) btn.clicked.connect(self.change_format) btn = QPushButton("Resize") btn_layout.addWidget(btn) btn.clicked.connect(self.view.resize_to_contents) bgcolor = QCheckBox('Background color') bgcolor.setChecked(self.model.bgcolor_enabled) bgcolor.setEnabled(self.model.bgcolor_enabled) bgcolor.stateChanged.connect(self.model.bgcolor) btn_layout.addWidget(bgcolor) layout = QVBoxLayout() layout.addWidget(self.view) layout.addLayout(btn_layout) self.setLayout(layout)
def _create_scrn_summwidget(self, scrn_device, scrn_idx): """Create and return a screen detail widget.""" cb_scrn = QCheckBox(scrn_device.get_nickname(dev=True), self) self._scrns_sel_bg.addButton(cb_scrn) self._scrns_sel_bg.setId(cb_scrn, scrn_idx) if scrn_idx == self._currScrn: cb_scrn.setChecked(True) cb_scrn.clicked.connect(self._setScrnWidget) cb_scrn.setStyleSheet(""" min-width:6.5em; max-width:6.5em; font-weight:bold;""") led_camenbl = SiriusLedState( self, scrn_device.substitute(prefix=self.prefix, propty='CamEnbl-Sts')) led_camenbl.setStyleSheet("min-width:3.2em; max-width:3.2em;") cb_scrntype = PyDMEnumComboBox( self, scrn_device.substitute(prefix=self.prefix, propty='ScrnType-Sel')) cb_scrntype.setSizePolicy(QSzPlcy.Minimum, QSzPlcy.Fixed) cb_scrntype.setStyleSheet("min-width:4.5em;max-width:4.5em;") lb_scrntype = PyDMLabel( self, scrn_device.substitute(prefix=self.prefix, propty='ScrnType-Sts')) lb_scrntype.setStyleSheet("min-width:4.5em; max-width:4.5em;") lb_scrntype.setAlignment(Qt.AlignCenter) led_scrntype = PyDMLed(self, scrn_device.substitute(prefix=self.prefix, propty='ScrnType-Sts'), color_list=[ PyDMLed.LightGreen, PyDMLed.Red, PyDMLed.Red, PyDMLed.Yellow ]) led_scrntype.shape = 2 led_scrntype.setStyleSheet("""min-width:4.5em; max-width:4.5em;""") wid = QWidget() lay = QGridLayout(wid) lay.setAlignment(Qt.AlignCenter) lay.addWidget(cb_scrn, 1, 1) lay.addWidget(led_camenbl, 1, 2) lay.addWidget(cb_scrntype, 1, 3) lay.addWidget(lb_scrntype, 1, 4) lay.addWidget(led_scrntype, 2, 4) return wid
def _create_form_field(self, layout, value, path, name=None): def _atomic_set(value): local_params = self.copy_params for path_element in path[:-1]: local_params = local_params[path_element] if isinstance(name, str): local_params[path[-1]] = value else: local_params[path[-1]][name] = value if isinstance(value, bool): widget = QCheckBox() widget.setChecked(value) widget.toggled.connect(_atomic_set) self._create_form_field_layout(layout, widget, name) elif isinstance(value, str): widget = QLineEdit() widget.setText(value) widget.textChanged.connect(_atomic_set) self._create_form_field_layout(layout, widget, name) elif isinstance(value, int): widget = QSpinBox() # XXX: this could be improved surely widget.setMaximum(2000) widget.setValue(value) widget.valueChanged.connect(_atomic_set) self._create_form_field_layout(layout, widget, name) elif isinstance(value, float): widget = QDoubleSpinBox() widget.setValue(value) widget.valueChanged.connect(_atomic_set) self._create_form_field_layout(layout, widget, name) elif isinstance(value, list): if len(value) == 3 and "color" in path: widget = ColorButton() widget.setColor(value, is_int=False) widget.colorChanged.connect(_atomic_set) self._create_form_field_layout(layout, widget, name) else: widget_layout = QHBoxLayout() widget_layout.addWidget(QLabel(name)) widget_layout.setStretch(0, len(value)) for idx, element in enumerate(value): self._create_form_field(widget_layout, element, path, idx) widget_layout.setStretch(1 + idx, 1) layout.addLayout(widget_layout)
def make_tag_filters(self): if not self.tags: self.tags = set() for content_item in self.content_info: tags = content_item.get('tags', []) for tag in tags: if tag: self.tags.add(tag) logger.debug("TAGS: %s", self.tags) self.filter_widgets = [] for tag in self.tags: item = QCheckBox(tag.capitalize()) item.setObjectName(tag.lower()) item.setChecked(True) item.clicked.connect(self.filter_content) self.filter_widgets.append(item) self.filters_layout.addWidget(item)
class FeaturesWidget(QWidget): def __init__(self, features_settings): super(FeaturesWidget, self).__init__() # Settings self.feature_categories = DBWrapper().all_features.keys() self.features_settings = features_settings if not self.features_settings: self.features_settings['features'] = {} # Check if default values are defined for cat in self.feature_categories: # defaults to true, compute all features self.features_settings['features'][cat] = True self.features_widgets = {} features_layout = QGridLayout(self) # Add an option to toggle all features self.all_features = QCheckBox('All') self.all_features.setChecked(False) self.all_features.clicked.connect(self.toggle_all) features_layout.addWidget(self.all_features, 0, 0, 1, 1) if 'features' in self.features_settings.keys(): for idx, (label, sett) in enumerate( self.features_settings['features'].items()): self.features_widgets[label] = QCheckBox(label) self.features_widgets[label].setChecked(sett) self.features_widgets[label].clicked.connect(self.toggle) features_layout.addWidget(self.features_widgets[label], idx + 1, 0, 1, 1) def toggle_all(self): for label, sett in self.features_widgets.items(): self.features_widgets[label].setChecked( self.all_features.isChecked()) def toggle(self): if any([not x.isChecked() for x in self.features_widgets.values()]): self.all_features.setChecked(False) def to_dict(self): for key, value in self.features_widgets.items(): self.features_settings['features'][key] = value.isChecked()
class CheckBoxWidget(AbstractDataSetWidget): """ BoolItem widget """ def __init__(self, item, parent_layout): super(CheckBoxWidget, self).__init__(item, parent_layout) self.checkbox = QCheckBox(self.item.get_prop_value("display", "text")) self.checkbox.setToolTip(item.get_help()) self.group = self.checkbox self.store = self.item.get_prop("display", "store", None) if self.store: self.checkbox.stateChanged.connect(self.do_store) def get(self): """Override AbstractDataSetWidget method""" value = self.item.get() if value is not None: self.checkbox.setChecked(value) def set(self): """Override AbstractDataSetWidget method""" self.item.set(self.value()) def value(self): return self.checkbox.isChecked() def place_on_grid(self, layout, row, label_column, widget_column, row_span=1, column_span=1): """Override AbstractDataSetWidget method""" if not self.item.get_prop_value("display", "label"): widget_column = label_column column_span += 1 else: self.place_label(layout, row, label_column) layout.addWidget(self.group, row, widget_column, row_span, column_span) def do_store(self, state): self.store.set(self.item.instance, self.item.item, state) self.parent_layout.refresh_widgets()
def event(self, event: QEvent) -> bool: if event.type() == QEvent.WindowActivate: self.channel_select.change_channels_num(self.settings.image.channels) selected = self._clean_measurements() for val in MEASUREMENT_DICT.values(): area = val.get_starting_leaf().area pc = val.get_starting_leaf().per_component if ( val.get_fields() or (area is not None and area != AreaType.ROI) or (pc is not None and pc != PerComponent.Yes) ): continue text = val.get_name() chk = QCheckBox(text) if text in selected: chk.setChecked(True) self.measurement_layout.addWidget(chk) return super().event(event)
class FontLayout(QGridLayout): """Font selection""" def __init__(self, value, parent=None): QGridLayout.__init__(self) font = tuple_to_qfont(value) assert font is not None # Font family self.family = QFontComboBox(parent) self.family.setCurrentFont(font) self.addWidget(self.family, 0, 0, 1, -1) # Font size self.size = QComboBox(parent) self.size.setEditable(True) sizelist = list(range(6, 12)) + list(range(12, 30, 2)) + [36, 48, 72] size = font.pointSize() if size not in sizelist: sizelist.append(size) sizelist.sort() self.size.addItems([str(s) for s in sizelist]) self.size.setCurrentIndex(sizelist.index(size)) self.addWidget(self.size, 1, 0) # Italic or not self.italic = QCheckBox(_("Italic"), parent) self.italic.setChecked(font.italic()) self.addWidget(self.italic, 1, 1) # Bold or not self.bold = QCheckBox(_("Bold"), parent) self.bold.setChecked(font.bold()) self.addWidget(self.bold, 1, 2) def get_font(self): font = self.family.currentFont() font.setItalic(self.italic.isChecked()) font.setBold(self.bold.isChecked()) font.setPointSize(int(self.size.currentText())) return qfont_to_tuple(font)
class _SaveDialog(QFileDialog): def __init__(self, parent): QFileDialog.__init__(self, parent) self.setFileMode(QFileDialog.AnyFile) self.setAcceptMode(QFileDialog.AcceptSave) # Widgets self._chk_tight = QCheckBox('Tight layout') self._txt_dpi = QSpinBox() self._txt_dpi.setRange(1, 10000) self._txt_dpi.setSingleStep(50) self._txt_dpi.setSuffix('dpi') self._txt_dpi.setValue(100) # Layouts layout = self.layout() lyt_extras = QHBoxLayout() lyt_extras.addWidget(QLabel('Extra options')) lyt_extras.addWidget(self._chk_tight) lyt_extras.addWidget(QLabel('Resolution')) lyt_extras.addWidget(self._txt_dpi) layout.addLayout(lyt_extras, layout.rowCount(), 0, 1, layout.columnCount()) self.setLayout(layout) def tightLayout(self): return self._chk_tight.isChecked() def setTightLayout(self, tight): self._chk_tight.setChecked(tight) def dpi(self): return self._txt_dpi.value() def setDpi(self, dpi): self._txt_dpi.setValue(dpi)
def __init__(self, parent, data, readonly=False, xlabels=None, ylabels=None): QWidget.__init__(self, parent) self.data = data self.old_data_shape = None if len(self.data.shape) == 1: self.old_data_shape = self.data.shape self.data.shape = (self.data.shape[0], 1) elif len(self.data.shape) == 0: self.old_data_shape = self.data.shape self.data.shape = (1, 1) format = SUPPORTED_FORMATS.get(data.dtype.name, '%s') self.model = ArrayModel(self.data, format=format, xlabels=xlabels, ylabels=ylabels, readonly=readonly, parent=self) self.view = ArrayView(self, self.model, data.dtype, data.shape) btn_layout = QHBoxLayout() btn_layout.setAlignment(Qt.AlignLeft) btn = QPushButton(_( "Format")) # disable format button for int type btn.setEnabled(is_float(data.dtype)) btn_layout.addWidget(btn) btn.clicked.connect(self.change_format) btn = QPushButton(_( "Resize")) btn_layout.addWidget(btn) btn.clicked.connect(self.view.resize_to_contents) bgcolor = QCheckBox(_( 'Background color')) bgcolor.setChecked(self.model.bgcolor_enabled) bgcolor.setEnabled(self.model.bgcolor_enabled) bgcolor.stateChanged.connect(self.model.bgcolor) btn_layout.addWidget(bgcolor) layout = QVBoxLayout() layout.addWidget(self.view) layout.addLayout(btn_layout) self.setLayout(layout)
def set_check_box(self, row, col, state): """ function to add a new select checkbox to a cell in a table row won't add a new checkbox if one already exists """ # Check input assert isinstance(state, bool) # Check if cellWidget exists if self.cellWidget(row, col): # existing: just set the value self.cellWidget(row, col).setChecked(state) else: # case to add checkbox checkbox = QCheckBox() checkbox.setText('') checkbox.setChecked(state) # Adding a widget which will be inserted into the table cell # then centering the checkbox within this widget which in turn, # centers it within the table column :-) self.setCellWidget(row, col, checkbox) # END-IF-ELSE return
class MessageCheckBox(QMessageBox): """ A QMessageBox derived widget that includes a QCheckBox aligned to the right under the message and on top of the buttons. """ def __init__(self, *args, **kwargs): super(MessageCheckBox, self).__init__(*args, **kwargs) self._checkbox = QCheckBox() # Set layout to include checkbox size = 9 check_layout = QVBoxLayout() check_layout.addItem(QSpacerItem(size, size)) check_layout.addWidget(self._checkbox, 0, Qt.AlignRight) check_layout.addItem(QSpacerItem(size, size)) # Access the Layout of the MessageBox to add the Checkbox layout = self.layout() if PYQT5: layout.addLayout(check_layout, 1, 2) else: layout.addLayout(check_layout, 1, 1) # --- Public API # Methods to access the checkbox def is_checked(self): return self._checkbox.isChecked() def set_checked(self, value): return self._checkbox.setChecked(value) def set_check_visible(self, value): self._checkbox.setVisible(value) def is_check_visible(self): self._checkbox.isVisible() def checkbox_text(self): self._checkbox.text() def set_checkbox_text(self, text): self._checkbox.setText(text)
def populate_gui(self): _contain_parsed = self.contain_parsed for _row, _entry in enumerate(_contain_parsed): if _entry == ['']: continue self.parent.ui.table.insertRow(_row) # select _layout = QHBoxLayout() _widget = QCheckBox() _widget.setEnabled(True) _layout.addWidget(_widget) _layout.addStretch() _new_widget = QWidget() _new_widget.setLayout(_layout) _widget.stateChanged.connect(lambda state=0, row=_row: self.parent.table_select_state_changed(state, row)) self.parent.ui.table.setCellWidget(_row, 0, _new_widget) # name _item = QTableWidgetItem(_entry[1]) self.parent.ui.table.setItem(_row, 1, _item) # runs _item = QTableWidgetItem(_entry[2]) self.parent.ui.table.setItem(_row, 2, _item) # Sample formula if _entry[3]: _item = QTableWidgetItem(_entry[3]) else: _item = QTableWidgetItem("") self.parent.ui.table.setItem(_row, 3, _item) # mass density if _entry[4]: _item = QTableWidgetItem(_entry[4]) else: _item = QTableWidgetItem("") self.parent.ui.table.setItem(_row, 4, _item) # radius if _entry[5]: _item = QTableWidgetItem(_entry[5]) else: _item = QTableWidgetItem("") self.parent.ui.table.setItem(_row, 5, _item) # packing fraction if _entry[6]: _item = QTableWidgetItem(_entry[6]) else: _item = QTableWidgetItem("") self.parent.ui.table.setItem(_row, 6, _item) # sample shape _widget = QComboBox() _widget.addItem("cylindrical") _widget.addItem("spherical") if _entry[7] == "spherical": _widget.setCurrentIndex(1) self.parent.ui.table.setCellWidget(_row, 7, _widget) # do abs corr _layout = QHBoxLayout() _widget = QCheckBox() if _entry[8] == "True": _widget.setCheckState(Qt.Checked) _widget.setStyleSheet("border: 2px; solid-black") _widget.setEnabled(True) _layout.addStretch() _layout.addWidget(_widget) _layout.addStretch() _new_widget = QWidget() _new_widget.setLayout(_layout) self.parent.ui.table.setCellWidget(_row, 8, _new_widget) for _row, _entry in enumerate(_contain_parsed): if _entry == ['']: continue # select _widget = self.parent.ui.table.cellWidget(_row, 0).children()[1] if _entry[0] == "True": _widget.setChecked(True)
class CondaPackageActionDialog(QDialog): """ """ def __init__(self, parent, env, name, action, version, versions): super(CondaPackageActionDialog, self).__init__(parent) self._parent = parent self._env = env self._version_text = None self._name = name self._dependencies_dic = {} self._conda_process = \ conda_api_q.CondaProcess(self, self._on_process_finished) # widgets self.label = QLabel(self) self.combobox_version = QComboBox() self.label_version = QLabel(self) self.widget_version = None self.table_dependencies = None self.checkbox = QCheckBox(_('Install dependencies (recommended)')) self.bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self) self.button_ok = self.bbox.button(QDialogButtonBox.Ok) self.button_cancel = self.bbox.button(QDialogButtonBox.Cancel) self.button_cancel.setDefault(True) self.button_cancel.setAutoDefault(True) dialog_size = QSize(300, 90) # helper variable values action_title = {const.UPGRADE: _("Upgrade package"), const.DOWNGRADE: _("Downgrade package"), const.REMOVE: _("Remove package"), const.INSTALL: _("Install package")} # Versions might have duplicates from different builds versions = sort_versions(list(set(versions)), reverse=True) # FIXME: There is a bug, a package installed by anaconda has version # astropy 0.4 and the linked list 0.4 but the available versions # in the json file do not include 0.4 but 0.4rc1... so... # temporal fix is to check if inside list otherwise show full list if action == const.UPGRADE: if version in versions: index = versions.index(version) versions = versions[:index] else: versions = versions elif action == const.DOWNGRADE: if version in versions: index = versions.index(version) versions = versions[index+1:] else: versions = versions elif action == const.REMOVE: versions = [version] self.combobox_version.setEnabled(False) if len(versions) == 1: if action == const.REMOVE: labeltext = _('Package version to remove:') else: labeltext = _('Package version available:') self.label_version.setText(versions[0]) self.widget_version = self.label_version else: labeltext = _("Select package version:") self.combobox_version.addItems(versions) self.widget_version = self.combobox_version self.label.setText(labeltext) self.label_version.setAlignment(Qt.AlignLeft) self.table_dependencies = QWidget(self) self._layout = QGridLayout() self._layout.addWidget(self.label, 0, 0, Qt.AlignVCenter | Qt.AlignLeft) self._layout.addWidget(self.widget_version, 0, 1, Qt.AlignVCenter | Qt.AlignRight) self.widgets = [self.checkbox, self.button_ok, self.widget_version, self.table_dependencies] row_index = 1 # Create a Table if action in [const.INSTALL, const.UPGRADE, const.DOWNGRADE]: table = QTableView(self) dialog_size = QSize(dialog_size.width() + 40, 300) self.table_dependencies = table row_index = 1 self._layout.addItem(QSpacerItem(10, 5), row_index, 0) self._layout.addWidget(self.checkbox, row_index + 1, 0, 1, 2) self.checkbox.setChecked(True) self._changed_version(versions[0]) table.setSelectionBehavior(QAbstractItemView.SelectRows) table.verticalHeader().hide() table.horizontalHeader().hide() table.setAlternatingRowColors(True) table.setShowGrid(False) table.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) table.horizontalHeader().setStretchLastSection(True) self._layout.addWidget(self.table_dependencies, row_index + 2, 0, 1, 2, Qt.AlignHCenter) self._layout.addItem(QSpacerItem(10, 5), row_index + 3, 0) self._layout.addWidget(self.bbox, row_index + 6, 0, 1, 2, Qt.AlignHCenter) title = "{0}: {1}".format(action_title[action], name) self.setLayout(self._layout) self.setMinimumSize(dialog_size) self.setFixedSize(dialog_size) self.setWindowTitle(title) self.setModal(True) # signals and slots self.bbox.accepted.connect(self.accept) self.bbox.rejected.connect(self.close) self.combobox_version.currentIndexChanged.connect( self._changed_version) self.checkbox.stateChanged.connect(self._changed_checkbox) def _changed_version(self, version, dependencies=True): """ """ self._set_gui_disabled(True) install_dependencies = (self.checkbox.checkState() == 2) self._version_text = to_text_string(version) self._get_dependencies(install_dependencies) def _get_dependencies(self, dependencies=True): """ """ name = [self._name + '=' + self._version_text] # Temporal fix env_name = self._env if env_name != 'root': env_name = osp.basename(env_name) self._conda_process.dependencies(name=env_name, pkgs=name, dep=dependencies) def _changed_checkbox(self, state): """ """ if state: self._changed_version(self._version_text) else: self._changed_version(self._version_text, dependencies=False) def _on_process_finished(self, boo): """ """ if self.isVisible(): dic = self._conda_process.output self.dependencies_dic = dic self._set_dependencies_table() self._set_gui_disabled(False) def _set_dependencies_table(self): """ """ table = self.table_dependencies dic = self.dependencies_dic table.setModel(CondaDependenciesModel(self, dic)) table.resizeColumnsToContents() table.resizeColumnToContents(1) def _set_gui_disabled(self, value): """ """ if value: table = self.table_dependencies table.setModel(CondaDependenciesModel(self, {})) table.resizeColumnsToContents() table.setDisabled(True) else: table = self.table_dependencies table.setDisabled(False) for widget in self.widgets: widget.setDisabled(value)
class ImageRotationDialog(ExToolWindow): def __init__(self, signal, axes, parent, plugin): super(ImageRotationDialog, self).__init__(parent) self.ui = parent self.create_controls() self.accepted.connect(self.ok) self.rejected.connect(self.close_new) self.signal = signal self.plugin = plugin self.new_out = None self._connected_updates = False if isinstance(axes, str): axm = signal.signal.axes_manager if axes.startswith("nav"): axes = (axm._axes.index(axm.navigation_axes[0]), axm._axes.index(axm.navigation_axes[1])) elif axes.startswith("sig"): axes = (axm._axes.index(axm.signal_axes[0]), axm._axes.index(axm.signal_axes[1])) self.axes = axes self.setWindowTitle(tr("Rotate")) # TODO: TAG: Functionality check if not hasattr(signal.signal, 'events'): self.gbo_preview.setVisible(False) # TODO: Add dynamic rotation, e.g. one that rotates when source # signal's data_changed event triggers def connect(self): # TODO: Don't have to con/dis those in gbo self.opt_new.toggled.connect(self.close_new) self.num_angle.valueChanged.connect(self.update) self.chk_grid.toggled.connect(self.update) self.num_grid.valueChanged.connect(self.update) self.chk_reshape.toggled.connect(self.update) self.opt_new.toggled.connect(self.update) self.opt_replace.toggled.connect(self.update) def disconnect(self): self.num_angle.valueChanged.disconnect(self.update) self.chk_grid.toggled.disconnect(self.update) self.num_grid.valueChanged.disconnect(self.update) self.chk_reshape.toggled.disconnect(self.update) self.opt_new.toggled.disconnect(self.update) self.opt_replace.toggled.disconnect(self.update) def ok(self): # Draw figure if not already done # TODO: TAG: Functionality check if not hasattr(self.signal.signal, 'events') or \ not self.gbo_preview.isChecked(): self.update() angle = self.num_angle.value() reshape = self.chk_reshape.isChecked() self.plugin.record_code( r"<p>.rotate_signal({0}, reshape={1}, axes={2})".format( angle, reshape, self.axes)) # Clean up event connections if self.new_out is not None: self.connect_update_plot(self.new_out.signal, disconnect=True) def close_new(self, value=False): if self.new_out is not None and not value: self.new_out.close() self.new_out = None self._connected_updates = False def set_preview(self, value): if not hasattr(self.signal.signal, 'events'): return if value: self.connect() self.update() else: self.disconnect() self.close_new() def _axes_in_nav(self): axm = self.signal.signal.axes_manager navidx = [axm._axes.index(ax) for ax in axm.navigation_axes] if self.axes[0] in navidx: return True return False def connect_update_plot(self, signal, disconnect=False): if self._connected_updates != disconnect: return # Nothing to do, prevent double connections if self._axes_in_nav(): f = signal._plot.navigator_plot.update else: f = signal._plot.signal_plot.update # TODO: TAG: Functionality check if hasattr(signal, 'events') and hasattr( signal.events, 'data_changed'): if disconnect: signal.events.data_changed.disconnect(f) else: signal.events.data_changed.connect(f, []) self._connected_updates = not disconnect def update(self): angle = self.num_angle.value() reshape = self.chk_reshape.isChecked() if self.opt_new.isChecked(): if self.new_out is None: out = None else: out = self.new_out.signal elif self.opt_replace.isChecked(): out = self.signal.signal else: return # Indeterminate state, do nothing s = self.plugin.rotate_signal(angle, self.signal.signal, record=False, reshape=reshape, out=out, axes=self.axes) if out is None: s.metadata.General.title = self.signal.name + "[Rotated]" s.plot() self.connect_update_plot(s) if (self.gbo_preview.isChecked() and self.opt_new.isChecked() and self.new_out is None): self.new_out = self.ui.lut_signalwrapper[s] else: s = out if self.chk_grid.isChecked() is True: pass # TODO: Draw grid def create_controls(self): """ Create UI controls. """ vbox = QVBoxLayout() form = QFormLayout() self.num_angle = QDoubleSpinBox() self.num_angle.setValue(0.0) self.num_angle.setMinimum(-360) self.num_angle.setMaximum(360) form.addRow(tr("Angle:"), self.num_angle) vbox.addLayout(form) self.gbo_preview = QGroupBox(tr("Preview")) self.gbo_preview.setCheckable(True) self.gbo_preview.setChecked(False) gbo_vbox = QVBoxLayout() self.chk_grid = QCheckBox(tr("Grid")) self.chk_grid.setChecked(False) self.num_grid = QSpinBox() self.num_grid.setValue(4) self.num_grid.setMinimum(1) self.num_grid.setEnabled(False) self.chk_grid.toggled[bool].connect(self.num_grid.setEnabled) gbo_vbox.addWidget(self.chk_grid) gbo_vbox.addWidget(self.num_grid) self.gbo_preview.setLayout(gbo_vbox) vbox.addWidget(self.gbo_preview) self.gbo_preview.toggled[bool].connect(self.set_preview) self.gbo_output = QGroupBox(tr("Output")) self.opt_new = QRadioButton(tr("New signal")) self.opt_replace = QRadioButton(tr("In place")) self.opt_new.setChecked(True) gbo_vbox2 = QVBoxLayout() gbo_vbox2.addWidget(self.opt_new) gbo_vbox2.addWidget(self.opt_replace) self.gbo_output.setLayout(gbo_vbox2) vbox.addWidget(self.gbo_output) self.chk_reshape = QCheckBox(tr("Resize to fit")) self.chk_reshape.setChecked(False) vbox.addWidget(self.chk_reshape) self.btn_ok = QPushButton(tr("&OK")) self.btn_ok.setDefault(True) self.btn_ok.clicked.connect(self.accept) self.btn_cancel = QPushButton(tr("&Cancel")) self.btn_cancel.clicked.connect(self.reject) hbox = QHBoxLayout() hbox.addWidget(self.btn_ok) hbox.addWidget(self.btn_cancel) vbox.addLayout(hbox) vbox.addStretch(1) self.setLayout(vbox)
class ItemPropertyDialog(QDialog): def __init__(self, jsonitem: JsonItem, parent=None): super().__init__(parent) assert jsonitem is not None self.item = jsonitem # name self.nameLabel = QLabel(self.tr("name:")) self.nameLineEdit = QLineEdit(self.item.name or "") self.nameLabel.setBuddy(self.nameLineEdit) # unit self.unitLabel = QLabel(self.tr("unit:")) self.unitLineEdit = QLineEdit(self.item.unit or "") self.unitLabel.setBuddy(self.unitLineEdit) # type self.typeLabel = QLabel(self.tr("type:")) self.typeComboBox = QComboBox() self.typeComboBox.addItems([k for k, t in VALUETYPES]) self.typeComboBox.setCurrentIndex( self.typeComboBox.findText(self.item.type)) self.typeComboBox.currentIndexChanged.connect(self.data_changed) self.typeLabel.setBuddy(self.typeComboBox) # decimals self.decimalsLabel = QLabel(self.tr("decimals:")) self.decimalsSpinBox = QSpinBox() self.decimalsSpinBox.setRange(0, 10) self.decimalsSpinBox.setValue(self.item.decimals or 0) self.decimalsLabel.setBuddy(self.decimalsSpinBox) self.decimalsSpinBox.valueChanged.connect(self.data_changed) self.last_decimals = self.decimalsSpinBox.value() # min self.minLabel = QLabel(self.tr("minimum:")) self.minSpinBox =QDoubleSpinBox() self.minSpinBox.setRange(-sys.maxsize, sys.maxsize) self.minLabel.setBuddy(self.minSpinBox) self.minSpinBox.setValue(self.item.min or 0.0) # max self.maxLabel = QLabel(self.tr("maximum:")) self.maxSpinBox = QDoubleSpinBox() self.maxSpinBox.setRange(-sys.maxsize, sys.maxsize) self.maxSpinBox.setValue(self.item.max or 100.0) # numerator self.scalefactorLabel = QLabel(self.tr("scalefactor:")) self.scalefactorSpinBox = NoZerosDoubleSpinBox() self.scalefactorSpinBox.setRange(-sys.maxsize, sys.maxsize) self.scalefactorSpinBox.setButtonSymbols(QSpinBox.NoButtons) self.scalefactorSpinBox.setDecimals(10) self.scalefactorSpinBox.setValue(self.item.scalefactor or 1) self.scalefactorLabel.setBuddy(self.scalefactorSpinBox) # readonly self.readonlyCheckBox = QCheckBox(self.tr("readonly")) self.readonlyCheckBox.setChecked(Qt.Checked if self.item.readonly else Qt.Unchecked) self.readonlyCheckBox.stateChanged.connect(self.data_changed) # buttons self.buttons = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal ) self.buttons.accepted.connect(self.accept) self.buttons.rejected.connect(self.reject) # layout layout = QGridLayout() layout.addWidget(self.nameLabel, 0, 0) layout.addWidget(self.nameLineEdit, 0, 1) layout.addWidget(self.unitLabel, 1, 0) layout.addWidget(self.unitLineEdit, 1, 1) layout.addWidget(self.typeLabel, 2, 0) layout.addWidget(self.typeComboBox, 2, 1) layout.addWidget(self.decimalsLabel, 3, 0) layout.addWidget(self.decimalsSpinBox, 3, 1) layout.addWidget(self.minLabel, 4, 0) layout.addWidget(self.minSpinBox, 4, 1) layout.addWidget(self.maxLabel, 5, 0) layout.addWidget(self.maxSpinBox, 5, 1) layout.addWidget(self.scalefactorLabel, 6, 0) layout.addWidget(self.scalefactorSpinBox, 6, 1) layout.addWidget(self.readonlyCheckBox, 7, 0, 1, 2) layout.addWidget(self.buttons, 8, 0, 1, 2) self.setLayout(layout) # misc self.setWindowTitle("Edit JsonItem '%s'" % self.item.key) self.data_changed() def accept(self): self.item.name = self.nameLineEdit.text() self.item.unit = self.unitLineEdit.text() self.item.decimals = self.decimalsSpinBox.value() self.item.min = self.minSpinBox.value() self.item.max = self.maxSpinBox.value() self.item.scalefactor = self.scalefactorSpinBox.value() self.item.readonly = self.readonlyCheckBox.checkState() == Qt.Checked self.item.type = self.typeComboBox.currentText() return super().accept() def data_changed(self): type_numeric = self.typeComboBox.currentText() not in ('bool', 'str') type_int = self.typeComboBox.currentText() == 'int' readonly = self.readonlyCheckBox.checkState() == Qt.Checked # not used properties invisible self.decimalsSpinBox.setVisible(type_numeric) self.decimalsLabel.setVisible(type_numeric) self.scalefactorSpinBox.setVisible(type_numeric) self.scalefactorLabel.setVisible(type_numeric) self.minSpinBox.setVisible(type_numeric and not readonly) self.minLabel.setVisible(type_numeric and not readonly) self.maxSpinBox.setVisible(type_numeric and not readonly) self.maxLabel.setVisible(type_numeric and not readonly) self.unitLineEdit.setVisible(type_numeric) self.unitLabel.setVisible(type_numeric) # no decimals for int self.minSpinBox.setDecimals(self.decimalsSpinBox.value()) self.maxSpinBox.setDecimals(self.decimalsSpinBox.value()) if type_int: delta = self.decimalsSpinBox.value() - self.last_decimals self.scalefactorSpinBox.setValue( self.scalefactorSpinBox.value() / 10**delta ) self.last_decimals = self.decimalsSpinBox.value()
class LSPServerEditor(QDialog): DEFAULT_HOST = '127.0.0.1' DEFAULT_PORT = 2084 DEFAULT_CMD = '' DEFAULT_ARGS = '' DEFAULT_CONFIGURATION = '{}' DEFAULT_EXTERNAL = False HOST_REGEX = re.compile(r'^\w+([.]\w+)*$') NON_EMPTY_REGEX = re.compile(r'^\S+$') JSON_VALID = _('JSON valid') JSON_INVALID = _('JSON invalid') def __init__(self, parent, language=None, cmd='', host='127.0.0.1', port=2084, args='', external=False, configurations={}, **kwargs): super(LSPServerEditor, self).__init__(parent) self.parent = parent self.external = external bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.button_ok = bbox.button(QDialogButtonBox.Ok) self.button_cancel = bbox.button(QDialogButtonBox.Cancel) self.button_ok.setEnabled(False) description = _('To create a new configuration, ' 'you need to select a programming ' 'language, along with a executable ' 'name for the server to execute ' '(If the instance is local), ' 'and the host and port. Finally, ' 'you need to provide the ' 'arguments that the server accepts. ' 'The placeholders <tt>%(host)s</tt> and ' '<tt>%(port)s</tt> refer to the host ' 'and the port, respectively.') server_settings_description = QLabel(description) server_settings_description.setWordWrap(True) lang_label = QLabel(_('Language:')) self.lang_cb = QComboBox(self) self.lang_cb.setToolTip(_('Programming language provided ' 'by the LSP server')) self.lang_cb.addItem(_('Select a language')) self.lang_cb.addItems(LSP_LANGUAGES) if language is not None: idx = LSP_LANGUAGES.index(language) self.lang_cb.setCurrentIndex(idx + 1) self.button_ok.setEnabled(True) host_label = QLabel(_('Host:')) self.host_input = QLineEdit(self) self.host_input.setToolTip(_('Name of the host that will provide ' 'access to the server')) self.host_input.setText(host) self.host_input.textChanged.connect(lambda x: self.validate()) port_label = QLabel(_('Port:')) self.port_spinner = QSpinBox(self) 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) cmd_label = QLabel(_('Command to execute:')) self.cmd_input = QLineEdit(self) self.cmd_input.setToolTip(_('Command used to start the ' 'LSP server locally')) self.cmd_input.setText(cmd) if not external: self.cmd_input.textChanged.connect(lambda x: self.validate()) args_label = QLabel(_('Server arguments:')) self.args_input = QLineEdit(self) self.args_input.setToolTip(_('Additional arguments required to ' 'start the server')) self.args_input.setText(args) conf_label = QLabel(_('LSP Server Configurations:')) self.conf_input = CodeEditor(None) self.conf_input.textChanged.connect(self.validate) color_scheme = CONF.get('appearance', 'selected') self.conf_input.setup_editor( language='JSON', color_scheme=color_scheme, 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') self.conf_input.setToolTip(_('Additional LSP server configurations ' 'set at runtime. JSON required')) conf_text = '{}' try: conf_text = json.dumps(configurations, indent=4, sort_keys=True) except Exception: pass self.conf_input.set_text(conf_text) self.json_label = QLabel(self.JSON_VALID, self) self.external_cb = QCheckBox(_('External server'), self) self.external_cb.setToolTip(_('Check if the server runs ' 'on a remote location')) self.external_cb.setChecked(external) self.external_cb.stateChanged.connect(self.set_local_options) hlayout = QHBoxLayout() general_vlayout = QVBoxLayout() general_vlayout.addWidget(server_settings_description) vlayout = QVBoxLayout() lang_layout = QVBoxLayout() lang_layout.addWidget(lang_label) lang_layout.addWidget(self.lang_cb) # layout2 = QHBoxLayout() # layout2.addLayout(lang_layout) lang_layout.addWidget(self.external_cb) vlayout.addLayout(lang_layout) host_layout = QVBoxLayout() host_layout.addWidget(host_label) host_layout.addWidget(self.host_input) port_layout = QVBoxLayout() port_layout.addWidget(port_label) port_layout.addWidget(self.port_spinner) conn_info_layout = QHBoxLayout() conn_info_layout.addLayout(host_layout) conn_info_layout.addLayout(port_layout) vlayout.addLayout(conn_info_layout) cmd_layout = QVBoxLayout() cmd_layout.addWidget(cmd_label) cmd_layout.addWidget(self.cmd_input) vlayout.addLayout(cmd_layout) args_layout = QVBoxLayout() args_layout.addWidget(args_label) args_layout.addWidget(self.args_input) vlayout.addLayout(args_layout) conf_layout = QVBoxLayout() conf_layout.addWidget(conf_label) conf_layout.addWidget(self.conf_input) conf_layout.addWidget(self.json_label) hlayout.addLayout(vlayout) hlayout.addLayout(conf_layout) general_vlayout.addLayout(hlayout) general_vlayout.addWidget(bbox) self.setLayout(general_vlayout) bbox.accepted.connect(self.accept) bbox.rejected.connect(self.reject) self.lang_cb.currentIndexChanged.connect( self.lang_selection_changed) self.form_status(False) if language is not None: self.form_status(True) self.validate() @Slot() def validate(self): host_text = self.host_input.text() cmd_text = self.cmd_input.text() if not self.HOST_REGEX.match(host_text): self.button_ok.setEnabled(False) self.host_input.setStyleSheet("QLineEdit{border: 1px solid red;}") self.host_input.setToolTip('Hostname must be valid') return else: self.host_input.setStyleSheet( "QLineEdit{border: 1px solid green;}") self.host_input.setToolTip('Hostname is valid') self.button_ok.setEnabled(True) if not self.external: if not self.NON_EMPTY_REGEX.match(cmd_text): self.button_ok.setEnabled(False) self.cmd_input.setStyleSheet( "QLineEdit{border: 1px solid red;}") self.cmd_input.setToolTip('Command must be non empty') return if find_program(cmd_text) is None: self.button_ok.setEnabled(False) self.cmd_input.setStyleSheet( "QLineEdit{border: 1px solid red;}") self.cmd_input.setToolTip('Program was not found ' 'on your system') return else: self.cmd_input.setStyleSheet( "QLineEdit{border: 1px solid green;}") self.cmd_input.setToolTip('Program was found on your system') self.button_ok.setEnabled(True) try: json.loads(self.conf_input.toPlainText()) try: self.json_label.setText(self.JSON_VALID) except: pass except (ValueError, json.decoder.JSONDecodeError): try: self.json_label.setText(self.JSON_INVALID) self.button_ok.setEnabled(False) except: pass def form_status(self, status): self.host_input.setEnabled(status) self.port_spinner.setEnabled(status) self.external_cb.setEnabled(status) self.cmd_input.setEnabled(status) self.args_input.setEnabled(status) self.conf_input.setEnabled(status) self.json_label.setVisible(status) @Slot() def lang_selection_changed(self): idx = self.lang_cb.currentIndex() if idx == 0: self.set_defaults() self.form_status(False) self.button_ok.setEnabled(False) else: server = self.parent.get_server_by_lang(LSP_LANGUAGES[idx - 1]) self.form_status(True) if server is not None: self.host_input.setText(server.host) self.port_spinner.setValue(server.port) self.external_cb.setChecked(server.external) self.cmd_input.setText(server.cmd) self.args_input.setText(server.args) self.conf_input.set_text(json.dumps(server.configurations)) self.json_label.setText(self.JSON_VALID) self.button_ok.setEnabled(True) else: self.set_defaults() def set_defaults(self): self.cmd_input.setStyleSheet('') self.host_input.setStyleSheet('') self.host_input.setText(self.DEFAULT_HOST) self.port_spinner.setValue(self.DEFAULT_PORT) self.external_cb.setChecked(self.DEFAULT_EXTERNAL) self.cmd_input.setText(self.DEFAULT_CMD) self.args_input.setText(self.DEFAULT_ARGS) self.conf_input.set_text(self.DEFAULT_CONFIGURATION) self.json_label.setText(self.JSON_VALID) @Slot(bool) @Slot(int) def set_local_options(self, enabled): self.external = enabled self.cmd_input.setEnabled(True) self.args_input.setEnabled(True) if enabled: self.cmd_input.setEnabled(False) self.cmd_input.setStyleSheet('') self.args_input.setEnabled(False) try: self.validate() except: pass def get_options(self): language_idx = self.lang_cb.currentIndex() language = LSP_LANGUAGES[language_idx - 1] host = self.host_input.text() port = int(self.port_spinner.value()) external = self.external_cb.isChecked() args = self.args_input.text() cmd = self.cmd_input.text() configurations = json.loads(self.conf_input.toPlainText()) server = LSPServer(language=language.lower(), cmd=cmd, args=args, host=host, port=port, external=external, configurations=configurations) return server
class DataFrameEditor(QDialog): """ Dialog for displaying and editing DataFrame and related objects. Signals ------- sig_option_changed(str, object): Raised if an option is changed. Arguments are name of option and its new value. """ sig_option_changed = Signal(str, object) def __init__(self, parent=None): QDialog.__init__(self, parent) # Destroying the C++ object right after closing the dialog box, # otherwise it may be garbage-collected in another QThread # (e.g. the editor's analysis thread in Spyder), thus leading to # a segmentation fault on UNIX or an application crash on Windows self.setAttribute(Qt.WA_DeleteOnClose) self.is_series = False self.layout = None def setup_and_check(self, data, title=''): """ Setup DataFrameEditor: return False if data is not supported, True otherwise. Supported types for data are DataFrame, Series and Index. """ self.layout = QGridLayout() self.setLayout(self.layout) self.setWindowIcon(ima.icon('arredit')) if title: title = to_text_string(title) + " - %s" % data.__class__.__name__ else: title = _("%s editor") % data.__class__.__name__ if isinstance(data, Series): self.is_series = True data = data.to_frame() elif isinstance(data, Index): data = DataFrame(data) self.setWindowTitle(title) self.resize(600, 500) self.dataModel = DataFrameModel(data, parent=self) self.dataTable = DataFrameView(self, self.dataModel) self.layout.addWidget(self.dataTable) self.setLayout(self.layout) self.setMinimumSize(400, 300) # Make the dialog act as a window self.setWindowFlags(Qt.Window) btn_layout = QHBoxLayout() btn = QPushButton(_("Format")) # disable format button for int type btn_layout.addWidget(btn) btn.clicked.connect(self.change_format) btn = QPushButton(_('Resize')) btn_layout.addWidget(btn) btn.clicked.connect(self.resize_to_contents) bgcolor = QCheckBox(_('Background color')) bgcolor.setChecked(self.dataModel.bgcolor_enabled) bgcolor.setEnabled(self.dataModel.bgcolor_enabled) bgcolor.stateChanged.connect(self.change_bgcolor_enable) btn_layout.addWidget(bgcolor) self.bgcolor_global = QCheckBox(_('Column min/max')) self.bgcolor_global.setChecked(self.dataModel.colum_avg_enabled) self.bgcolor_global.setEnabled(not self.is_series and self.dataModel.bgcolor_enabled) self.bgcolor_global.stateChanged.connect(self.dataModel.colum_avg) btn_layout.addWidget(self.bgcolor_global) btn_layout.addStretch() bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) bbox.accepted.connect(self.accept) bbox.rejected.connect(self.reject) btn_layout.addWidget(bbox) self.layout.addLayout(btn_layout, 2, 0) return True def change_bgcolor_enable(self, state): """ This is implementet so column min/max is only active when bgcolor is """ self.dataModel.bgcolor(state) self.bgcolor_global.setEnabled(not self.is_series and state > 0) def change_format(self): """ Ask user for display format for floats and use it. This function also checks whether the format is valid and emits `sig_option_changed`. """ format, valid = QInputDialog.getText(self, _('Format'), _("Float formatting"), QLineEdit.Normal, self.dataModel.get_format()) if valid: format = str(format) try: format % 1.1 except: msg = _("Format ({}) is incorrect").format(format) QMessageBox.critical(self, _("Error"), msg) return if not format.startswith('%'): msg = _("Format ({}) should start with '%'").format(format) QMessageBox.critical(self, _("Error"), msg) return self.dataModel.set_format(format) self.sig_option_changed.emit('dataframe_format', format) def get_value(self): """Return modified Dataframe -- this is *not* a copy""" # It is import to avoid accessing Qt C++ object as it has probably # already been destroyed, due to the Qt.WA_DeleteOnClose attribute df = self.dataModel.get_data() if self.is_series: return df.iloc[:, 0] else: return df def resize_to_contents(self): QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) self.dataTable.resizeColumnsToContents() self.dataModel.fetch_more(columns=True) self.dataTable.resizeColumnsToContents() QApplication.restoreOverrideCursor()
class SampleLogsView(QSplitter): """Sample Logs View This contains a table of the logs, a plot of the currently selected logs, and the statistics of the selected log. """ def __init__(self, presenter, parent = None, name = '', isMD=False, noExp = 0): super(SampleLogsView, self).__init__(parent) self.presenter = presenter self.setWindowTitle("{} sample logs".format(name)) self.setWindowFlags(Qt.Window) # Create sample log table self.table = QTableView() self.table.setSelectionBehavior(QAbstractItemView.SelectRows) self.table.clicked.connect(self.presenter.clicked) self.table.doubleClicked.connect(self.presenter.doubleClicked) self.table.contextMenuEvent = self.tableMenu self.addWidget(self.table) frame_right = QFrame() layout_right = QVBoxLayout() #Add full_time and experimentinfo options layout_options = QHBoxLayout() if isMD: layout_options.addWidget(QLabel("Experiment Info #")) self.experimentInfo = QSpinBox() self.experimentInfo.setMaximum(noExp-1) self.experimentInfo.valueChanged.connect(self.presenter.changeExpInfo) layout_options.addWidget(self.experimentInfo) self.full_time = QCheckBox("Relative Time") self.full_time.setChecked(True) self.full_time.stateChanged.connect(self.presenter.plot_logs) layout_options.addWidget(self.full_time) layout_right.addLayout(layout_options) # Sample log plot self.fig = Figure() self.canvas = FigureCanvas(self.fig) self.canvas.setSizePolicy(QSizePolicy.Expanding,QSizePolicy.Expanding) self.canvas.mpl_connect('button_press_event', self.presenter.plot_clicked) self.ax = self.fig.add_subplot(111, projection='mantid') layout_right.addWidget(self.canvas) # Sample stats self.create_stats_widgets() layout_stats = QFormLayout() layout_stats.addRow('', QLabel("Log Statistics")) layout_stats.addRow('Min:', self.stats_widgets["minimum"]) layout_stats.addRow('Max:', self.stats_widgets["maximum"]) layout_stats.addRow('Mean:', self.stats_widgets["mean"]) layout_stats.addRow('Median:', self.stats_widgets["median"]) layout_stats.addRow('Std Dev:', self.stats_widgets["standard_deviation"]) layout_stats.addRow('Time Avg:', self.stats_widgets["time_mean"]) layout_stats.addRow('Time Std Dev:', self.stats_widgets["time_standard_deviation"]) layout_stats.addRow('Duration:', self.stats_widgets["duration"]) layout_right.addLayout(layout_stats) frame_right.setLayout(layout_right) self.addWidget(frame_right) self.setStretchFactor(0,1) self.resize(1200,800) self.show() def tableMenu(self, event): """Right click menu for table, can plot or print selected logs""" menu = QMenu(self) plotAction = menu.addAction("Plot selected") plotAction.triggered.connect(self.presenter.new_plot_logs) plotAction = menu.addAction("Print selected") plotAction.triggered.connect(self.presenter.print_selected_logs) menu.exec_(event.globalPos()) def set_model(self, model): """Set the model onto the table""" self.model = model self.table.setModel(self.model) self.table.resizeColumnsToContents() self.table.horizontalHeader().setSectionResizeMode(2, QHeaderView.Stretch) def plot_selected_logs(self, ws, exp, rows): """Update the plot with the selected rows""" self.ax.clear() self.create_ax_by_rows(self.ax, ws, exp, rows) self.fig.canvas.draw() def new_plot_selected_logs(self, ws, exp, rows): """Create a new plot, in a separate window for selected rows""" fig, ax = plt.subplots(subplot_kw={'projection': 'mantid'}) self.create_ax_by_rows(ax, ws, exp, rows) fig.show() def create_ax_by_rows(self, ax, ws, exp, rows): """Creates the plots for given rows onto axis ax""" for row in rows: log_text = self.get_row_log_name(row) ax.plot(ws, LogName=log_text, label=log_text, marker='.', FullTime=not self.full_time.isChecked(), ExperimentInfo=exp) ax.set_ylabel('') if ax.get_legend_handles_labels()[0]: ax.legend() def get_row_log_name(self, i): """Returns the log name of particular row""" return str(self.model.item(i, 0).text()) def get_exp(self): """Get set experiment info number""" return self.experimentInfo.value() def get_selected_row_indexes(self): """Return a list of selected row from table""" return [row.row() for row in self.table.selectionModel().selectedRows()] def set_selected_rows(self, rows): """Set seleceted rows in table""" mode = QItemSelectionModel.Select | QItemSelectionModel.Rows for row in rows: self.table.selectionModel().select(self.model.index(row, 0), mode) def create_stats_widgets(self): """Creates the statistics widgets""" self.stats_widgets = {"minimum": QLineEdit(), "maximum": QLineEdit(), "mean": QLineEdit(), "median": QLineEdit(), "standard_deviation": QLineEdit(), "time_mean": QLineEdit(), "time_standard_deviation": QLineEdit(), "duration": QLineEdit()} for widget in self.stats_widgets.values(): widget.setReadOnly(True) def set_statistics(self, stats): """Updates the statistics widgets from stats dictionary""" for param in self.stats_widgets.keys(): self.stats_widgets[param].setText('{:.6}'.format(getattr(stats, param))) def clear_statistics(self): """Clears the values in statistics widgets""" for widget in self.stats_widgets.values(): widget.clear()
class ColorbarWidget(QWidget): colorbarChanged = Signal() # The parent should simply redraw their canvas def __init__(self, parent=None): super(ColorbarWidget, self).__init__(parent) self.setWindowTitle("Colorbar") self.setMaximumWidth(200) self.dval = QDoubleValidator() self.cmin = QLineEdit() self.cmin_value = 0 self.cmin.setMaximumWidth(100) self.cmin.editingFinished.connect(self.clim_changed) self.cmin_layout = QHBoxLayout() self.cmin_layout.addStretch() self.cmin_layout.addWidget(self.cmin) self.cmin_layout.addStretch() self.cmax = QLineEdit() self.cmax_value = 1 self.cmax.setMaximumWidth(100) self.cmax.editingFinished.connect(self.clim_changed) self.cmin.setValidator(self.dval) self.cmax.setValidator(self.dval) self.cmax_layout = QHBoxLayout() self.cmax_layout.addStretch() self.cmax_layout.addWidget(self.cmax) self.cmax_layout.addStretch() self.norm_layout = QHBoxLayout() self.norm = QComboBox() self.norm.addItems(NORM_OPTS) self.norm.currentIndexChanged.connect(self.norm_changed) self.powerscale = QLineEdit() self.powerscale_value = 2 self.powerscale.setText("2") self.powerscale.setValidator(QDoubleValidator(0.001,100,3)) self.powerscale.setMaximumWidth(50) self.powerscale.editingFinished.connect(self.norm_changed) self.powerscale.hide() self.powerscale_label = QLabel("n=") self.powerscale_label.hide() self.norm_layout.addStretch() self.norm_layout.addWidget(self.norm) self.norm_layout.addStretch() self.norm_layout.addWidget(self.powerscale_label) self.norm_layout.addWidget(self.powerscale) self.autoscale = QCheckBox("Autoscaling") self.autoscale.setChecked(True) self.autoscale.stateChanged.connect(self.update_clim) self.canvas = FigureCanvas(Figure()) if parent: # Set facecolor to match parent self.canvas.figure.set_facecolor(parent.palette().window().color().getRgbF()) self.ax = self.canvas.figure.add_axes([0.4,0.05,0.2,0.9]) # layout self.layout = QVBoxLayout(self) self.layout.addLayout(self.cmax_layout) self.layout.addWidget(self.canvas, stretch=1) self.layout.addLayout(self.cmin_layout) self.layout.addLayout(self.norm_layout) self.layout.addWidget(self.autoscale) def set_mappable(self, mappable): """ When a new plot is created this method should be called with the new mappable """ self.ax.clear() self.colorbar = Colorbar(ax=self.ax, mappable=mappable) self.cmin_value, self.cmax_value = self.colorbar.get_clim() self.update_clim_text() self.redraw() def norm_changed(self): """ Called when a different normalization is selected """ idx = self.norm.currentIndex() if NORM_OPTS[idx] == 'Power': self.powerscale.show() self.powerscale_label.show() else: self.powerscale.hide() self.powerscale_label.hide() self.colorbar.mappable.set_norm(self.get_norm()) self.colorbarChanged.emit() def get_norm(self): """ This will create a matplotlib.colors.Normalize from selected idx, limits and powerscale """ idx = self.norm.currentIndex() if self.autoscale.isChecked(): cmin = cmax = None else: cmin = self.cmin_value cmax = self.cmax_value if NORM_OPTS[idx] == 'Power': if self.powerscale.hasAcceptableInput(): self.powerscale_value = float(self.powerscale.text()) return PowerNorm(gamma=self.powerscale_value, vmin=cmin, vmax=cmax) elif NORM_OPTS[idx] == "SymmetricLog10": return SymLogNorm(1e-8 if cmin is None else max(1e-8, abs(cmin)*1e-3), vmin=cmin, vmax=cmax) else: return Normalize(vmin=cmin, vmax=cmax) def clim_changed(self): """ Called when either the min or max is changed. Will unset the autoscale. """ self.autoscale.blockSignals(True) self.autoscale.setChecked(False) self.autoscale.blockSignals(False) self.update_clim() def update_clim(self): """ This will update the clim of the plot based on min, max, and autoscale """ if self.autoscale.isChecked(): data = self.colorbar.mappable.get_array() try: try: self.cmin_value = data[~data.mask].min() self.cmax_value = data[~data.mask].max() except AttributeError: self.cmin_value = np.nanmin(data) self.cmax_value = np.nanmax(data) except (ValueError, RuntimeWarning): # all values mask pass self.update_clim_text() else: if self.cmin.hasAcceptableInput(): self.cmin_value = float(self.cmin.text()) if self.cmax.hasAcceptableInput(): self.cmax_value = float(self.cmax.text()) self.colorbar.set_clim(self.cmin_value, self.cmax_value) self.redraw() def update_clim_text(self): """ Update displayed limit values based on stored ones """ self.cmin.setText("{:.4}".format(self.cmin_value)) self.cmax.setText("{:.4}".format(self.cmax_value)) def redraw(self): """ Redraws the colobar and emits signal to cause the parent to redraw """ self.colorbar.update_ticks() self.colorbar.draw_all() self.canvas.draw_idle() self.colorbarChanged.emit()
class DlgGitHubLogin(QDialog): """Dialog to submit error reports to Github.""" def __init__(self, parent, username, password, token, remember=False, remember_token=False): QDialog.__init__(self, parent) title = _("Sign in to Github") self.resize(415, 375) self.setWindowTitle(title) self.setWindowFlags( self.windowFlags() & ~Qt.WindowContextHelpButtonHint) # Header html = ('<html><head/><body><p align="center">' '{title}</p></body></html>') lbl_html = QLabel(html.format(title=title)) lbl_html.setStyleSheet('font-size: 16px;') # Tabs self.tabs = QTabWidget() # Basic form layout basic_form_layout = QFormLayout() basic_form_layout.setContentsMargins(-1, 0, -1, -1) basic_lbl_msg = QLabel(_("For regular users, i.e. users <b>without</b>" " two-factor authentication enabled")) basic_lbl_msg.setWordWrap(True) basic_lbl_msg.setAlignment(Qt.AlignJustify) lbl_user = QLabel(_("Username:"******"", QWidget()) lbl_password = QLabel(_("Password: "******"Remember me")) self.cb_remember.setToolTip(_("Spyder will save your credentials " "safely")) self.cb_remember.setChecked(remember) basic_form_layout.setWidget(4, QFormLayout.FieldRole, self.cb_remember) # Basic auth tab basic_auth = QWidget() basic_layout = QVBoxLayout() basic_layout.addSpacerItem(QSpacerItem(QSpacerItem(0, 8))) basic_layout.addWidget(basic_lbl_msg) basic_layout.addSpacerItem( QSpacerItem(QSpacerItem(0, 50, vPolicy=QSizePolicy.Expanding))) basic_layout.addLayout(basic_form_layout) basic_layout.addSpacerItem( QSpacerItem(QSpacerItem(0, 50, vPolicy=QSizePolicy.Expanding))) basic_auth.setLayout(basic_layout) self.tabs.addTab(basic_auth, _("Password Only")) # Token form layout token_form_layout = QFormLayout() token_form_layout.setContentsMargins(-1, 0, -1, -1) token_lbl_msg = QLabel(_("For users <b>with</b> two-factor " "authentication enabled, or who prefer a " "per-app token authentication.<br><br>" "You can go <b><a href=\"{}\">here</a></b> " "and click \"Generate token\" at the bottom " "to create a new token to use for this, with " "the appropriate permissions.").format( TOKEN_URL)) token_lbl_msg.setOpenExternalLinks(True) token_lbl_msg.setWordWrap(True) token_lbl_msg.setAlignment(Qt.AlignJustify) lbl_token = QLabel("Token: ") token_form_layout.setWidget(1, QFormLayout.LabelRole, lbl_token) self.le_token = QLineEdit() self.le_token.setEchoMode(QLineEdit.Password) self.le_token.textChanged.connect(self.update_btn_state) token_form_layout.setWidget(1, QFormLayout.FieldRole, self.le_token) self.cb_remember_token = None # Same validation as with cb_remember if self.is_keyring_available() and valid_py_os: self.cb_remember_token = QCheckBox(_("Remember token")) self.cb_remember_token.setToolTip(_("Spyder will save your " "token safely")) self.cb_remember_token.setChecked(remember_token) token_form_layout.setWidget(3, QFormLayout.FieldRole, self.cb_remember_token) # Token auth tab token_auth = QWidget() token_layout = QVBoxLayout() token_layout.addSpacerItem(QSpacerItem(QSpacerItem(0, 8))) token_layout.addWidget(token_lbl_msg) token_layout.addSpacerItem( QSpacerItem(QSpacerItem(0, 50, vPolicy=QSizePolicy.Expanding))) token_layout.addLayout(token_form_layout) token_layout.addSpacerItem( QSpacerItem(QSpacerItem(0, 50, vPolicy=QSizePolicy.Expanding))) token_auth.setLayout(token_layout) self.tabs.addTab(token_auth, _("Access Token")) # Sign in button self.bt_sign_in = QPushButton(_("Sign in")) self.bt_sign_in.clicked.connect(self.accept) self.bt_sign_in.setDisabled(True) # Main layout layout = QVBoxLayout() layout.addWidget(lbl_html) layout.addWidget(self.tabs) layout.addWidget(self.bt_sign_in) self.setLayout(layout) # Final adjustments if username and password: self.le_user.setText(username) self.le_password.setText(password) self.bt_sign_in.setFocus() elif username: self.le_user.setText(username) self.le_password.setFocus() elif token: self.le_token.setText(token) else: self.le_user.setFocus() self.setFixedSize(self.width(), self.height()) self.le_password.installEventFilter(self) self.le_user.installEventFilter(self) self.tabs.currentChanged.connect(self.update_btn_state) def eventFilter(self, obj, event): interesting_objects = [self.le_password, self.le_user] if obj in interesting_objects and event.type() == QEvent.KeyPress: if (event.key() == Qt.Key_Return and event.modifiers() & Qt.ControlModifier and self.bt_sign_in.isEnabled()): self.accept() return True return False def update_btn_state(self): user = to_text_string(self.le_user.text()).strip() != '' password = to_text_string(self.le_password.text()).strip() != '' token = to_text_string(self.le_token.text()).strip() != '' enable = ((user and password and self.tabs.currentIndex() == 0) or (token and self.tabs.currentIndex() == 1)) self.bt_sign_in.setEnabled(enable) def is_keyring_available(self): """Check if keyring is available for password storage.""" try: import keyring # analysis:ignore return True except Exception: return False @classmethod def login(cls, parent, username, password, token, remember, remember_token): dlg = DlgGitHubLogin(parent, username, password, token, remember, remember_token) if dlg.exec_() == dlg.Accepted: user = dlg.le_user.text() password = dlg.le_password.text() token = dlg.le_token.text() if dlg.cb_remember: remember = dlg.cb_remember.isChecked() else: remember = False if dlg.cb_remember_token: remember_token = dlg.cb_remember_token.isChecked() else: remember_token = False credentials = dict(username=user, password=password, token=token, remember=remember, remember_token=remember_token) return credentials return dict(username=None, password=None, token=None, remember=False, remember_token=False)
class RunConfigOptions(QWidget): """Run configuration options""" def __init__(self, parent=None): QWidget.__init__(self, parent) self.dir = None self.runconf = RunConfiguration() firstrun_o = CONF.get('run', ALWAYS_OPEN_FIRST_RUN_OPTION, False) # --- Interpreter --- interpreter_group = QGroupBox(_("Console")) interpreter_layout = QVBoxLayout() interpreter_group.setLayout(interpreter_layout) self.current_radio = QRadioButton(CURRENT_INTERPRETER) interpreter_layout.addWidget(self.current_radio) self.dedicated_radio = QRadioButton(DEDICATED_INTERPRETER) interpreter_layout.addWidget(self.dedicated_radio) self.systerm_radio = QRadioButton(SYSTERM_INTERPRETER) interpreter_layout.addWidget(self.systerm_radio) # --- General settings ---- common_group = QGroupBox(_("General settings")) common_layout = QGridLayout() common_group.setLayout(common_layout) self.clear_var_cb = QCheckBox(CLEAR_ALL_VARIABLES) common_layout.addWidget(self.clear_var_cb, 0, 0) self.post_mortem_cb = QCheckBox(POST_MORTEM) common_layout.addWidget(self.post_mortem_cb, 1, 0) self.clo_cb = QCheckBox(_("Command line options:")) common_layout.addWidget(self.clo_cb, 2, 0) self.clo_edit = QLineEdit() self.clo_cb.toggled.connect(self.clo_edit.setEnabled) self.clo_edit.setEnabled(False) common_layout.addWidget(self.clo_edit, 2, 1) # --- Working directory --- wdir_group = QGroupBox(_("Working Directory settings")) wdir_layout = QVBoxLayout() wdir_group.setLayout(wdir_layout) self.file_dir_radio = QRadioButton(FILE_DIR) wdir_layout.addWidget(self.file_dir_radio) self.cwd_radio = QRadioButton(CW_DIR) wdir_layout.addWidget(self.cwd_radio) fixed_dir_layout = QHBoxLayout() self.fixed_dir_radio = QRadioButton(FIXED_DIR) fixed_dir_layout.addWidget(self.fixed_dir_radio) self.wd_edit = QLineEdit() self.fixed_dir_radio.toggled.connect(self.wd_edit.setEnabled) self.wd_edit.setEnabled(False) fixed_dir_layout.addWidget(self.wd_edit) browse_btn = QPushButton(ima.icon('DirOpenIcon'), '', self) browse_btn.setToolTip(_("Select directory")) browse_btn.clicked.connect(self.select_directory) fixed_dir_layout.addWidget(browse_btn) wdir_layout.addLayout(fixed_dir_layout) # --- System terminal --- external_group = QGroupBox(_("External system terminal")) external_group.setDisabled(True) self.systerm_radio.toggled.connect(external_group.setEnabled) external_layout = QGridLayout() external_group.setLayout(external_layout) self.interact_cb = QCheckBox(INTERACT) external_layout.addWidget(self.interact_cb, 1, 0, 1, -1) self.pclo_cb = QCheckBox(_("Command line options:")) external_layout.addWidget(self.pclo_cb, 3, 0) self.pclo_edit = QLineEdit() self.pclo_cb.toggled.connect(self.pclo_edit.setEnabled) self.pclo_edit.setEnabled(False) self.pclo_edit.setToolTip(_("<b>-u</b> is added to the " "other options you set here")) external_layout.addWidget(self.pclo_edit, 3, 1) # Checkbox to preserve the old behavior, i.e. always open the dialog # on first run hline = QFrame() hline.setFrameShape(QFrame.HLine) hline.setFrameShadow(QFrame.Sunken) self.firstrun_cb = QCheckBox(ALWAYS_OPEN_FIRST_RUN % _("this dialog")) self.firstrun_cb.clicked.connect(self.set_firstrun_o) self.firstrun_cb.setChecked(firstrun_o) layout = QVBoxLayout() layout.addWidget(interpreter_group) layout.addWidget(common_group) layout.addWidget(wdir_group) layout.addWidget(external_group) layout.addWidget(hline) layout.addWidget(self.firstrun_cb) self.setLayout(layout) def select_directory(self): """Select directory""" basedir = to_text_string(self.wd_edit.text()) if not osp.isdir(basedir): basedir = getcwd_or_home() directory = getexistingdirectory(self, _("Select directory"), basedir) if directory: self.wd_edit.setText(directory) self.dir = directory def set(self, options): self.runconf.set(options) self.clo_cb.setChecked(self.runconf.args_enabled) self.clo_edit.setText(self.runconf.args) if self.runconf.current: self.current_radio.setChecked(True) elif self.runconf.systerm: self.systerm_radio.setChecked(True) else: self.dedicated_radio.setChecked(True) self.interact_cb.setChecked(self.runconf.interact) self.post_mortem_cb.setChecked(self.runconf.post_mortem) self.pclo_cb.setChecked(self.runconf.python_args_enabled) self.pclo_edit.setText(self.runconf.python_args) self.clear_var_cb.setChecked(self.runconf.clear_namespace) self.file_dir_radio.setChecked(self.runconf.file_dir) self.cwd_radio.setChecked(self.runconf.cw_dir) self.fixed_dir_radio.setChecked(self.runconf.fixed_dir) self.dir = self.runconf.dir self.wd_edit.setText(self.dir) def get(self): self.runconf.args_enabled = self.clo_cb.isChecked() self.runconf.args = to_text_string(self.clo_edit.text()) self.runconf.current = self.current_radio.isChecked() self.runconf.systerm = self.systerm_radio.isChecked() self.runconf.interact = self.interact_cb.isChecked() self.runconf.post_mortem = self.post_mortem_cb.isChecked() self.runconf.python_args_enabled = self.pclo_cb.isChecked() self.runconf.python_args = to_text_string(self.pclo_edit.text()) self.runconf.clear_namespace = self.clear_var_cb.isChecked() self.runconf.file_dir = self.file_dir_radio.isChecked() self.runconf.cw_dir = self.cwd_radio.isChecked() self.runconf.fixed_dir = self.fixed_dir_radio.isChecked() self.runconf.dir = self.wd_edit.text() return self.runconf.get() def is_valid(self): wdir = to_text_string(self.wd_edit.text()) if not self.fixed_dir_radio.isChecked() or osp.isdir(wdir): return True else: QMessageBox.critical(self, _("Run configuration"), _("The following working directory is " "not valid:<br><b>%s</b>") % wdir) return False def set_firstrun_o(self): CONF.set('run', ALWAYS_OPEN_FIRST_RUN_OPTION, self.firstrun_cb.isChecked())
class ContourOptionsDialog(QDialog): """ Dialog box for selecting contour options """ def __init__(self, contour_settings): super(ContourOptionsDialog, self).__init__(contour_settings.cubeviz_layout) self.setWindowFlags(self.windowFlags() | Qt.Tool) self.setWindowTitle("Contour Options") self.is_preview_active = False # preview mode? self.contour_settings = contour_settings # ref to caller ContourSettings self.image_viewer = self.contour_settings.image_viewer # ref to image viewer self.options = self.contour_settings.options # ref to ContourSettings options self._colormap_members = self.contour_settings.colormap_members # Colormap options self._colormap_index = DEFAULT_GLUE_COLORMAP_INDEX # Currently selected colormap if "cmap" in self.options: if self.options["cmap"] in self._colormap_members: self._colormap_index = self._colormap_members.index(self.options["cmap"]) # Is there a user spacing? if self.contour_settings.spacing is None: self.is_custom_spacing = False else: self.is_custom_spacing = True # Is there a user min? if self.contour_settings.vmin is None: self.is_vmin = False else: self.is_vmin = True # Is there a user max? if self.contour_settings.vmax is None: self.is_vmax = False else: self.is_vmax = True self.add_contour_label = self.contour_settings.add_contour_label # bool self._init_ui() def _init_ui(self): # Line 1: Color map self.colormap_label = QLabel("Color Scheme: ") self.colormap_combo = QColormapCombo() self.colormap_combo.addItem("", userData=UserDataWrapper(cm.viridis)) self.colormap_combo._update_icons() self.colormap_combo.setCurrentIndex(self._colormap_index) self.colormap_combo.setMaximumWidth(150) self.colormap_combo.currentIndexChanged.connect( self._on_colormap_change) # hbl is short for Horizontal Box Layout hbl1 = QHBoxLayout() hbl1.addWidget(self.colormap_label) hbl1.addWidget(self.colormap_combo) # Line 2: Display contour labels self.contour_label_checkBox = QCheckBox("Contour labels (font size):") if self.contour_settings.add_contour_label: self.contour_label_checkBox.setChecked(True) self.contour_label_checkBox.toggled.connect(self.toggle_labels) font_string = str(self.contour_settings.font_size) self.font_size_input = QLineEdit(font_string) self.font_size_input.setFixedWidth(150) self.font_size_input.setDisabled( not self.contour_settings.add_contour_label) hbl2 = QHBoxLayout() hbl2.addWidget(self.contour_label_checkBox) hbl2.addWidget(self.font_size_input) # Line 3: Contour Spacing self.custom_spacing_checkBox = QCheckBox("Contour spacing (interval):") if self.is_custom_spacing: self.custom_spacing_checkBox.setChecked(True) self.custom_spacing_checkBox.toggled.connect(self.custom_spacing) self.spacing_input = QLineEdit() self.spacing_input.setFixedWidth(150) self.spacing_input.setDisabled(not self.is_custom_spacing) spacing = "" if self.is_custom_spacing: spacing = str(self.contour_settings.spacing) elif self.contour_settings.data_spacing is not None: spacing = self.contour_settings.data_spacing spacing = "{0:1.4f}".format(spacing) self.spacing_default_text = spacing self.spacing_input.setText(spacing) hbl3 = QHBoxLayout() hbl3.addWidget(self.custom_spacing_checkBox) hbl3.addWidget(self.spacing_input) # Line 4: Vmax self.vmax_checkBox = QCheckBox("Set max:") self.vmax_input = QLineEdit() self.vmax_input.setFixedWidth(150) self.vmax_input.setDisabled(not self.is_vmax) vmax = "" if self.is_vmax: self.vmax_checkBox.setChecked(True) vmax = str(self.contour_settings.vmax) elif self.contour_settings.data_max is not None: vmax = self.contour_settings.data_max vmax = "{0:1.4f}".format(vmax) self.vmax_input.setText(vmax) self.vmax_default_text = vmax self.vmax_checkBox.toggled.connect(self.toggle_vmax) hbl4 = QHBoxLayout() hbl4.addWidget(self.vmax_checkBox) hbl4.addWidget(self.vmax_input) # Line 5: Vmin self.vmin_checkBox = QCheckBox("Set min:") self.vmin_input = QLineEdit() self.vmin_input.setFixedWidth(150) self.vmin_input.setDisabled(not self.is_vmin) vmin = "" if self.is_vmin: self.vmin_checkBox.setChecked(True) vmin = str(self.contour_settings.vmin) elif self.contour_settings.data_min is not None: vmin = self.contour_settings.data_min vmin = "{0:1.4f}".format(vmin) self.vmin_input.setText(vmin) self.vmin_default_text = vmin self.vmin_checkBox.toggled.connect(self.toggle_vmin) hbl5 = QHBoxLayout() hbl5.addWidget(self.vmin_checkBox) hbl5.addWidget(self.vmin_input) # Line f: self.previewButton = QPushButton("Preview") self.previewButton.clicked.connect(self.preview) self.defaultButton = QPushButton("Reset") self.defaultButton.clicked.connect(self.default) self.okButton = QPushButton("OK") self.okButton.clicked.connect(self.finish) self.okButton.setDefault(True) self.cancelButton = QPushButton("Cancel") self.cancelButton.clicked.connect(self.cancel) hblf = QHBoxLayout() hblf.addStretch(1) hblf.addWidget(self.previewButton) hblf.addWidget(self.defaultButton) hblf.addWidget(self.cancelButton) hblf.addWidget(self.okButton) vbl = QVBoxLayout() vbl.addLayout(hbl1) vbl.addLayout(hbl2) vbl.addLayout(hbl3) vbl.addLayout(hbl4) vbl.addLayout(hbl5) vbl.addLayout(hblf) self.setLayout(vbl) self.show() def update_data_vals(self, vmin="", vmax="", spacing="1"): self.vmin_default_text = vmin if not self.is_vmin: self.vmin_input.setText(vmin) self.vmax_default_text = vmax if not self.is_vmax: self.vmax_input.setText(vmax) self.spacing_default_text = spacing if not self.is_custom_spacing: self.spacing_input.setText(spacing) def _on_colormap_change(self, index): """Combo index changed handler""" self._colormap_index = index def custom_spacing(self): """Checkbox toggled handler""" if self.is_custom_spacing: self.is_custom_spacing = False self.spacing_input.setDisabled(True) spacing = "" if self.contour_settings.data_spacing: spacing = self.contour_settings.data_spacing spacing = "{0:1.4f}".format(spacing) self.spacing_input.setText(spacing) self.spacing_input.setStyleSheet("") else: self.is_custom_spacing = True self.spacing_input.setDisabled(False) def toggle_labels(self): """Checkbox toggled handler""" if self.add_contour_label: self.add_contour_label = False self.font_size_input.setDisabled(True) font_string = str(self.contour_settings.font_size) self.font_size_input.setText(font_string) self.font_size_input.setStyleSheet("") else: self.add_contour_label = True self.font_size_input.setDisabled(False) def toggle_vmax(self): """Checkbox toggled handler""" if self.is_vmax: self.is_vmax = False self.vmax_input.setDisabled(True) vmax = "" if self.contour_settings.data_max: vmax = self.contour_settings.data_max vmax = "{0:1.4f}".format(vmax) self.vmax_input.setText(vmax) self.vmax_input.setStyleSheet("") else: self.is_vmax = True self.vmax_input.setDisabled(False) def toggle_vmin(self): """Checkbox toggled handler""" if self.is_vmin: self.is_vmin = False self.vmin_input.setDisabled(True) vmin = "" if self.contour_settings.data_min: vmin = self.contour_settings.data_min vmin = "{0:1.4f}".format(vmin) self.vmin_input.setText(vmin) self.vmin_input.setStyleSheet("") else: self.is_vmin = True self.vmin_input.setDisabled(False) def input_validation(self): red = "background-color: rgba(255, 0, 0, 128);" def float_check(min_val=None): if user_input.text() == "": user_input.setStyleSheet(red) return False else: try: value = float(user_input.text()) if min_val is not None: if value <= min_val: user_input.setStyleSheet(red) return False else: user_input.setStyleSheet("") except ValueError: user_input.setStyleSheet(red) return False return True def int_check(min_val=None): if user_input.text() == "": user_input.setStyleSheet(red) return False else: try: value = int(user_input.text()) if min_val is not None: if value <= min_val: user_input.setStyleSheet(red) return False else: user_input.setStyleSheet("") except ValueError: user_input.setStyleSheet(red) return False return True success = True # Check 1: spacing_input if self.is_custom_spacing: user_input = self.spacing_input float_check(0) success = success and float_check() # Check 2: font_size_input if self.add_contour_label: user_input = self.font_size_input int_check(0) success = success and int_check() # Check 3: vmax if self.is_vmax: user_input = self.vmax_input float_check() success = success and float_check() # Check 4: vmax if self.is_vmin: user_input = self.vmin_input float_check() success = success and float_check() # Check 5: vmax and vmin if self.is_vmax and self.is_vmin and success: vmax = float(self.vmax_input.text()) vmin = float(self.vmin_input.text()) if vmax <= vmin: self.vmax_input.setStyleSheet(red) self.vmin_input.setStyleSheet(red) success = False return success def finish(self): """ Ok button pressed. Finalize options and send to image viewer """ success = self.input_validation() if not success: return # Change Color Map self._colormap_index = self.colormap_combo.currentIndex() colormap = self._colormap_members[self._colormap_index] self.contour_settings.options["cmap"] = colormap # labels self.contour_settings.add_contour_label = self.add_contour_label # font size if self.add_contour_label: font_size = int(self.font_size_input.text()) self.contour_settings.font_size = font_size else: self.contour_settings.font_size = DEFAULT_CONTOUR_FONT_SIZE # Spacing if self.is_custom_spacing: self.contour_settings.spacing = float(self.spacing_input.text()) else: self.contour_settings.spacing = None # vmax if self.is_vmax: vmax = float(self.vmax_input.text()) self.contour_settings.vmax = vmax self.contour_settings.options["vmax"] = vmax else: self.contour_settings.vmax = None self.contour_settings.options["vmax"] = None # vmin if self.is_vmin: vmin = float(self.vmin_input.text()) self.contour_settings.vmin = vmin self.contour_settings.options["vmin"] = vmin else: self.contour_settings.vmin = None self.contour_settings.options["vmin"] = None # Redraw contour if self.contour_settings.image_viewer.is_contour_active: self.contour_settings.draw_function() self.close() def preview(self): """ Prepare preview contour settings and send to image viewer """ success = self.input_validation() if not success: return image_viewer = self.contour_settings.image_viewer preview_settings = ContourSettings(image_viewer) preview_settings.dialog = self preview_settings.options = self.contour_settings.options.copy() preview_settings.spacing = self.contour_settings.spacing # Change Color Map self._colormap_index = self.colormap_combo.currentIndex() colormap = self._colormap_members[self._colormap_index] preview_settings.options["cmap"] = colormap # labels add_contour_label = self.contour_label_checkBox.isChecked() preview_settings.add_contour_label = add_contour_label # font size if add_contour_label: font_size = int(self.font_size_input.text()) preview_settings.font_size = font_size # Spacing if self.is_custom_spacing: preview_settings.spacing = float(self.spacing_input.text()) else: preview_settings.spacing = None # vmax if self.is_vmax: vmax = float(self.vmax_input.text()) preview_settings.vmax = vmax preview_settings.options["vmax"] = vmax else: preview_settings.vmax = None preview_settings.options["vmax"] = None # vmin if self.is_vmin: vmin = float(self.vmin_input.text()) preview_settings.vmin = vmin preview_settings.options["vmin"] = vmin else: preview_settings.vmin = None preview_settings.options["vmin"] = None # Redraw contour if image_viewer.is_contour_active: self.is_preview_active = True image_viewer.set_contour_preview(preview_settings) else: message = "Contour map is currently switched off. " \ "Please turn on the contour map by selecting " \ "a component from the contour map drop-down menu." info = QMessageBox.critical(self, "Error", message) def default(self): """ Set options back to default and send to image viewer """ self.contour_settings.options = self.contour_settings.default_options() self.contour_settings.spacing = None self.contour_settings.font_size = DEFAULT_CONTOUR_FONT_SIZE self.contour_settings.vmax = None self.contour_settings.vmin = None self.contour_settings.add_contour_label = False if self.contour_settings.image_viewer.is_contour_active: self.contour_settings.draw_function() self.contour_settings.options_dialog() def cancel(self): if self.contour_settings.image_viewer.is_contour_active: self.contour_settings.draw_function() self.close() def closeEvent(self, event): """closeEvent handler""" if self.is_preview_active: self.contour_settings.image_viewer.end_contour_preview() def keyPressEvent(self, e): if e.key() == Qt.Key_Escape: self.cancel()
class NameCategoryPrompt(ExToolWindow): def __init__(self, main_window, parent=None): super(NameCategoryPrompt, self).__init__(parent) self.setWindowTitle(tr("Plugin properties")) self.ui = main_window self.create_controls() def checks_changed(self): menu = self.chk_menu.isChecked() toolbar = self.chk_toolbar.isChecked() icon = self.chk_icon.isChecked() if menu or toolbar: self.txt_category.setEnabled(True) else: self.txt_category.setEnabled(False) self.txt_iconpath.setEnabled(icon) self.btn_browse_icon.setEnabled(icon) def browse_icon(self): formats = QtGui.QImageReader.supportedImageFormats() formats = [str(f, encoding='ascii') for f in formats] # Add one filter that takes all supported: type_filter = tr("Supported formats") type_filter += ' (*.{0})'.format(' *.'.join(formats)) # Add all as individual options type_filter += ';;' + tr("All files") + \ ' (*.*) ;;*.' + ';;*.'.join(formats) path = QtWidgets.QFileDialog.getOpenFileName(self, tr("Pick icon"), os.path.dirname(self.ui.cur_dir), type_filter) if isinstance(path, tuple): # Pyside returns tuple, PyQt not path = path[0] if path is None: return self.txt_iconpath.setText(path) def create_controls(self): self.txt_name = QLineEdit() self.chk_menu = QCheckBox(tr("Menu entry")) self.chk_menu.setChecked(True) self.chk_toolbar = QCheckBox(tr("Toolbar button")) self.chk_toolbar.setChecked(True) self.txt_category = QLineEdit() self.chk_icon = QCheckBox() self.chk_toolbar.setChecked(False) self.txt_iconpath = QLineEdit() self.btn_browse_icon = QPushButton("...") self.txt_iconpath.setEnabled(False) self.btn_browse_icon.setEnabled(False) btns = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, QtCore.Qt.Horizontal) self.chk_menu.toggled.connect(self.checks_changed) self.chk_toolbar.toggled.connect(self.checks_changed) self.chk_icon.toggled.connect(self.checks_changed) self.btn_browse_icon.clicked.connect(self.browse_icon) btns.accepted.connect(self.accept) btns.rejected.connect(self.reject) hbox = QHBoxLayout() for w in [self.chk_icon, self.txt_iconpath, self.btn_browse_icon]: hbox.addWidget(w) form = QFormLayout() form.addRow(tr("Name"), self.txt_name) form.addRow(self.chk_menu, self.chk_toolbar) form.addRow(tr("Category"), self.txt_category) form.addRow(tr("Icon"), hbox) vbox = QVBoxLayout(self) vbox.addLayout(form) vbox.addWidget(btns) self.setLayout(vbox)
class RunConfigOptions(QWidget): """Run configuration options""" def __init__(self, parent=None): QWidget.__init__(self, parent) self.current_radio = None self.dedicated_radio = None self.systerm_radio = None self.runconf = RunConfiguration() firstrun_o = CONF.get("run", ALWAYS_OPEN_FIRST_RUN_OPTION, False) # --- General settings ---- common_group = QGroupBox(_("General settings")) common_layout = QGridLayout() common_group.setLayout(common_layout) self.clo_cb = QCheckBox(_("Command line options:")) common_layout.addWidget(self.clo_cb, 0, 0) self.clo_edit = QLineEdit() self.clo_cb.toggled.connect(self.clo_edit.setEnabled) self.clo_edit.setEnabled(False) common_layout.addWidget(self.clo_edit, 0, 1) self.wd_cb = QCheckBox(_("Working directory:")) common_layout.addWidget(self.wd_cb, 1, 0) wd_layout = QHBoxLayout() self.wd_edit = QLineEdit() self.wd_cb.toggled.connect(self.wd_edit.setEnabled) self.wd_edit.setEnabled(False) wd_layout.addWidget(self.wd_edit) browse_btn = QPushButton(ima.icon("DirOpenIcon"), "", self) browse_btn.setToolTip(_("Select directory")) browse_btn.clicked.connect(self.select_directory) wd_layout.addWidget(browse_btn) common_layout.addLayout(wd_layout, 1, 1) self.post_mortem_cb = QCheckBox(_("Enter debugging mode when " "errors appear during execution")) common_layout.addWidget(self.post_mortem_cb) # --- Interpreter --- interpreter_group = QGroupBox(_("Console")) interpreter_layout = QVBoxLayout() interpreter_group.setLayout(interpreter_layout) self.current_radio = QRadioButton(CURRENT_INTERPRETER) interpreter_layout.addWidget(self.current_radio) self.dedicated_radio = QRadioButton(DEDICATED_INTERPRETER) interpreter_layout.addWidget(self.dedicated_radio) self.systerm_radio = QRadioButton(SYSTERM_INTERPRETER) interpreter_layout.addWidget(self.systerm_radio) # --- Dedicated interpreter --- new_group = QGroupBox(_("Dedicated Python console")) self.current_radio.toggled.connect(new_group.setDisabled) new_layout = QGridLayout() new_group.setLayout(new_layout) self.interact_cb = QCheckBox(_("Interact with the Python " "console after execution")) new_layout.addWidget(self.interact_cb, 1, 0, 1, -1) self.show_kill_warning_cb = QCheckBox(_("Show warning when killing" " running process")) new_layout.addWidget(self.show_kill_warning_cb, 2, 0, 1, -1) self.pclo_cb = QCheckBox(_("Command line options:")) new_layout.addWidget(self.pclo_cb, 3, 0) self.pclo_edit = QLineEdit() self.pclo_cb.toggled.connect(self.pclo_edit.setEnabled) self.pclo_edit.setEnabled(False) self.pclo_edit.setToolTip(_("<b>-u</b> is added to the " "other options you set here")) new_layout.addWidget(self.pclo_edit, 3, 1) # Checkbox to preserve the old behavior, i.e. always open the dialog # on first run hline = QFrame() hline.setFrameShape(QFrame.HLine) hline.setFrameShadow(QFrame.Sunken) self.firstrun_cb = QCheckBox(ALWAYS_OPEN_FIRST_RUN % _("this dialog")) self.firstrun_cb.clicked.connect(self.set_firstrun_o) self.firstrun_cb.setChecked(firstrun_o) layout = QVBoxLayout() layout.addWidget(interpreter_group) layout.addWidget(common_group) layout.addWidget(new_group) layout.addWidget(hline) layout.addWidget(self.firstrun_cb) self.setLayout(layout) def select_directory(self): """Select directory""" basedir = to_text_string(self.wd_edit.text()) if not osp.isdir(basedir): basedir = getcwd() directory = getexistingdirectory(self, _("Select directory"), basedir) if directory: self.wd_edit.setText(directory) self.wd_cb.setChecked(True) def set(self, options): self.runconf.set(options) self.clo_cb.setChecked(self.runconf.args_enabled) self.clo_edit.setText(self.runconf.args) self.wd_cb.setChecked(self.runconf.wdir_enabled) self.wd_edit.setText(self.runconf.wdir) if self.runconf.current: self.current_radio.setChecked(True) elif self.runconf.systerm: self.systerm_radio.setChecked(True) else: self.dedicated_radio.setChecked(True) self.interact_cb.setChecked(self.runconf.interact) self.show_kill_warning_cb.setChecked(self.runconf.show_kill_warning) self.post_mortem_cb.setChecked(self.runconf.post_mortem) self.pclo_cb.setChecked(self.runconf.python_args_enabled) self.pclo_edit.setText(self.runconf.python_args) def get(self): self.runconf.args_enabled = self.clo_cb.isChecked() self.runconf.args = to_text_string(self.clo_edit.text()) self.runconf.wdir_enabled = self.wd_cb.isChecked() self.runconf.wdir = to_text_string(self.wd_edit.text()) self.runconf.current = self.current_radio.isChecked() self.runconf.systerm = self.systerm_radio.isChecked() self.runconf.interact = self.interact_cb.isChecked() self.runconf.show_kill_warning = self.show_kill_warning_cb.isChecked() self.runconf.post_mortem = self.post_mortem_cb.isChecked() self.runconf.python_args_enabled = self.pclo_cb.isChecked() self.runconf.python_args = to_text_string(self.pclo_edit.text()) return self.runconf.get() def is_valid(self): wdir = to_text_string(self.wd_edit.text()) if not self.wd_cb.isChecked() or osp.isdir(wdir): return True else: QMessageBox.critical( self, _("Run configuration"), _("The following working directory is " "not valid:<br><b>%s</b>") % wdir ) return False def set_firstrun_o(self): CONF.set("run", ALWAYS_OPEN_FIRST_RUN_OPTION, self.firstrun_cb.isChecked())
class CondaPackageActionDialog(QDialog): """ """ def __init__(self, parent, prefix, name, action, version, versions, packages_sizes, active_channels): super(CondaPackageActionDialog, self).__init__(parent) self._parent = parent self._prefix = prefix self._version_text = None self._name = name self._dependencies_dic = {} self._active_channels = active_channels self._packages_sizes = packages_sizes self.api = ManagerAPI() # Widgets self.label = QLabel(self) self.combobox_version = QComboBox() self.label_version = QLabel(self) self.widget_version = None self.table_dependencies = None self.checkbox = QCheckBox(_("Install dependencies (recommended)")) self.bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self) self.button_ok = self.bbox.button(QDialogButtonBox.Ok) self.button_cancel = self.bbox.button(QDialogButtonBox.Cancel) self.button_cancel.setDefault(True) self.button_cancel.setAutoDefault(True) dialog_size = QSize(300, 90) # Helper variable values action_title = { C.ACTION_UPGRADE: _("Upgrade package"), C.ACTION_DOWNGRADE: _("Downgrade package"), C.ACTION_REMOVE: _("Remove package"), C.ACTION_INSTALL: _("Install package"), } # FIXME: There is a bug, a package installed by anaconda has version # astropy 0.4 and the linked list 0.4 but the available versions # in the json file do not include 0.4 but 0.4rc1... so... # temporal fix is to check if inside list otherwise show full list if action == C.ACTION_UPGRADE: if version in versions: index = versions.index(version) combo_versions = versions[index + 1 :] else: versions = versions elif action == C.ACTION_DOWNGRADE: if version in versions: index = versions.index(version) combo_versions = versions[:index] else: versions = versions elif action == C.ACTION_REMOVE: combo_versions = [version] self.combobox_version.setEnabled(False) elif action == C.ACTION_INSTALL: combo_versions = versions # Reverse order for combobox combo_versions = list(reversed(combo_versions)) if len(versions) == 1: if action == C.ACTION_REMOVE: labeltext = _("Package version to remove:") else: labeltext = _("Package version available:") self.label_version.setText(combo_versions[0]) self.widget_version = self.label_version else: labeltext = _("Select package version:") self.combobox_version.addItems(combo_versions) self.widget_version = self.combobox_version self.label.setText(labeltext) self.label_version.setAlignment(Qt.AlignLeft) self.table_dependencies = QWidget(self) layout = QVBoxLayout() version_layout = QHBoxLayout() version_layout.addWidget(self.label) version_layout.addStretch() version_layout.addWidget(self.widget_version) layout.addLayout(version_layout) self.widgets = [self.checkbox, self.button_ok, self.widget_version, self.table_dependencies] # Create a Table if action in [C.ACTION_INSTALL, C.ACTION_UPGRADE, C.ACTION_DOWNGRADE]: table = QTableView(self) dialog_size = QSize(dialog_size.width() + 40, 300) self.table_dependencies = table layout.addWidget(self.checkbox) self.checkbox.setChecked(True) self._changed_version(versions[0]) table.setSelectionBehavior(QAbstractItemView.SelectRows) table.verticalHeader().hide() table.horizontalHeader().hide() table.setAlternatingRowColors(True) table.setShowGrid(False) table.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) table.horizontalHeader().setStretchLastSection(True) layout.addWidget(self.table_dependencies) layout.addWidget(self.bbox) title = "{0}: {1}".format(action_title[action], name) self.setLayout(layout) self.setMinimumSize(dialog_size) self.setFixedSize(dialog_size) self.setWindowTitle(title) self.setModal(True) # Signals and slots self.bbox.accepted.connect(self.accept) self.bbox.rejected.connect(self.close) self.combobox_version.currentIndexChanged.connect(self._changed_version) self.checkbox.stateChanged.connect(self._changed_checkbox) def _changed_version(self, version, dependencies=True): """ """ self._set_gui_disabled(True) version = self.combobox_version.currentText() install_dependencies = self.checkbox.checkState() == Qt.Checked self._version_text = to_text_string(version) self._get_dependencies(install_dependencies) def _get_dependencies(self, dependencies=True): """ """ package_name = [self._name + "=" + self._version_text] worker = self.api.conda_dependencies( prefix=self._prefix, pkgs=package_name, dep=dependencies, channels=self._active_channels ) worker.sig_finished.connect(self._on_process_finished) def _changed_checkbox(self, state): """ """ if state: self._changed_version(self._version_text) else: self._changed_version(self._version_text, dependencies=False) def _on_process_finished(self, worker, output, error): """ """ if self.isVisible(): dic = output self.dependencies_dic = dic self._set_dependencies_table() self._set_gui_disabled(False) def _set_dependencies_table(self): """ """ table = self.table_dependencies dic = self.dependencies_dic table.setModel(CondaDependenciesModel(self, dic, self._packages_sizes)) table.resizeColumnsToContents() table.resizeRowsToContents() def _set_gui_disabled(self, value): """ """ if value: table = self.table_dependencies table.setModel(CondaDependenciesModel(self, {})) table.resizeColumnsToContents() table.setDisabled(True) else: table = self.table_dependencies table.setDisabled(False) for widget in self.widgets: widget.setDisabled(value) def reject(self): self.api.conda_terminate() super(CondaPackageActionDialog, self).reject()