def _setupUi(self): self.image_view = PyDMImageView( parent=self, image_channel=self._dev+':Image-RB', width_channel=self._dev+':Width-RB') self.image_view.setObjectName('image') self.image_view.setStyleSheet( '#image{min-width:20em; min-height:20em;}') self.image_view.maxRedrawRate = 5 self.image_view.colorMap = self.image_view.Jet self.image_view.readingOrder = self.image_view.Clike self._roixproj = SiriusConnectionSignal(self._dev+':ROIProjX-Mon') self._roiyproj = SiriusConnectionSignal(self._dev+':ROIProjY-Mon') self._roixfit = SiriusConnectionSignal(self._dev+':ROIGaussFitX-Mon') self._roiyfit = SiriusConnectionSignal(self._dev+':ROIGaussFitY-Mon') self._roixaxis = SiriusConnectionSignal(self._dev+':ROIAxisX-Mon') self._roiyaxis = SiriusConnectionSignal(self._dev+':ROIAxisY-Mon') self._roistartx = SiriusConnectionSignal(self._dev+':ROIStartX-Mon') self._roistarty = SiriusConnectionSignal(self._dev+':ROIStartY-Mon') self._roiendx = SiriusConnectionSignal(self._dev+':ROIEndX-Mon') self._roiendy = SiriusConnectionSignal(self._dev+':ROIEndY-Mon') self._roixproj.new_value_signal[np.ndarray].connect(self._update_roi) self.plt_roi = PlotCurveItem([0, 0, 500, 500, 0], [0, 500, 500, 0, 0]) pen = mkPen() pen.setColor(QColor('red')) pen.setWidth(1) self.plt_roi.setPen(pen) self.image_view.addItem(self.plt_roi) self.plt_fit_x = PlotCurveItem([0, 0], [0, 400]) self.plt_fit_y = PlotCurveItem([0, 0], [0, 400]) self.plt_his_x = PlotCurveItem([0, 0], [0, 400]) self.plt_his_y = PlotCurveItem([0, 0], [0, 400]) pen = mkPen() pen.setColor(QColor('yellow')) self.plt_his_x.setPen(pen) self.plt_his_y.setPen(pen) self.image_view.addItem(self.plt_fit_x) self.image_view.addItem(self.plt_fit_y) self.image_view.addItem(self.plt_his_x) self.image_view.addItem(self.plt_his_y) gb_conf = self._get_config_widget(self) gb_posi = self._get_position_widget(self) gb_size = self._get_size_widget(self) gl = QGridLayout(self) gl.setContentsMargins(0, 0, 0, 0) if self._ori == 'V': gl.addWidget(self.image_view, 0, 0, 1, 2) gl.addWidget(gb_posi, 1, 0) gl.addWidget(gb_size, 1, 1) gl.addWidget(gb_conf, 2, 0, 1, 2) else: gl.addWidget(self.image_view, 0, 0, 1, 2) gl.addWidget(gb_conf, 0, 2, 2, 1) gl.addWidget(gb_posi, 1, 0) gl.addWidget(gb_size, 1, 1) gl.setColumnStretch(0, 5) gl.setColumnStretch(1, 5) gl.setColumnStretch(2, 1)
def __init__( self, parent: QWidget = None, text: str = "", ): super().__init__(parent) # Set up components self._info_str = QLabel(self) self._button_ok = QPushButton(trans._("OK")) # Widget set up self._info_str.setText(text) # Layout button_layout = QGridLayout() button_layout.addWidget(self._button_ok, 0, 1) button_layout.setColumnStretch(0, 1) button_layout.setColumnStretch(1, 1) main_layout = QVBoxLayout() main_layout.addWidget(self._info_str) main_layout.addLayout(button_layout) self.setLayout(main_layout) # Signals self._button_ok.clicked.connect(self._close_dialog)
def _setupDecayModeWidget(self): self._ld_autostop = QLabel('Auto Stop', self) self._cb_autostop = PyDMStateButton( self, self._inj_prefix.substitute(propty='AutoStop-Sel')) self._cb_autostop.shape = 1 self._led_autostop = SiriusLedState( self, self._inj_prefix.substitute(propty='AutoStop-Sts')) wid = QWidget() lay = QGridLayout(wid) lay.setAlignment(Qt.AlignTop) lay.setContentsMargins(0, 6, 0, 0) lay.addWidget(self._ld_autostop, 0, 0) lay.addWidget(self._cb_autostop, 0, 1) lay.addWidget(self._led_autostop, 0, 2) lay.setColumnStretch(0, 3) lay.setColumnStretch(1, 2) lay.setColumnStretch(2, 2) wid.setStyleSheet(""" .QLabel{ min-width: 6.5em; max-width: 6.5em; min-height: 1.5em; qproperty-alignment: 'AlignRight | AlignVCenter'; } PyDMLabel{ qproperty-alignment: AlignCenter; }""") return wid
def _setupUi(self): cw = QWidget(self) glay = QGridLayout(cw) glay.setHorizontalSpacing(10) glay.setVerticalSpacing(10) lab = QLabel('<h3>Booster Energy Ramping</h3>', cw) lab.setStyleSheet(""" min-height:1.55em; max-height: 1.55em; qproperty-alignment: 'AlignVCenter | AlignRight'; background-color: qlineargradient(spread:pad, x1:1, y1:0.0227273, x2:0, y2:0, stop:0 rgba(173, 190, 207, 255), stop:1 rgba(213, 213, 213, 255));""") glay.addWidget(lab, 0, 0, 1, 2) self.settings = Settings( self, self.prefix, self.ramp_config, self._tunecorr_configname, self._chromcorr_configname) self.setMenuBar(self.settings) self.status_and_commands = StatusAndCommands( self, self.prefix, self.ramp_config) glay.addWidget(self.status_and_commands, 1, 1) self.config_parameters = ConfigParameters( self, self.prefix, self.ramp_config, self._undo_stack, self._tunecorr_configname, self._chromcorr_configname) self.config_parameters.setObjectName('ConfigParameters') glay.addWidget(self.config_parameters, 1, 0) glay.setColumnStretch(0, 15) glay.setColumnStretch(1, 1) self.setCentralWidget(cw)
def __init__(self, settings: ViewSettings): super().__init__() self.settings = settings self.layout_list = QComboBox() self.layout_list.addItems(self.settings.theme_list()) self.layout_list.setCurrentText(self.settings.theme_name) self.layout_list.currentIndexChanged.connect(self.change_theme) self.labels_render_cmb = QComboBox() self.labels_render_cmb.addItems(RENDERING_LIST) self._update_render_mode() self.labels_render_cmb.currentTextChanged.connect( self.change_render_mode) settings.connect_to_profile(RENDERING_MODE_NAME, self._update_render_mode) layout = QGridLayout() layout.addWidget(QLabel("Theme:"), 0, 0) layout.addWidget(self.layout_list, 0, 1) layout.addWidget(QLabel("ROI render mode:"), 1, 0) layout.addWidget(self.labels_render_cmb, 1, 1) layout.setColumnStretch(2, 1) layout.setRowStretch(2, 1) self.setLayout(layout)
def _setupui(self): """.""" wid = QWidget(self) self.setCentralWidget(wid) lay1 = QGridLayout() wid.setLayout(lay1) for dev in DEVICES: grbox = QGroupBox(dev.label, wid) lay = QGridLayout() lay.setContentsMargins(0, 0, 0, 0) grbox.setLayout(lay) lay.addWidget(ControlBox(grbox, dev, prefix=self.prefix), 0, 0) ivsq = GraphIvsQ(wid, dev, prefix=self.prefix) amp = GraphAmpPha(wid, dev, prefix=self.prefix) pha = GraphAmpPha(wid, dev, prop='Phase', prefix=self.prefix) lay.addWidget(ivsq, 0, 1) lay.addWidget(amp, 0, 2) lay.addWidget(pha, 0, 3) lay.setColumnStretch(0, 1) lay.setColumnStretch(1, 1) lay.setColumnStretch(2, 1) lay.setColumnStretch(3, 1) lay1.addWidget(grbox, dev.value, 0)
def _setupUi(self): self.title = QLabel('<h2>PS & PU</h2>', alignment=Qt.AlignCenter) self.title.setStyleSheet('max-height:1.29em;') layout = QGridLayout(self) layout.setHorizontalSpacing(12) layout.addWidget(self.title, 0, 0, 1, 2) for sec in ['LI', 'TB', 'BO', 'TS', 'SI']: status = self._make_groupbox(sec) if sec == 'LI': layout.addWidget(status, 1, 0) elif sec == 'TB': layout.addWidget(status, 1, 1) elif sec == 'BO': layout.addWidget(status, 2, 0) elif sec == 'TS': layout.addWidget(status, 2, 1) elif sec == 'SI': layout.addWidget(status, 3, 0, 1, 2) layout.setColumnStretch(0, 6) layout.setColumnStretch(1, 5) self.setStyleSheet(""" QLed { min-height: 1.1em; max-height: 1.1em; min-width: 1.1em; max-width: 1.1em;} """)
def __init__(self): super().__init__() self.select_type = QComboBox() self.select_type.addItems(["Suffix", "Replace", "Mapping file"]) self.values = ["_mask", ("", ""), ""] self.first_text = QLineEdit(self.values[0]) self.second_text = QLineEdit() self.first_label = QLabel("Use suffix:") self.second_label = QLabel("Replace:") self.select_file_btn = QPushButton("Select file") self.state = 0 layout = QGridLayout() layout.addWidget(self.select_type, 0, 0, 1, 2) layout.addWidget(self.first_label, 1, 0) layout.addWidget(self.second_label, 1, 1) layout.addWidget(self.first_text, 2, 0) layout.addWidget(self.second_text, 2, 1) layout.addWidget(self.select_file_btn, 3, 0, 1, 2) layout.setColumnStretch(0, 1) self.setLayout(layout) self.second_text.setHidden(True) self.second_label.setHidden(True) self.select_file_btn.setHidden(True) self.first_text.textChanged.connect(self.value_changed.emit) self.second_text.textChanged.connect(self.value_changed.emit) self.select_type.currentIndexChanged.connect(self.value_changed.emit) self.select_type.currentIndexChanged.connect(self.change_type) self.select_file_btn.clicked.connect(self.select_file)
def _setupReliableMeasWidget(self): gbox_reliablemeas = QGroupBox('Measure Reliability Status', self) gbox_reliablemeas.setStyleSheet(""" .QLabel{min-height:1.29em; max-height:1.29em;} """) lay_reliablemeas = QGridLayout(gbox_reliablemeas) relmeas_count = self._db['ReliableMeasLabels-Cte']['count'] self.relmeas_labels = list() for idx in range(relmeas_count): led = SiriusLedAlert(parent=self, init_channel=self.dcct_prefix.substitute( propty='ReliableMeas-Mon'), bit=idx) lay_reliablemeas.addWidget(led, idx, 0) lbl = QLabel('', self) self.relmeas_labels.append(lbl) lay_reliablemeas.addWidget(lbl, idx, 1) lay_reliablemeas.setColumnStretch(0, 1) lay_reliablemeas.setColumnStretch(1, 10) self.reliablemeas_channel = _PV( self.dcct_prefix.substitute(propty='ReliableMeasLabels-Cte'), callback=self._updateReliableMeasLabels) return gbox_reliablemeas
def _setupCoeffSettingsWidget(self): ld_coefchoo = QLabel('Choose Set', self, alignment=Qt.AlignRight) cb_coefchoo = PyDMEnumComboBox(self, self.dev_pref + ':LDSET') pb_coefload = PyDMPushButton(parent=self, label='Apply Set', icon=qta.icon('mdi.upload'), init_channel=self.dev_pref + ':BO_CPCOEFF', pressValue=1) pb_coefload.setStyleSheet("icon-size:20px;") pb_coefvrfy = PyDMPushButton(parent=self, label='Verify Set', icon=qta.icon('mdi.check-circle-outline'), init_channel=self.dev_pref + ':BO_CVERIFY', pressValue=1) pb_coefvrfy.setStyleSheet("icon-size:20px;") ld_gen = QLabel('<h4>Generate Coefficients</h4>', self, alignment=Qt.AlignCenter) ld_gengain = QLabel('Gain [0-1]', self, alignment=Qt.AlignRight) sb_gengain = PyDMSpinbox(self, self.dev_pref + ':FLT_GAIN') sb_gengain.showStepExponent = False ld_genphs = QLabel('Phase [°]', self, alignment=Qt.AlignRight) sb_genphs = PyDMSpinbox(self, self.dev_pref + ':FLT_PHASE') sb_genphs.showStepExponent = False ld_genfreq = QLabel('Frequency [0-1]', self, alignment=Qt.AlignRight) sb_genfreq = PyDMSpinbox(self, self.dev_pref + ':FLT_FREQ') sb_genfreq.showStepExponent = False ld_genntap = QLabel('Number of taps', self, alignment=Qt.AlignRight) sb_genntap = PyDMSpinbox(self, self.dev_pref + ':FLT_TAPS') sb_genntap.showStepExponent = False wid = QWidget(self) lay_genset = QGridLayout(wid) lay_genset.setVerticalSpacing(6) lay_genset.setHorizontalSpacing(9) lay_genset.addWidget(ld_gen, 0, 1, 1, 2) lay_genset.addWidget(ld_gengain, 1, 1) lay_genset.addWidget(sb_gengain, 1, 2) lay_genset.addWidget(ld_genphs, 2, 1) lay_genset.addWidget(sb_genphs, 2, 2) lay_genset.addWidget(ld_genfreq, 3, 1) lay_genset.addWidget(sb_genfreq, 3, 2) lay_genset.addWidget(ld_genntap, 4, 1) lay_genset.addWidget(sb_genntap, 4, 2) lay_genset.addWidget(ld_coefchoo, 5, 1) lay_genset.addWidget(cb_coefchoo, 5, 2) lay = QGridLayout() lay_genset.addLayout(lay, 6, 1, 1, 2) lay.addWidget(pb_coefload, 0, 0) lay.addWidget(pb_coefvrfy, 0, 2) lay.setColumnStretch(1, 2) lay_genset.setRowStretch(7, 2) lay_genset.setColumnStretch(0, 2) lay_genset.setColumnStretch(3, 2) return wid
def _setupFBSettingsWidget(self): gbox_settings = QGroupBox('FeedBack Settings', self) ld_fbpatt = QLabel('Feedback Mask', self) le_fbpatt = PyDMLineEdit(self, self.dev_pref + ':FB_PATTERN') ld_cfpatt = QLabel('Alternate Mask', self) le_cfpatt = PyDMLineEdit(self, self.dev_pref + ':CF_PATTERN') ld_alter_inuse = QLabel('Alternate Set In Use', self) led_alter_inuse = SiriusLedState( self, self.dev_pref + ':CF_PATTERN_SUB.VALB') ld_fbenbl = QLabel('Enable', self) pb_fbenbl = PyDMStateButton(self, self.dev_pref + ':FBCTRL') ld_coefsel = QLabel('Coeficient Set', self) cb_coefsel = PyDMEnumComboBox(self, self.dev_pref + ':SETSEL') ld_sftgain = QLabel('Shift Gain', self) sb_sftgain = PyDMSpinbox(self, self.dev_pref + ':SHIFTGAIN') sb_sftgain.showStepExponent = False ld_downspl = QLabel('Downsampling', self) sb_downspl = PyDMSpinbox(self, self.dev_pref + ':PROC_DS') sb_downspl.showStepExponent = False ld_satthrs = QLabel('Sat. Threshold [%]', self) sb_satthrs = PyDMSpinbox(self, self.dev_pref + ':SAT_THRESHOLD') sb_satthrs.showStepExponent = False lay_patt = QGridLayout() lay_patt.addWidget(ld_fbpatt, 0, 0) lay_patt.addWidget(le_fbpatt, 0, 1) lay_patt.addWidget(ld_cfpatt, 1, 0) lay_patt.addWidget(le_cfpatt, 1, 1) lay_patt.addWidget(ld_alter_inuse, 2, 0) lay_patt.addWidget(led_alter_inuse, 2, 1) lay = QGridLayout(gbox_settings) lay.addWidget(ld_fbenbl, 0, 1) lay.addWidget(pb_fbenbl, 0, 2) lay.addWidget(ld_downspl, 0, 4) lay.addWidget(sb_downspl, 0, 5) lay.addWidget(ld_coefsel, 1, 1) lay.addWidget(cb_coefsel, 1, 2) lay.addWidget(ld_sftgain, 1, 4) lay.addWidget(sb_sftgain, 1, 5) lay.addWidget(ld_satthrs, 2, 1) lay.addWidget(sb_satthrs, 2, 2) lay.addLayout(lay_patt, 4, 1, 1, 5) lay.setColumnStretch(0, 3) lay.setColumnStretch(6, 3) lay.setColumnStretch(3, 2) lay.setRowStretch(3, 2) lay.setRowStretch(5, 3) return gbox_settings
class HistogramWidget(QWidget): def __init__( self, x: np.ndarray, y: np.ndarray, xlabel: Optional[str] = None, ylabel: Optional[str] = None, parent=None, ): super(HistogramWidget, self).__init__(parent) # set the width of the histogram plot to match the napari layer control width self.setMinimumWidth(240) self.setMaximumWidth(240) self.hist_plot = Histogram(x, y, xlabel=xlabel, ylabel=ylabel, parent=self) self.hist_plot.setMaximumWidth(230) self.thresh_text = QLineEdit() self.text_layout = QHBoxLayout() self.text_layout.addWidget(QLabel("SNR threshold:")) self.text_layout.addWidget(self.thresh_text) self.text_layout.addItem(QSpacerItem(5, 1)) self.grid_layout = QGridLayout(self) self.grid_layout.setContentsMargins(0, 0, 0, 0) self.grid_layout.setSpacing(2) # self.grid_layout.setColumnMinimumWidth(0, 86) # self.grid_layout.setColumnStretch(1, 1) self.grid_layout.addWidget(self.hist_plot, 0, 0, 4, 6) self.grid_layout.addLayout(self.text_layout, 4, 0) self.grid_layout.setRowStretch(5, 1) self.grid_layout.setColumnStretch(1, 1) self.setLayout(self.grid_layout) self.threshold_changed_callbacks = [] self._on_hist_thresh_change() # connect events self.hist_plot.connect_line_dragged(self._on_hist_thresh_change) self.thresh_text.returnPressed.connect(self._on_thresh_text_change) def _on_hist_thresh_change(self): hist_thresh_value = self.hist_plot._vert_line.getPos()[0] self.thresh_text.setText(f"{hist_thresh_value:.2f}") for func in self.threshold_changed_callbacks: func() def _on_thresh_text_change(self): hist_thresh_value = float(self.thresh_text.text()) self.hist_plot._vert_line.setValue(hist_thresh_value)
def __init__(self, parent=None): super(WidgetGallery, self).__init__(parent) self.originalPalette = QApplication.palette() styleComboBox = QComboBox() styleComboBox.addItems(QStyleFactory.keys()) styleLabel = QLabel("&Style:") styleLabel.setBuddy(styleComboBox) self.useStylePaletteCheckBox = QCheckBox( "&Use style's standard palette") self.useStylePaletteCheckBox.setChecked(True) disableWidgetsCheckBox = QCheckBox("&Disable widgets") self.createTopLeftGroupBox() self.createTopRightGroupBox() self.createBottomLeftTabWidget() self.createBottomRightGroupBox() self.createProgressBar() styleComboBox.activated[str].connect(self.changeStyle) self.useStylePaletteCheckBox.toggled.connect(self.changePalette) disableWidgetsCheckBox.toggled.connect( self.topLeftGroupBox.setDisabled) disableWidgetsCheckBox.toggled.connect( self.topRightGroupBox.setDisabled) disableWidgetsCheckBox.toggled.connect( self.bottomLeftTabWidget.setDisabled) disableWidgetsCheckBox.toggled.connect( self.bottomRightGroupBox.setDisabled) topLayout = QHBoxLayout() topLayout.addWidget(styleLabel) topLayout.addWidget(styleComboBox) topLayout.addStretch(1) topLayout.addWidget(self.useStylePaletteCheckBox) topLayout.addWidget(disableWidgetsCheckBox) mainLayout = QGridLayout() mainLayout.addLayout(topLayout, 0, 0, 1, 2) mainLayout.addWidget(self.topLeftGroupBox, 1, 0) mainLayout.addWidget(self.topRightGroupBox, 1, 1) mainLayout.addWidget(self.bottomLeftTabWidget, 2, 0) mainLayout.addWidget(self.bottomRightGroupBox, 2, 1) mainLayout.addWidget(self.progressBar, 3, 0, 1, 2) mainLayout.setRowStretch(1, 1) mainLayout.setRowStretch(2, 1) mainLayout.setColumnStretch(0, 1) mainLayout.setColumnStretch(1, 1) self.setLayout(mainLayout) self.changeStyle('Windows') self.val = 0
def setup_gui(self): """Setup the main layout of the widget.""" layout = QGridLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.canvas, 0, 1) layout.addLayout(self.setup_toolbar(), 0, 3, 2, 1) layout.setColumnStretch(0, 100) layout.setColumnStretch(2, 100) layout.setRowStretch(1, 100)
def __init__(self, parent, batch_manager): super().__init__(parent) self.task_count = 0 self.calculation_manager = batch_manager self.whole_progress = QProgressBar(self) self.whole_progress.setMinimum(0) self.whole_progress.setMaximum(1) self.whole_progress.setFormat("%v of %m") self.whole_progress.setTextVisible(True) self.part_progress = QProgressBar(self) self.part_progress.setMinimum(0) self.part_progress.setMaximum(1) self.part_progress.setFormat("%v of %m") self.whole_label = QLabel("All batch progress:", self) self.part_label = QLabel("Single batch progress:", self) self.cancel_remove_btn = QPushButton("Remove task") self.cancel_remove_btn.setDisabled(True) self.logs = ExceptionList(self) self.logs.setToolTip("Logs") self.task_view = QListView() self.task_que = QStandardItemModel(self) self.task_view.setModel(self.task_que) self.process_num_timer = QTimer() self.process_num_timer.setInterval(1000) self.process_num_timer.setSingleShot(True) self.process_num_timer.timeout.connect(self.change_number_of_workers) self.number_of_process = QSpinBox(self) self.number_of_process.setRange(1, multiprocessing.cpu_count()) self.number_of_process.setValue(1) self.number_of_process.setToolTip( "Number of process used in batch calculation") self.number_of_process.valueChanged.connect( self.process_num_timer_start) self.progress_item_dict = {} layout = QGridLayout() layout.addWidget(self.whole_label, 0, 0, Qt.AlignRight) layout.addWidget(self.whole_progress, 0, 1, 1, 2) layout.addWidget(self.part_label, 1, 0, Qt.AlignRight) layout.addWidget(self.part_progress, 1, 1, 1, 2) lab = QLabel("Number of process:") lab.setToolTip("Number of process used in batch calculation") layout.addWidget(lab, 2, 0) layout.addWidget(self.number_of_process, 2, 1) layout.addWidget(self.logs, 3, 0, 2, 3) layout.addWidget(self.task_view, 0, 4, 4, 1) layout.addWidget(self.cancel_remove_btn, 4, 4, 1, 1) layout.setColumnMinimumWidth(2, 10) layout.setColumnStretch(2, 1) self.setLayout(layout) self.preview_timer = QTimer() self.preview_timer.setInterval(1000) self.preview_timer.timeout.connect(self.update_info) self.task_view.selectionModel().currentChanged.connect( self.task_selection_change) self.cancel_remove_btn.clicked.connect(self.task_cancel_remove)
def __init__(self): super().__init__() # noinspection PyArgumentList self.reload_btn = QPushButton("Reload algorithms", clicked=self.reload_algorithm_action) layout = QGridLayout() layout.addWidget(self.reload_btn, 0, 0) layout.setColumnStretch(1, 1) layout.setRowStretch(1, 1) self.setLayout(layout)
def _setupDigMonLayout(self): lb_x = QLabel('<h4>X</h4>', self, alignment=Qt.AlignCenter) lb_y = QLabel('<h4>Y</h4>', self, alignment=Qt.AlignCenter) self.lb_tunex = PyDMLabel(self, 'SI-Glob:DI-Tune-H:TuneFrac-Mon') self.lb_tuney = PyDMLabel(self, 'SI-Glob:DI-Tune-V:TuneFrac-Mon') lay = QGridLayout() lay.addWidget(lb_x, 0, 0) lay.addWidget(self.lb_tunex, 0, 1) lay.addWidget(lb_y, 1, 0) lay.addWidget(self.lb_tuney, 1, 1) lay.setColumnStretch(0, 1) lay.setColumnStretch(1, 5) return lay
def setupUI(self): mainLayout = QGridLayout() leftColumnWidget = QGroupBox(config.thisTranslation["commentaries"]) commentaryLayout = QVBoxLayout() commentaryLayout.addWidget(self.commentaryListView()) subSubLayout = QHBoxLayout() button = QPushButton(config.thisTranslation["open"]) button.clicked.connect(self.openPreviousCommentary) subSubLayout.addWidget(button) button = QPushButton(config.thisTranslation["activeOnly"]) button.clicked.connect(self.showActiveOnlyCommentaries) subSubLayout.addWidget(button) commentaryLayout.addLayout(subSubLayout) leftColumnWidget.setLayout(commentaryLayout) rightColumnWidget = QGroupBox(config.thisTranslation["menu10_books"]) bookLayout = QHBoxLayout() subLayout = QVBoxLayout() subLayout.addWidget(self.bookListView()) subSubLayout = QHBoxLayout() button = QPushButton(config.thisTranslation["showAll"]) button.clicked.connect(self.showAllBooks) subSubLayout.addWidget(button) button = QPushButton(config.thisTranslation["favouriteOnly"]) button.clicked.connect(self.favouriteBookOnly) subSubLayout.addWidget(button) button = QPushButton(config.thisTranslation["addFavourite"]) button.clicked.connect(self.addFavorite) subSubLayout.addWidget(button) button = QPushButton(config.thisTranslation["removeFavourite"]) button.clicked.connect(self.removeFavorite) subSubLayout.addWidget(button) subLayout.addLayout(subSubLayout) bookLayout.addLayout(subLayout) subLayout = QVBoxLayout() subLayout.addWidget(self.chapterListView()) button = QPushButton(config.thisTranslation["open"]) button.clicked.connect(self.openPreviousBookChapter) subLayout.addWidget(button) bookLayout.addLayout(subLayout) rightColumnWidget.setLayout(bookLayout) mainLayout.addWidget(leftColumnWidget, 0, 0) mainLayout.addWidget(rightColumnWidget, 0, 1) mainLayout.setColumnStretch(1, 2) self.setLayout(mainLayout)
def _setupUi(self): '''Build the graphic interface''' wid = QWidget(self) if_glay = QGridLayout() if_glay.addLayout(self.display_header(), 0, 0, 1, 3) if_glay.addLayout(self.display_graph(), 1, 0, 2, 1) if_glay.addLayout(self.display_mainData(), 1, 1, 1, 1) if_glay.addLayout(self.display_selectors(), 1, 2, 1, 1) if_glay.setAlignment(Qt.AlignTop) if_glay.setColumnStretch(0, 10) wid.setLayout(if_glay) self.setCentralWidget(wid)
def __init__(self, parent): super().__init__(parent) servers_label = QLabel( _("Spyder uses the <a href=\"{lsp_url}\">Language Server " "Protocol</a> to provide code completion and linting " "for its Editor. Here, you can setup and configure LSP servers " "for languages other than Python, so Spyder can provide such " "features for those languages as well.").format(lsp_url=LSP_URL)) servers_label.setOpenExternalLinks(True) servers_label.setWordWrap(True) servers_label.setAlignment(Qt.AlignJustify) # Servers table table_group = QGroupBox(_('Available servers:')) self.table = LSPServerTable(self, text_color=ima.MAIN_FG_COLOR) self.table.setMaximumHeight(150) table_layout = QVBoxLayout() table_layout.addWidget(self.table) table_group.setLayout(table_layout) # Buttons self.reset_btn = QPushButton(_("Reset to default values")) self.new_btn = QPushButton(_("Set up a new server")) self.delete_btn = QPushButton(_("Delete currently selected server")) self.delete_btn.setEnabled(False) # Slots connected to buttons self.new_btn.clicked.connect(self.create_new_server) self.reset_btn.clicked.connect(self.reset_to_default) self.delete_btn.clicked.connect(self.delete_server) # Buttons layout btns = [self.new_btn, self.delete_btn, self.reset_btn] buttons_layout = QGridLayout() for i, btn in enumerate(btns): buttons_layout.addWidget(btn, i, 1) buttons_layout.setColumnStretch(0, 1) buttons_layout.setColumnStretch(1, 2) buttons_layout.setColumnStretch(2, 1) # Combined layout servers_layout = QVBoxLayout() servers_layout.addSpacing(-10) servers_layout.addWidget(servers_label) servers_layout.addWidget(table_group) servers_layout.addSpacing(10) servers_layout.addLayout(buttons_layout) self.setLayout(servers_layout)
def _setupUi(self): self.label_title = QLabel('SI Current and Lifetime') self.label_title.setStyleSheet(""" font-size:1.2em; font-weight:bold; background-color: qlineargradient(spread:pad, x1:1, y1:0.0227273, x2:0, y2:0, stop:0 rgba(173, 190, 207, 255), stop:1 rgba(213, 213, 213, 255));""") self.label_title.setAlignment(Qt.AlignRight | Qt.AlignVCenter) self.settings = QWidget() vlay_sett = QVBoxLayout(self.settings) vlay_sett.setContentsMargins(0, 0, 0, 0) vlay_sett.addWidget(self._setupCurrentSettingsWidget()) vlay_sett.addWidget(self._setupLifetimeSettigsWidget()) vlay_sett.addWidget(self._setupGraphSettingsWidget()) self.pb_showsett = QPushButton('<', self) self.pb_showsett.setObjectName('showsett') self.pb_showsett.setToolTip('Hide settings') self.pb_showsett.setStyleSheet( '#showsett{min-width:0.7em;max-width:0.7em;}') self.pb_showsett.released.connect(self._handle_settings_vis) self.pb_showeff = QPushButton('v', self) self.pb_showeff.setObjectName('showeff') self.pb_showeff.setToolTip('Show efficiency graph') self.pb_showeff.setStyleSheet( '#showeff{min-width:0.7em;max-width:0.7em;}') self.pb_showeff.released.connect(self._handle_efficiency_vis) hbox_visi = QHBoxLayout() hbox_visi.addStretch() hbox_visi.addWidget(self.pb_showsett) hbox_visi.addWidget(self.pb_showeff) self.eff_graph = EffMonitor(self, self.prefix, self.device.sec) self.eff_graph.setVisible(False) cw = QWidget() self.setCentralWidget(cw) lay = QGridLayout(cw) lay.addWidget(self.label_title, 0, 0, 1, 2) lay.addLayout(self._setupGraphPanelLayout(), 1, 0) lay.addWidget(self.settings, 1, 1) lay.addLayout(hbox_visi, 2, 0, 1, 2, alignment=Qt.AlignRight) lay.addWidget(self.eff_graph, 3, 0, 1, 2) lay.setColumnStretch(0, 6) lay.setColumnStretch(1, 1)
def _setupUi(self): fbsett_wid = self._setupFeedbackSettings() status_wid = self._setupStatusWidget() lay = QGridLayout(self) lay.setAlignment(Qt.AlignTop | Qt.AlignCenter) if self._is_resumed: led_gensts = SiriusLedAlert(self, self.dev_pref+':ERRSUM') dev_label = QLabel( '<h3>'+self._label+'</h3>', self, alignment=Qt.AlignCenter) self.pb_detail = QPushButton(qta.icon('fa5s.ellipsis-v'), '', self) self.pb_detail.setObjectName('dtls') self.pb_detail.setStyleSheet( '#dtls{min-width:20px;max-width:20px;icon-size:15px;}') cmd = ['sirius-hla-si-di-bbb.py', '-dev', self.dev_pref] if self._prefix: cmd.extend(['-p', self._prefix]) connect_newprocess(self.pb_detail, cmd, self) hbox_label = QHBoxLayout() hbox_label.setContentsMargins(0, 0, 0, 0) hbox_label.addWidget(led_gensts, alignment=Qt.AlignLeft) hbox_label.addWidget(dev_label) hbox_label.addWidget(self.pb_detail, alignment=Qt.AlignRight) hbox_label.setStretch(0, 1) hbox_label.setStretch(1, 10) hbox_label.setStretch(2, 1) wid = QWidget(self) wid.setObjectName('box') wid.setStyleSheet(""" #box{border: 2px solid gray;}""") lay_box = QGridLayout(wid) lay_box.setVerticalSpacing(15) lay_box.addLayout(hbox_label, 0, 0) lay_box.addWidget(fbsett_wid, 1, 0) lay_box.addWidget(status_wid, 2, 0) lay.setContentsMargins(0, 0, 0, 0) lay.addWidget(wid) else: info_wid = BbBInfoWidget(self, self._prefix, self._device) lay.addWidget(fbsett_wid, 0, 1) lay.addWidget(status_wid, 0, 2) lay.addWidget(info_wid, 0, 3) lay.setColumnStretch(0, 3) lay.setColumnStretch(4, 3) lay.setRowStretch(1, 3)
def _setupUi(self): dac_wid = BbBSlowDACsWidget(self, self.prefix, self.device) adc_wid = BbBADCWidget(self, self.prefix, self.device) devs_wid = BbBGeneralSettingsWidget(self, self.prefix, self.device) intlk = BbBInterlock(self, self.prefix, self.device) lay = QGridLayout(self) lay.addWidget(devs_wid, 1, 1) lay.addWidget(intlk, 1, 3) lay.addWidget(adc_wid, 3, 1) lay.addWidget(dac_wid, 3, 3) lay.setColumnStretch(0, 3) lay.setColumnStretch(2, 3) lay.setColumnStretch(4, 3) lay.setRowStretch(0, 3) lay.setRowStretch(2, 3) lay.setRowStretch(4, 3)
def __init__(self): super().__init__() layout = QGridLayout() self.setLayout(layout) self.status = QLabel('Click "Start"', self) self.play_btn = QPushButton("Start", self) self.abort_btn = QPushButton("Abort!", self) self.reset_btn = QPushButton("Reset", self) self.progress_bar = QProgressBar() layout.addWidget(self.play_btn, 0, 0) layout.addWidget(self.reset_btn, 0, 1) layout.addWidget(self.abort_btn, 0, 2) layout.addWidget(self.status, 0, 3) layout.setColumnStretch(3, 1) layout.addWidget(self.progress_bar, 1, 0, 1, 4)
def __init__(self, parent, batch_manager): QWidget.__init__(self, parent) self.calculation_manager = batch_manager self.whole_progress = QProgressBar(self) self.whole_progress.setMinimum(0) self.whole_progress.setMaximum(1) self.whole_progress.setFormat("%v of %m") self.whole_progress.setTextVisible(True) self.part_progress = QProgressBar(self) self.part_progress.setMinimum(0) self.part_progress.setMaximum(1) self.part_progress.setFormat("%v of %m") self.whole_label = QLabel("All batch progress:", self) self.part_label = QLabel("Single batch progress:", self) self.logs = ExceptionList(self) self.logs.setToolTip("Logs") self.task_que = QListWidget() self.process_num_timer = QTimer() self.process_num_timer.setInterval(1000) self.process_num_timer.setSingleShot(True) self.process_num_timer.timeout.connect(self.change_number_of_workers) self.number_of_process = QSpinBox(self) self.number_of_process.setRange(1, multiprocessing.cpu_count()) self.number_of_process.setValue(1) self.number_of_process.setToolTip( "Number of process used in batch calculation") self.number_of_process.valueChanged.connect( self.process_num_timer_start) layout = QGridLayout() layout.addWidget(self.whole_label, 0, 0, Qt.AlignRight) layout.addWidget(self.whole_progress, 0, 1, 1, 2) layout.addWidget(self.part_label, 1, 0, Qt.AlignRight) layout.addWidget(self.part_progress, 1, 1, 1, 2) lab = QLabel("Number of process:") lab.setToolTip("Number of process used in batch calculation") layout.addWidget(lab, 2, 0) layout.addWidget(self.number_of_process, 2, 1) layout.addWidget(self.logs, 3, 0, 1, 3) layout.addWidget(self.task_que, 0, 4, 0, 1) layout.setColumnMinimumWidth(2, 10) layout.setColumnStretch(2, 1) self.setLayout(layout) self.preview_timer = QTimer() self.preview_timer.setInterval(1000) self.preview_timer.timeout.connect(self.update_info)
def _setupUi(self): self.label_description = QLabel( '<h2>'+self.norm_config['label']+'</h2>', self) self.label_description.setAlignment(Qt.AlignCenter) self.label_time = QLabel('<h2>T = '+str(self.time)+'ms</h2>', self) self.label_time.setAlignment(Qt.AlignCenter) self.strengths = self._setupStrengthWidget() self.orbit = self._setupOrbitWidget() self.tune = self._setupTuneWidget() self.chrom = self._setupChromWidget() self.bt_apply = QPushButton(qta.icon('fa5s.angle-right'), '', self) self.bt_apply.setToolTip('Apply Changes to Machine') self.bt_apply.setStyleSheet('icon-size: 30px 30px;') self.bt_apply.clicked.connect(self._updateRampConfig) cw = QWidget() lay = QGridLayout() lay.setVerticalSpacing(10) lay.setHorizontalSpacing(10) lay.addWidget(self.label_description, 0, 0, 1, 2) lay.addWidget(self.label_time, 1, 0, 1, 2) lay.addWidget(self.strengths, 2, 0, 4, 1) lay.addWidget(self.orbit, 2, 1) lay.addWidget(self.tune, 3, 1) lay.addWidget(self.chrom, 4, 1) lay.addWidget(self.bt_apply, 5, 1) lay.setColumnStretch(0, 2) lay.setColumnStretch(1, 2) lay.setRowStretch(0, 2) lay.setRowStretch(1, 2) lay.setRowStretch(2, 8) lay.setRowStretch(3, 8) lay.setRowStretch(4, 8) lay.setRowStretch(5, 1) cw.setLayout(lay) cw.setStyleSheet(""" QGroupBox::title{ subcontrol-origin: margin; subcontrol-position: top center; padding: 0 2px 0 2px;}""") cw.setFocusPolicy(Qt.StrongFocus) self.setCentralWidget(cw)
def _setupUi(self): gbox_feedback = self._setupFBSettingsWidget() gbox_coefview = self._setupCoefficientsViewWidget() gbox_coefedit = self._setupCoefficientsEditWidget() lay = QGridLayout(self) lay.setAlignment(Qt.AlignLeft | Qt.AlignTop) lay.setVerticalSpacing(9) lay.setHorizontalSpacing(15) lay.addWidget(gbox_coefedit, 0, 0, 1, 2) lay.addWidget(gbox_feedback, 1, 0) if not self.dev_pref.endswith('-L'): gbox_bun_clean = self._setupBCSettingsWidget() lay.addWidget(gbox_bun_clean, 1, 1) lay.addWidget(gbox_coefview, 0, 2, 2, 1) lay.setColumnStretch(0, 2) lay.setColumnStretch(2, 1)
class InfoWidget(QWidget): """Display basic file information in a table (two columns). Parameters ---------- values : dict Each key/value pair in this dict will be displayed in a row, separated by a colon. """ def __init__(self, values=None): super().__init__() vbox = QVBoxLayout(self) self.grid = QGridLayout() self.grid.setColumnStretch(1, 1) vbox.addLayout(self.grid) vbox.addStretch(1) self.set_values(values) def set_values(self, values=None): """Set values (and overwrite existing values). Parameters ---------- values : dict Each key/value pair in this dict will be displayed in a row, separated by a colon. """ self.clear() if values: for row, (key, value) in enumerate(values.items()): left = QLabel(str(key) + ":") right = QLabel(str(value)) right.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed) self.grid.addWidget(left, row, 0) self.grid.addWidget(right, row, 1) def clear(self): """Clear all values. """ item = self.grid.takeAt(0) while item: item.widget().deleteLater() del item item = self.grid.takeAt(0)
def _setupUi(self): cw = QWidget() self.setCentralWidget(cw) label = QLabel('<h3>ID Control Window</h3>', self, alignment=Qt.AlignCenter) label.setStyleSheet('QLabel{min-height: 3em; max-height: 3em;}') self.label_mov1 = QLabel(self) self.label_mov1.setVisible(False) self.label_mov1.setStyleSheet( 'QLabel{min-height: 3em; max-height: 3em;}') self.label_mov2 = QLabel(self) self.label_mov2.setVisible(False) self.label_mov2.setStyleSheet( 'QLabel{min-height: 3em; max-height: 3em;}') self.movie_mov = QMovie(_os.path.join( _os.path.abspath(_os.path.dirname(__file__)), 'hula.gif')) self.movie_mov.setScaledSize(QSize(50, 50)) self.label_mov1.setMovie(self.movie_mov) self.label_mov2.setMovie(self.movie_mov) self._gbox_apu = QGroupBox('APU', self) self._gbox_apu.setLayout(self._setupAPULayout()) lay = QGridLayout(cw) lay.addWidget(self.label_mov1, 0, 0) lay.addWidget(label, 0, 1) lay.addWidget(self.label_mov2, 0, 2) lay.addWidget(self._gbox_apu, 1, 0, 1, 3) lay.setColumnStretch(0, 1) lay.setColumnStretch(1, 15) lay.setColumnStretch(2, 1)
def preview_layout(self, show_hidden_areas=False): """ Show the layout with placeholder texts using a QWidget. """ from spyder.utils.qthelpers import qapplication app = qapplication() widget = QWidget() layout = QGridLayout() for area in self._areas: label = QPlainTextEdit() label.setReadOnly(True) label.setPlainText("\n".join(area["plugin_ids"])) if area["visible"] or show_hidden_areas: layout.addWidget( label, area["row"], area["column"], area["row_span"], area["col_span"], ) # label.setVisible(area["visible"]) if area["default"]: label.setStyleSheet( "QPlainTextEdit {background-color: #ff0000;}") if not area["visible"]: label.setStyleSheet( "QPlainTextEdit {background-color: #eeeeee;}") for row, stretch in self._row_stretchs.items(): layout.setRowStretch(row, stretch) for col, stretch in self._column_stretchs.items(): layout.setColumnStretch(col, stretch) widget.setLayout(layout) widget.showMaximized() app.exec_()
class SkiviImageWindow(QMainWindow): def __init__(self, arr, mgr): QMainWindow.__init__(self) self.arr = arr self.mgr = mgr self.main_widget = QWidget() self.layout = QGridLayout(self.main_widget) self.setCentralWidget(self.main_widget) self.label = ImageLabel(self, arr) self.label_container = QFrame() self.label_container.setFrameShape(QFrame.StyledPanel | QFrame.Sunken) self.label_container.setLineWidth(1) self.label_container.layout = QGridLayout(self.label_container) self.label_container.layout.setContentsMargins(0, 0, 0, 0) self.label_container.layout.addWidget(self.label, 0, 0) self.layout.addWidget(self.label_container, 0, 0) self.mgr.add_window(self) self.main_widget.show() self.setWindowTitle('Skivi - The skimage viewer.') self.mixer_panel = MixerPanel(self.arr) self.layout.addWidget(self.mixer_panel, 0, 2) self.mixer_panel.show() self.mixer_panel.set_callback(self.refresh_image) self.rgbv_hist = QuadHistogram(self.arr) self.layout.addWidget(self.rgbv_hist, 0, 1) self.rgbv_hist.show() self.rgb_hsv_disp = RGBHSVDisplay() self.layout.addWidget(self.rgb_hsv_disp, 1, 0) self.rgb_hsv_disp.show() self.layout.setColumnStretch(0, 1) self.layout.setRowStretch(0, 1) self.save_file = QtWidgets.QPushButton('Save to File') self.save_file.clicked.connect(self.save_to_file) self.save_stack = QtWidgets.QPushButton('Save to Stack') self.save_stack.clicked.connect(self.save_to_stack) self.save_file.show() self.save_stack.show() self.layout.addWidget(self.save_stack, 1, 1) self.layout.addWidget(self.save_file, 1, 2) def closeEvent(self, event): # Allow window to be destroyed by removing any # references to it self.mgr.remove_window(self) def update_histograms(self): self.rgbv_hist.update_hists(self.arr) def refresh_image(self): self.label.update_image() self.update_histograms() def scale_mouse_pos(self, x, y): width = self.label.pm.width() height = self.label.pm.height() x_frac = 1. * x / width y_frac = 1. * y / height width = self.arr.shape[1] height = self.arr.shape[0] new_x = int(width * x_frac) new_y = int(height * y_frac) return(new_x, new_y) def label_mouseMoveEvent(self, evt): x = evt.x() y = evt.y() x, y = self.scale_mouse_pos(x, y) # handle tracking out of array bounds maxw = self.arr.shape[1] maxh = self.arr.shape[0] if x >= maxw or y >= maxh or x < 0 or y < 0: r = g = b = h = s = v = '' else: r = self.arr[y, x, 0] g = self.arr[y, x, 1] b = self.arr[y, x, 2] h, s, v = self.mixer_panel.mixer.rgb_2_hsv_pixel(r, g, b) self.rgb_hsv_disp.update_vals((x, y, r, g, b, h, s, v)) def save_to_stack(self): from ... import io img = self.arr.copy() io.push(img) msg = dedent(''' The image has been pushed to the io stack. Use io.pop() to retrieve the most recently pushed image.''') msglabel = QLabel(msg) dialog = QtWidgets.QDialog() ok = QtWidgets.QPushButton('OK', dialog) ok.clicked.connect(dialog.accept) ok.setDefault(True) dialog.layout = QGridLayout(dialog) dialog.layout.addWidget(msglabel, 0, 0, 1, 3) dialog.layout.addWidget(ok, 1, 1) dialog.exec_() def save_to_file(self): from ... import io filename = str(QtWidgets.QFileDialog.getSaveFileName()) if len(filename) == 0: return io.imsave(filename, self.arr)
class ThumbnailScrollBar(QFrame): """ A widget that manages the display of the FigureThumbnails that are created when a figure is sent to the IPython console by the kernel and that controls what is displayed in the FigureViewer. """ redirect_stdio = Signal(bool) def __init__(self, figure_viewer, parent=None, background_color=None): super(ThumbnailScrollBar, self).__init__(parent) self._thumbnails = [] self.background_color = background_color self.current_thumbnail = None self.set_figureviewer(figure_viewer) self.setup_gui() def setup_gui(self): """Setup the main layout of the widget.""" scrollarea = self.setup_scrollarea() up_btn, down_btn = self.setup_arrow_buttons() self.setFixedWidth(150) layout = QVBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) layout.addWidget(up_btn) layout.addWidget(scrollarea) layout.addWidget(down_btn) def setup_scrollarea(self): """Setup the scrollarea that will contain the FigureThumbnails.""" self.view = QWidget() self.scene = QGridLayout(self.view) self.scene.setColumnStretch(0, 100) self.scene.setColumnStretch(2, 100) self.scrollarea = QScrollArea() self.scrollarea.setWidget(self.view) self.scrollarea.setWidgetResizable(True) self.scrollarea.setFrameStyle(0) self.scrollarea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.scrollarea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.scrollarea.setSizePolicy(QSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred)) # Set the vertical scrollbar explicitely : # This is required to avoid a "RuntimeError: no access to protected # functions or signals for objects not created from Python" in Linux. self.scrollarea.setVerticalScrollBar(QScrollBar()) return self.scrollarea def setup_arrow_buttons(self): """ Setup the up and down arrow buttons that are placed at the top and bottom of the scrollarea. """ # Get the height of the up/down arrow of the default vertical # scrollbar : vsb = self.scrollarea.verticalScrollBar() style = vsb.style() opt = QStyleOptionSlider() vsb.initStyleOption(opt) vsb_up_arrow = style.subControlRect( QStyle.CC_ScrollBar, opt, QStyle.SC_ScrollBarAddLine, self) # Setup the up and down arrow button : up_btn = up_btn = QPushButton(icon=ima.icon('last_edit_location')) up_btn.setFlat(True) up_btn.setFixedHeight(vsb_up_arrow.size().height()) up_btn.clicked.connect(self.go_up) down_btn = QPushButton(icon=ima.icon('folding.arrow_down_on')) down_btn.setFlat(True) down_btn.setFixedHeight(vsb_up_arrow.size().height()) down_btn.clicked.connect(self.go_down) return up_btn, down_btn def set_figureviewer(self, figure_viewer): """Set the bamespace for the FigureViewer.""" self.figure_viewer = figure_viewer # ---- Save Figure def save_all_figures_as(self): """Save all the figures to a file.""" self.redirect_stdio.emit(False) dirname = getexistingdirectory(self, caption='Save all figures', basedir=getcwd_or_home()) self.redirect_stdio.emit(True) if dirname: return self.save_all_figures_todir(dirname) def save_all_figures_todir(self, dirname): """Save all figure in dirname.""" fignames = [] for thumbnail in self._thumbnails: fig = thumbnail.canvas.fig fmt = thumbnail.canvas.fmt fext = {'image/png': '.png', 'image/jpeg': '.jpg', 'image/svg+xml': '.svg'}[fmt] figname = get_unique_figname(dirname, 'Figure', fext) save_figure_tofile(fig, fmt, figname) fignames.append(figname) return fignames def save_current_figure_as(self): """Save the currently selected figure.""" if self.current_thumbnail is not None: self.save_figure_as(self.current_thumbnail.canvas.fig, self.current_thumbnail.canvas.fmt) def save_figure_as(self, fig, fmt): """Save the figure to a file.""" fext, ffilt = { 'image/png': ('.png', 'PNG (*.png)'), 'image/jpeg': ('.jpg', 'JPEG (*.jpg;*.jpeg;*.jpe;*.jfif)'), 'image/svg+xml': ('.svg', 'SVG (*.svg);;PNG (*.png)')}[fmt] figname = get_unique_figname(getcwd_or_home(), 'Figure', fext) self.redirect_stdio.emit(False) fname, fext = getsavefilename( parent=self.parent(), caption='Save Figure', basedir=figname, filters=ffilt, selectedfilter='', options=None) self.redirect_stdio.emit(True) if fname: save_figure_tofile(fig, fmt, fname) # ---- Thumbails Handlers def add_thumbnail(self, fig, fmt): thumbnail = FigureThumbnail(background_color=self.background_color) thumbnail.canvas.load_figure(fig, fmt) # Scale the thumbnail size, while respecting the figure # dimension ratio. fwidth = thumbnail.canvas.fwidth fheight = thumbnail.canvas.fheight max_length = 100 if fwidth/fheight > 1: canvas_width = max_length canvas_height = canvas_width / fwidth * fheight else: canvas_height = max_length canvas_width = canvas_height / fheight * fwidth thumbnail.canvas.setFixedSize(canvas_width, canvas_height) thumbnail.sig_canvas_clicked.connect(self.set_current_thumbnail) thumbnail.sig_remove_figure.connect(self.remove_thumbnail) thumbnail.sig_save_figure.connect(self.save_figure_as) self._thumbnails.append(thumbnail) self.scene.setRowStretch(self.scene.rowCount()-1, 0) self.scene.addWidget(thumbnail, self.scene.rowCount()-1, 1) self.scene.setRowStretch(self.scene.rowCount(), 100) self.set_current_thumbnail(thumbnail) def remove_current_thumbnail(self): """Remove the currently selected thumbnail.""" if self.current_thumbnail is not None: self.remove_thumbnail(self.current_thumbnail) def remove_all_thumbnails(self): """Remove all thumbnails.""" for thumbnail in self._thumbnails: self.layout().removeWidget(thumbnail) thumbnail.sig_canvas_clicked.disconnect() thumbnail.sig_remove_figure.disconnect() thumbnail.sig_save_figure.disconnect() thumbnail.deleteLater() self._thumbnails = [] self.current_thumbnail = None self.figure_viewer.figcanvas.clear_canvas() def remove_thumbnail(self, thumbnail): """Remove thumbnail.""" if thumbnail in self._thumbnails: index = self._thumbnails.index(thumbnail) self._thumbnails.remove(thumbnail) self.layout().removeWidget(thumbnail) thumbnail.deleteLater() thumbnail.sig_canvas_clicked.disconnect() thumbnail.sig_remove_figure.disconnect() thumbnail.sig_save_figure.disconnect() # Select a new thumbnail if any : if thumbnail == self.current_thumbnail: if len(self._thumbnails) > 0: self.set_current_index(min(index, len(self._thumbnails)-1)) else: self.current_thumbnail = None self.figure_viewer.figcanvas.clear_canvas() def set_current_index(self, index): """Set the currently selected thumbnail by its index.""" self.set_current_thumbnail(self._thumbnails[index]) def get_current_index(self): """Return the index of the currently selected thumbnail.""" try: return self._thumbnails.index(self.current_thumbnail) except ValueError: return -1 def set_current_thumbnail(self, thumbnail): """Set the currently selected thumbnail.""" self.current_thumbnail = thumbnail self.figure_viewer.load_figure( thumbnail.canvas.fig, thumbnail.canvas.fmt) for thumbnail in self._thumbnails: thumbnail.highlight_canvas(thumbnail == self.current_thumbnail) def go_previous_thumbnail(self): """Select the thumbnail previous to the currently selected one.""" if self.current_thumbnail is not None: index = self._thumbnails.index(self.current_thumbnail) - 1 index = index if index >= 0 else len(self._thumbnails) - 1 self.set_current_index(index) self.scroll_to_item(index) def go_next_thumbnail(self): """Select thumbnail next to the currently selected one.""" if self.current_thumbnail is not None: index = self._thumbnails.index(self.current_thumbnail) + 1 index = 0 if index >= len(self._thumbnails) else index self.set_current_index(index) self.scroll_to_item(index) def scroll_to_item(self, index): """Scroll to the selected item of ThumbnailScrollBar.""" spacing_between_items = self.scene.verticalSpacing() height_view = self.scrollarea.viewport().height() height_item = self.scene.itemAt(index).sizeHint().height() height_view_excluding_item = max(0, height_view - height_item) height_of_top_items = spacing_between_items for i in range(index): item = self.scene.itemAt(i) height_of_top_items += item.sizeHint().height() height_of_top_items += spacing_between_items pos_scroll = height_of_top_items - height_view_excluding_item // 2 vsb = self.scrollarea.verticalScrollBar() vsb.setValue(pos_scroll) # ---- ScrollBar Handlers def go_up(self): """Scroll the scrollbar of the scrollarea up by a single step.""" vsb = self.scrollarea.verticalScrollBar() vsb.setValue(int(vsb.value() - vsb.singleStep())) def go_down(self): """Scroll the scrollbar of the scrollarea down by a single step.""" vsb = self.scrollarea.verticalScrollBar() vsb.setValue(int(vsb.value() + vsb.singleStep()))
def setup(self): """Setup the ShortcutEditor with the provided arguments.""" # Widgets icon_info = HelperToolButton() icon_info.setIcon(get_std_icon('MessageBoxInformation')) layout_icon_info = QVBoxLayout() layout_icon_info.setContentsMargins(0, 0, 0, 0) layout_icon_info.setSpacing(0) layout_icon_info.addWidget(icon_info) layout_icon_info.addStretch(100) self.label_info = QLabel() self.label_info.setText( _("Press the new shortcut and select 'Ok' to confirm, " "click 'Cancel' to revert to the previous state, " "or use 'Clear' to unbind the command from a shortcut.")) self.label_info.setAlignment(Qt.AlignTop | Qt.AlignLeft) self.label_info.setWordWrap(True) layout_info = QHBoxLayout() layout_info.setContentsMargins(0, 0, 0, 0) layout_info.addLayout(layout_icon_info) layout_info.addWidget(self.label_info) layout_info.setStretch(1, 100) self.label_current_sequence = QLabel(_("Current shortcut:")) self.text_current_sequence = QLabel(self.current_sequence) self.label_new_sequence = QLabel(_("New shortcut:")) self.text_new_sequence = ShortcutLineEdit(self) self.text_new_sequence.setPlaceholderText(_("Press shortcut.")) self.helper_button = HelperToolButton() self.helper_button.setIcon(QIcon()) self.label_warning = QLabel() self.label_warning.setWordWrap(True) self.label_warning.setAlignment(Qt.AlignTop | Qt.AlignLeft) self.button_default = QPushButton(_('Default')) self.button_ok = QPushButton(_('Ok')) self.button_ok.setEnabled(False) self.button_clear = QPushButton(_('Clear')) self.button_cancel = QPushButton(_('Cancel')) button_box = QHBoxLayout() button_box.addWidget(self.button_default) button_box.addStretch(100) button_box.addWidget(self.button_ok) button_box.addWidget(self.button_clear) button_box.addWidget(self.button_cancel) # New Sequence button box self.btn_clear_sequence = create_toolbutton( self, icon=ima.icon('editclear'), tip=_("Clear all entered key sequences"), triggered=self.clear_new_sequence) self.button_back_sequence = create_toolbutton( self, icon=ima.icon('ArrowBack'), tip=_("Remove last key sequence entered"), triggered=self.back_new_sequence) newseq_btnbar = QHBoxLayout() newseq_btnbar.setSpacing(0) newseq_btnbar.setContentsMargins(0, 0, 0, 0) newseq_btnbar.addWidget(self.button_back_sequence) newseq_btnbar.addWidget(self.btn_clear_sequence) # Setup widgets self.setWindowTitle(_('Shortcut: {0}').format(self.name)) self.helper_button.setToolTip('') style = """ QToolButton { margin:1px; border: 0px solid grey; padding:0px; border-radius: 0px; }""" self.helper_button.setStyleSheet(style) icon_info.setToolTip('') icon_info.setStyleSheet(style) # Layout layout_sequence = QGridLayout() layout_sequence.setContentsMargins(0, 0, 0, 0) layout_sequence.addLayout(layout_info, 0, 0, 1, 4) layout_sequence.addItem(QSpacerItem(15, 15), 1, 0, 1, 4) layout_sequence.addWidget(self.label_current_sequence, 2, 0) layout_sequence.addWidget(self.text_current_sequence, 2, 2) layout_sequence.addWidget(self.label_new_sequence, 3, 0) layout_sequence.addWidget(self.helper_button, 3, 1) layout_sequence.addWidget(self.text_new_sequence, 3, 2) layout_sequence.addLayout(newseq_btnbar, 3, 3) layout_sequence.addWidget(self.label_warning, 4, 2, 1, 2) layout_sequence.setColumnStretch(2, 100) layout_sequence.setRowStretch(4, 100) layout = QVBoxLayout() layout.addLayout(layout_sequence) layout.addSpacing(5) layout.addLayout(button_box) self.setLayout(layout) # Signals self.button_ok.clicked.connect(self.accept_override) self.button_clear.clicked.connect(self.unbind_shortcut) self.button_cancel.clicked.connect(self.reject) self.button_default.clicked.connect(self.set_sequence_to_default) # Set all widget to no focus so that we can register <Tab> key # press event. widgets = ( self.label_warning, self.helper_button, self.text_new_sequence, self.button_clear, self.button_default, self.button_cancel, self.button_ok, self.btn_clear_sequence, self.button_back_sequence) for w in widgets: w.setFocusPolicy(Qt.NoFocus) w.clearFocus()
def setup_page(self): self.ICON = ima.icon('eyedropper') names = self.get_option("names") try: names.pop(names.index(u'Custom')) except ValueError: pass custom_names = self.get_option("custom_names", []) # Interface options theme_group = QGroupBox(_("Main interface")) # Interface Widgets ui_themes = ['Automatic', 'Light', 'Dark'] ui_theme_choices = list(zip(ui_themes, [ui_theme.lower() for ui_theme in ui_themes])) ui_theme_combo = self.create_combobox(_('Interface theme'), ui_theme_choices, 'ui_theme', restart=True) styles = [str(txt) for txt in list(QStyleFactory.keys())] # Don't offer users the possibility to change to a different # style in Gtk-based desktops # Fixes Issue 2036 if is_gtk_desktop() and ('GTK+' in styles): styles = ['GTK+'] choices = list(zip(styles, [style.lower() for style in styles])) style_combo = self.create_combobox(_('Qt windows style'), choices, 'windows_style', default=self.main.default_style) self.style_combobox = style_combo.combobox themes = ['Spyder 2', 'Spyder 3'] icon_choices = list(zip(themes, [theme.lower() for theme in themes])) icons_combo = self.create_combobox(_('Icon theme'), icon_choices, 'icon_theme', restart=True) theme_comboboxes_layout = QGridLayout() theme_comboboxes_layout.addWidget(ui_theme_combo.label, 0, 0) theme_comboboxes_layout.addWidget(ui_theme_combo.combobox, 0, 1) theme_comboboxes_layout.addWidget(style_combo.label, 1, 0) theme_comboboxes_layout.addWidget(self.style_combobox, 1, 1) theme_comboboxes_layout.addWidget(icons_combo.label, 2, 0) theme_comboboxes_layout.addWidget(icons_combo.combobox, 2, 1) theme_layout = QVBoxLayout() theme_layout.addLayout(theme_comboboxes_layout) theme_group.setLayout(theme_layout) # Syntax coloring options syntax_group = QGroupBox(_("Syntax highlighting theme")) # Syntax Widgets edit_button = QPushButton(_("Edit selected scheme")) create_button = QPushButton(_("Create new scheme")) self.delete_button = QPushButton(_("Delete scheme")) self.reset_button = QPushButton(_("Reset to defaults")) self.preview_editor = CodeEditor(self) self.stacked_widget = QStackedWidget(self) self.scheme_editor_dialog = SchemeEditor(parent=self, stack=self.stacked_widget) self.scheme_choices_dict = {} schemes_combobox_widget = self.create_combobox('', [('', '')], 'selected') self.schemes_combobox = schemes_combobox_widget.combobox # Syntax layout syntax_layout = QGridLayout(syntax_group) btns = [self.schemes_combobox, edit_button, self.reset_button, create_button, self.delete_button] for i, btn in enumerate(btns): syntax_layout.addWidget(btn, i, 1) syntax_layout.setColumnStretch(0, 1) syntax_layout.setColumnStretch(1, 2) syntax_layout.setColumnStretch(2, 1) syntax_layout.setContentsMargins(0, 12, 0, 12) # Fonts options fonts_group = QGroupBox(_("Fonts")) # Fonts widgets plain_text_font = self.create_fontgroup( option='font', title=_("Plain text"), fontfilters=QFontComboBox.MonospacedFonts, without_group=True) rich_text_font = self.create_fontgroup( option='rich_font', title=_("Rich text"), without_group=True) # Fonts layouts fonts_layout = QGridLayout() fonts_layout.addWidget(plain_text_font.fontlabel, 0, 0) fonts_layout.addWidget(plain_text_font.fontbox, 0, 1) fonts_layout.addWidget(plain_text_font.sizelabel, 0, 2) fonts_layout.addWidget(plain_text_font.sizebox, 0, 3) fonts_layout.addWidget(rich_text_font.fontlabel, 1, 0) fonts_layout.addWidget(rich_text_font.fontbox, 1, 1) fonts_layout.addWidget(rich_text_font.sizelabel, 1, 2) fonts_layout.addWidget(rich_text_font.sizebox, 1, 3) fonts_group.setLayout(fonts_layout) # Left options layout options_layout = QVBoxLayout() options_layout.addWidget(theme_group) options_layout.addWidget(syntax_group) options_layout.addWidget(fonts_group) # Right preview layout preview_group = QGroupBox(_("Preview")) preview_layout = QVBoxLayout() preview_layout.addWidget(self.preview_editor) preview_group.setLayout(preview_layout) # Combined layout combined_layout = QGridLayout() combined_layout.setRowStretch(0, 1) combined_layout.setColumnStretch(1, 100) combined_layout.addLayout(options_layout, 0, 0) combined_layout.addWidget(preview_group, 0, 1) self.setLayout(combined_layout) # Signals and slots create_button.clicked.connect(self.create_new_scheme) edit_button.clicked.connect(self.edit_scheme) self.reset_button.clicked.connect(self.reset_to_default) self.delete_button.clicked.connect(self.delete_scheme) self.schemes_combobox.currentIndexChanged.connect(self.update_preview) self.schemes_combobox.currentIndexChanged.connect(self.update_buttons) # Setup for name in names: self.scheme_editor_dialog.add_color_scheme_stack(name) for name in custom_names: self.scheme_editor_dialog.add_color_scheme_stack(name, custom=True) self.update_combobox() self.update_preview() self.update_qt_style_combobox()
def setup_page(self): self.ICON = ima.icon('genprefs') newcb = self.create_checkbox # --- Interface general_group = QGroupBox(_("General")) languages = LANGUAGE_CODES.items() language_choices = sorted([(val, key) for key, val in languages]) language_combo = self.create_combobox(_('Language:'), language_choices, 'interface_language', restart=True) opengl_options = ['Automatic', 'Desktop', 'Software', 'GLES'] opengl_choices = list(zip(opengl_options, [c.lower() for c in opengl_options])) opengl_combo = self.create_combobox(_('Rendering engine:'), opengl_choices, 'opengl', restart=True) single_instance_box = newcb(_("Use a single instance"), 'single_instance', tip=_("Set this to open external<br> " "Python files in an already running " "instance (Requires a restart)")) prompt_box = newcb(_("Prompt when exiting"), 'prompt_on_exit') popup_console_box = newcb(_("Show internal Spyder errors to report " "them to Github"), 'show_internal_errors') check_updates = newcb(_("Check for updates on startup"), 'check_updates_on_startup') # Decide if it's possible to activate or not single instance mode if running_in_mac_app(): self.set_option("single_instance", True) single_instance_box.setEnabled(False) comboboxes_advanced_layout = QHBoxLayout() cbs_adv_grid = QGridLayout() cbs_adv_grid.addWidget(language_combo.label, 0, 0) cbs_adv_grid.addWidget(language_combo.combobox, 0, 1) cbs_adv_grid.addWidget(opengl_combo.label, 1, 0) cbs_adv_grid.addWidget(opengl_combo.combobox, 1, 1) comboboxes_advanced_layout.addLayout(cbs_adv_grid) comboboxes_advanced_layout.addStretch(1) general_layout = QVBoxLayout() general_layout.addLayout(comboboxes_advanced_layout) general_layout.addWidget(single_instance_box) general_layout.addWidget(prompt_box) general_layout.addWidget(popup_console_box) general_layout.addWidget(check_updates) general_group.setLayout(general_layout) # --- Theme interface_group = QGroupBox(_("Interface")) vertdock_box = newcb(_("Vertical title bars in panes"), 'vertical_dockwidget_titlebars') verttabs_box = newcb(_("Vertical tabs in panes"), 'vertical_tabs') animated_box = newcb(_("Animated toolbars and panes"), 'animated_docks') tear_off_box = newcb(_("Tear off menus"), 'tear_off_menus', tip=_("Set this to detach any<br> " "menu from the main window")) margin_box = newcb(_("Custom margin for panes:"), 'use_custom_margin') margin_spin = self.create_spinbox("", _("pixels"), 'custom_margin', 0, 0, 30) margin_box.toggled.connect(margin_spin.spinbox.setEnabled) margin_box.toggled.connect(margin_spin.slabel.setEnabled) margin_spin.spinbox.setEnabled(self.get_option('use_custom_margin')) margin_spin.slabel.setEnabled(self.get_option('use_custom_margin')) cursor_box = newcb(_("Cursor blinking:"), 'use_custom_cursor_blinking') cursor_spin = self.create_spinbox( "", _("ms"), 'custom_cursor_blinking', default=QApplication.cursorFlashTime(), min_=0, max_=5000, step=100) cursor_box.toggled.connect(cursor_spin.spinbox.setEnabled) cursor_box.toggled.connect(cursor_spin.slabel.setEnabled) cursor_spin.spinbox.setEnabled( self.get_option('use_custom_cursor_blinking')) cursor_spin.slabel.setEnabled( self.get_option('use_custom_cursor_blinking')) margins_cursor_layout = QGridLayout() margins_cursor_layout.addWidget(margin_box, 0, 0) margins_cursor_layout.addWidget(margin_spin.spinbox, 0, 1) margins_cursor_layout.addWidget(margin_spin.slabel, 0, 2) margins_cursor_layout.addWidget(cursor_box, 1, 0) margins_cursor_layout.addWidget(cursor_spin.spinbox, 1, 1) margins_cursor_layout.addWidget(cursor_spin.slabel, 1, 2) margins_cursor_layout.setColumnStretch(2, 100) # Layout interface interface_layout = QVBoxLayout() interface_layout.addWidget(vertdock_box) interface_layout.addWidget(verttabs_box) interface_layout.addWidget(animated_box) interface_layout.addWidget(tear_off_box) interface_layout.addLayout(margins_cursor_layout) interface_group.setLayout(interface_layout) # --- Status bar sbar_group = QGroupBox(_("Status bar")) show_status_bar = newcb(_("Show status bar"), 'show_status_bar') memory_box = newcb(_("Show memory usage every"), 'memory_usage/enable', tip=self.main.mem_status.toolTip()) memory_spin = self.create_spinbox("", _(" ms"), 'memory_usage/timeout', min_=100, max_=1000000, step=100) memory_box.toggled.connect(memory_spin.setEnabled) memory_spin.setEnabled(self.get_option('memory_usage/enable')) memory_box.setEnabled(self.main.mem_status.is_supported()) memory_spin.setEnabled(self.main.mem_status.is_supported()) cpu_box = newcb(_("Show CPU usage every"), 'cpu_usage/enable', tip=self.main.cpu_status.toolTip()) cpu_spin = self.create_spinbox("", _(" ms"), 'cpu_usage/timeout', min_=100, max_=1000000, step=100) cpu_box.toggled.connect(cpu_spin.setEnabled) cpu_spin.setEnabled(self.get_option('cpu_usage/enable')) cpu_box.setEnabled(self.main.cpu_status.is_supported()) cpu_spin.setEnabled(self.main.cpu_status.is_supported()) status_bar_o = self.get_option('show_status_bar') show_status_bar.toggled.connect(memory_box.setEnabled) show_status_bar.toggled.connect(memory_spin.setEnabled) show_status_bar.toggled.connect(cpu_box.setEnabled) show_status_bar.toggled.connect(cpu_spin.setEnabled) memory_box.setEnabled(status_bar_o) memory_spin.setEnabled(status_bar_o) cpu_box.setEnabled(status_bar_o) cpu_spin.setEnabled(status_bar_o) # Layout status bar cpu_memory_layout = QGridLayout() cpu_memory_layout.addWidget(memory_box, 0, 0) cpu_memory_layout.addWidget(memory_spin, 0, 1) cpu_memory_layout.addWidget(cpu_box, 1, 0) cpu_memory_layout.addWidget(cpu_spin, 1, 1) sbar_layout = QVBoxLayout() sbar_layout.addWidget(show_status_bar) sbar_layout.addLayout(cpu_memory_layout) sbar_group.setLayout(sbar_layout) # --- Screen resolution Group (hidpi) screen_resolution_group = QGroupBox(_("Screen resolution")) screen_resolution_bg = QButtonGroup(screen_resolution_group) screen_resolution_label = QLabel(_("Configuration for high DPI " "screens<br><br>" "Please see " "<a href=\"{0}\">{0}</a><> " "for more information about " "these options (in " "English).").format(HDPI_QT_PAGE)) screen_resolution_label.setWordWrap(True) normal_radio = self.create_radiobutton( _("Normal"), 'normal_screen_resolution', button_group=screen_resolution_bg) auto_scale_radio = self.create_radiobutton( _("Enable auto high DPI scaling"), 'high_dpi_scaling', button_group=screen_resolution_bg, tip=_("Set this for high DPI displays"), restart=True) custom_scaling_radio = self.create_radiobutton( _("Set a custom high DPI scaling"), 'high_dpi_custom_scale_factor', button_group=screen_resolution_bg, tip=_("Set this for high DPI displays when " "auto scaling does not work"), restart=True) custom_scaling_edit = self.create_lineedit( "", 'high_dpi_custom_scale_factors', tip=_("Enter values for different screens " "separated by semicolons ';', " "float values are supported"), alignment=Qt.Horizontal, regex=r"[0-9]+(?:\.[0-9]*)(;[0-9]+(?:\.[0-9]*))*", restart=True) normal_radio.toggled.connect(custom_scaling_edit.setDisabled) auto_scale_radio.toggled.connect(custom_scaling_edit.setDisabled) custom_scaling_radio.toggled.connect(custom_scaling_edit.setEnabled) # Layout Screen resolution screen_resolution_layout = QVBoxLayout() screen_resolution_layout.addWidget(screen_resolution_label) screen_resolution_inner_layout = QGridLayout() screen_resolution_inner_layout.addWidget(normal_radio, 0, 0) screen_resolution_inner_layout.addWidget(auto_scale_radio, 1, 0) screen_resolution_inner_layout.addWidget(custom_scaling_radio, 2, 0) screen_resolution_inner_layout.addWidget(custom_scaling_edit, 2, 1) screen_resolution_layout.addLayout(screen_resolution_inner_layout) screen_resolution_group.setLayout(screen_resolution_layout) tabs = QTabWidget() tabs.addTab(self.create_tab(screen_resolution_group, interface_group), _("Interface")) tabs.addTab(self.create_tab(general_group, sbar_group), _("Advanced Settings")) vlayout = QVBoxLayout() vlayout.addWidget(tabs) self.setLayout(vlayout)
def setup_page(self): newcb = self.create_checkbox # --- Introspection --- # Basic features group basic_features_group = QGroupBox(_("Basic features")) completion_box = newcb(_("Enable code completion"), 'code_completion') goto_definition_box = newcb( _("Enable Go to definition"), 'jedi_definition', tip=_("If this option is enabled, left-clicking on\n" "an object name while pressing the {} key will go to\n" "that object's definition (if resolved).".format(self.CTRL))) follow_imports_box = newcb(_("Follow imports when going to a " "definition"), 'jedi_definition/follow_imports') show_signature_box = newcb(_("Show calltips"), 'jedi_signature_help') basic_features_layout = QVBoxLayout() basic_features_layout.addWidget(completion_box) basic_features_layout.addWidget(goto_definition_box) basic_features_layout.addWidget(follow_imports_box) basic_features_layout.addWidget(show_signature_box) basic_features_group.setLayout(basic_features_layout) # Advanced group advanced_group = QGroupBox(_("Advanced")) modules_textedit = self.create_textedit( _("Preload the following modules to make completion faster " "and more accurate:"), 'preload_modules' ) if is_dark_interface(): modules_textedit.textbox.setStyleSheet( "border: 1px solid #32414B;" ) advanced_layout = QVBoxLayout() advanced_layout.addWidget(modules_textedit) advanced_group.setLayout(advanced_layout) # --- Linting --- # Linting options linting_label = QLabel(_("Spyder can optionally highlight syntax " "errors and possible problems with your " "code in the editor.")) linting_label.setOpenExternalLinks(True) linting_label.setWordWrap(True) linting_check = self.create_checkbox( _("Enable basic linting"), 'pyflakes') linting_complexity_box = self.create_checkbox( _("Enable complexity linting with " "the Mccabe package"), 'mccabe') # Linting layout linting_layout = QVBoxLayout() linting_layout.addWidget(linting_label) linting_layout.addWidget(linting_check) linting_layout.addWidget(linting_complexity_box) linting_widget = QWidget() linting_widget.setLayout(linting_layout) # --- Code style tab --- # Code style label pep_url = ( '<a href="https://www.python.org/dev/peps/pep-0008">PEP 8</a>') code_style_codes_url = _( "<a href='http://pycodestyle.pycqa.org/en/stable" "/intro.html#error-codes'>pycodestyle error codes</a>") code_style_label = QLabel( _("Spyder can use pycodestyle to analyze your code for " "conformance to the {} convention. You can also " "manually show or hide specific warnings by their " "{}.").format(pep_url, code_style_codes_url)) code_style_label.setOpenExternalLinks(True) code_style_label.setWordWrap(True) # Code style checkbox code_style_check = self.create_checkbox( _("Enable code style linting"), 'pycodestyle') # Code style options self.code_style_filenames_match = self.create_lineedit( _("Only check filenames matching these patterns:"), 'pycodestyle/filename', alignment=Qt.Horizontal, word_wrap=False, placeholder=_("Check Python files: *.py")) self.code_style_exclude = self.create_lineedit( _("Exclude files or directories matching these patterns:"), 'pycodestyle/exclude', alignment=Qt.Horizontal, word_wrap=False, placeholder=_("Exclude all test files: (?!test_).*\\.py")) code_style_select = self.create_lineedit( _("Show the following errors or warnings:").format( code_style_codes_url), 'pycodestyle/select', alignment=Qt.Horizontal, word_wrap=False, placeholder=_("Example codes: E113, W391")) code_style_ignore = self.create_lineedit( _("Ignore the following errors or warnings:"), 'pycodestyle/ignore', alignment=Qt.Horizontal, word_wrap=False, placeholder=_("Example codes: E201, E303")) code_style_max_line_length = self.create_spinbox( _("Maximum allowed line length:"), None, 'pycodestyle/max_line_length', min_=10, max_=500, step=1, tip=_("Default is 79")) # Code style layout code_style_g_layout = QGridLayout() code_style_g_layout.addWidget( self.code_style_filenames_match.label, 1, 0) code_style_g_layout.addWidget( self.code_style_filenames_match.textbox, 1, 1) code_style_g_layout.addWidget(self.code_style_exclude.label, 2, 0) code_style_g_layout.addWidget(self.code_style_exclude.textbox, 2, 1) code_style_g_layout.addWidget(code_style_select.label, 3, 0) code_style_g_layout.addWidget(code_style_select.textbox, 3, 1) code_style_g_layout.addWidget(code_style_ignore.label, 4, 0) code_style_g_layout.addWidget(code_style_ignore.textbox, 4, 1) code_style_g_layout.addWidget(code_style_max_line_length.plabel, 5, 0) code_style_g_layout.addWidget( code_style_max_line_length.spinbox, 5, 1) # Set Code style options enabled/disabled code_style_g_widget = QWidget() code_style_g_widget.setLayout(code_style_g_layout) code_style_g_widget.setEnabled(self.get_option('pycodestyle')) code_style_check.toggled.connect(code_style_g_widget.setEnabled) # Code style layout code_style_layout = QVBoxLayout() code_style_layout.addWidget(code_style_label) code_style_layout.addWidget(code_style_check) code_style_layout.addWidget(code_style_g_widget) code_style_widget = QWidget() code_style_widget.setLayout(code_style_layout) # --- Docstring tab --- # Docstring style label numpy_url = ( "<a href='https://numpydoc.readthedocs.io/en/" "latest/format.html'>Numpy</a>") pep257_url = ( "<a href='https://www.python.org/dev/peps/pep-0257/'>PEP 257</a>") docstring_style_codes = _( "<a href='http://www.pydocstyle.org/en/stable" "/error_codes.html'>page</a>") docstring_style_label = QLabel( _("Here you can decide if you want to perform style analysis on " "your docstrings according to the {} or {} conventions. You can " "also decide if you want to show or ignore specific errors, " "according to the codes found on this {}.").format( numpy_url, pep257_url, docstring_style_codes)) docstring_style_label.setOpenExternalLinks(True) docstring_style_label.setWordWrap(True) # Docstring style checkbox docstring_style_check = self.create_checkbox( _("Enable docstring style linting"), 'pydocstyle') # Docstring style options docstring_style_convention = self.create_combobox( _("Choose the convention used to lint docstrings: "), (("Numpy", 'numpy'), ("PEP 257", 'pep257'), ("Custom", 'custom')), 'pydocstyle/convention') self.docstring_style_select = self.create_lineedit( _("Show the following errors:"), 'pydocstyle/select', alignment=Qt.Horizontal, word_wrap=False, placeholder=_("Example codes: D413, D414")) self.docstring_style_ignore = self.create_lineedit( _("Ignore the following errors:"), 'pydocstyle/ignore', alignment=Qt.Horizontal, word_wrap=False, placeholder=_("Example codes: D107, D402")) self.docstring_style_match = self.create_lineedit( _("Only check filenames matching these patterns:"), 'pydocstyle/match', alignment=Qt.Horizontal, word_wrap=False, placeholder=_("Skip test files: (?!test_).*\\.py")) self.docstring_style_match_dir = self.create_lineedit( _("Only check in directories matching these patterns:"), 'pydocstyle/match_dir', alignment=Qt.Horizontal, word_wrap=False, placeholder=_("Skip dot directories: [^\\.].*")) # Custom option handling docstring_style_convention.combobox.currentTextChanged.connect( self.setup_docstring_style_convention) current_convention = docstring_style_convention.combobox.currentText() self.setup_docstring_style_convention(current_convention) # Docstring style layout docstring_style_g_layout = QGridLayout() docstring_style_g_layout.addWidget( docstring_style_convention.label, 1, 0) docstring_style_g_layout.addWidget( docstring_style_convention.combobox, 1, 1) docstring_style_g_layout.addWidget( self.docstring_style_select.label, 2, 0) docstring_style_g_layout.addWidget( self.docstring_style_select.textbox, 2, 1) docstring_style_g_layout.addWidget( self.docstring_style_ignore.label, 3, 0) docstring_style_g_layout.addWidget( self.docstring_style_ignore.textbox, 3, 1) docstring_style_g_layout.addWidget( self.docstring_style_match.label, 4, 0) docstring_style_g_layout.addWidget( self.docstring_style_match.textbox, 4, 1) docstring_style_g_layout.addWidget( self.docstring_style_match_dir.label, 5, 0) docstring_style_g_layout.addWidget( self.docstring_style_match_dir.textbox, 5, 1) # Set Docstring style options enabled/disabled docstring_style_g_widget = QWidget() docstring_style_g_widget.setLayout(docstring_style_g_layout) docstring_style_g_widget.setEnabled(self.get_option('pydocstyle')) docstring_style_check.toggled.connect( docstring_style_g_widget.setEnabled) # Docstring style layout docstring_style_layout = QVBoxLayout() docstring_style_layout.addWidget(docstring_style_label) docstring_style_layout.addWidget(docstring_style_check) docstring_style_layout.addWidget(docstring_style_g_widget) docstring_style_widget = QWidget() docstring_style_widget.setLayout(docstring_style_layout) # --- Advanced tab --- # Advanced label advanced_label = QLabel( _("Please don't modify these values unless " "you know what you're doing!")) advanced_label.setWordWrap(True) advanced_label.setAlignment(Qt.AlignJustify) # Advanced options advanced_command_launch = self.create_lineedit( _("Command to launch the Python language server: "), 'advanced/command_launch', alignment=Qt.Horizontal, word_wrap=False) advanced_host = self.create_lineedit( _("IP Address and port to bind the server to: "), 'advanced/host', alignment=Qt.Horizontal, word_wrap=False) advanced_port = self.create_spinbox( ":", "", 'advanced/port', min_=1, max_=65535, step=1) # Advanced layout advanced_g_layout = QGridLayout() advanced_g_layout.addWidget(advanced_command_launch.label, 1, 0) advanced_g_layout.addWidget(advanced_command_launch.textbox, 1, 1) advanced_g_layout.addWidget(advanced_host.label, 2, 0) advanced_host_port_g_layout = QGridLayout() advanced_host_port_g_layout.addWidget(advanced_host.textbox, 1, 0) advanced_host_port_g_layout.addWidget(advanced_port.plabel, 1, 1) advanced_host_port_g_layout.addWidget(advanced_port.spinbox, 1, 2) advanced_g_layout.addLayout(advanced_host_port_g_layout, 2, 1) advanced_widget = QWidget() advanced_layout = QVBoxLayout() advanced_layout.addWidget(advanced_label) advanced_layout.addLayout(advanced_g_layout) advanced_widget.setLayout(advanced_layout) # --- Other servers tab --- # Section label servers_label = QLabel( _("Spyder uses the <a href=\"{lsp_url}\">Language Server " "Protocol</a> to provide code completion and linting " "for its Editor. Here, you can setup and configure LSP servers " "for languages other than Python, so Spyder can provide such " "features for those languages as well." ).format(lsp_url=LSP_URL)) servers_label.setOpenExternalLinks(True) servers_label.setWordWrap(True) servers_label.setAlignment(Qt.AlignJustify) # Servers table table_group = QGroupBox(_('Available servers:')) self.table = LSPServerTable(self, text_color=ima.MAIN_FG_COLOR) table_layout = QVBoxLayout() table_layout.addWidget(self.table) table_group.setLayout(table_layout) # Buttons self.reset_btn = QPushButton(_("Reset to default values")) self.new_btn = QPushButton(_("Set up a new server")) self.delete_btn = QPushButton(_("Delete currently selected server")) self.delete_btn.setEnabled(False) # Slots connected to buttons self.new_btn.clicked.connect(self.create_new_server) self.reset_btn.clicked.connect(self.reset_to_default) self.delete_btn.clicked.connect(self.delete_server) # Buttons layout btns = [self.new_btn, self.delete_btn, self.reset_btn] buttons_layout = QGridLayout() for i, btn in enumerate(btns): buttons_layout.addWidget(btn, i, 1) buttons_layout.setColumnStretch(0, 1) buttons_layout.setColumnStretch(1, 2) buttons_layout.setColumnStretch(2, 1) # Combined layout servers_widget = QWidget() servers_layout = QVBoxLayout() servers_layout.addSpacing(-10) servers_layout.addWidget(servers_label) servers_layout.addWidget(table_group) servers_layout.addSpacing(10) servers_layout.addLayout(buttons_layout) servers_widget.setLayout(servers_layout) # --- Tabs organization --- tabs = QTabWidget() tabs.addTab(self.create_tab(basic_features_group, advanced_group), _('Introspection')) tabs.addTab(self.create_tab(linting_widget), _('Linting')) tabs.addTab(self.create_tab(code_style_widget), _('Code style')) tabs.addTab(self.create_tab(docstring_style_widget), _('Docstring style')) tabs.addTab(self.create_tab(advanced_widget), _('Advanced')) tabs.addTab(self.create_tab(servers_widget), _('Other languages')) vlayout = QVBoxLayout() vlayout.addWidget(tabs) self.setLayout(vlayout)