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 __init__(self, parent): SpyderPluginWidget.__init__(self, parent) # Widgets self.stack = QStackedWidget(self) self.shellwidgets = {} # Layout layout = QGridLayout(self) layout.addWidget(self.stack) # Initialize plugin self.initialize_plugin()
def __init__(self, name, a, b, callback): QWidget.__init__(self) self.name = name self.callback = callback self.a = a self.b = b self.manually_triggered = False self.slider = QSlider() self.slider.setRange(0, 1000) self.slider.setValue(500) self.slider.valueChanged.connect(self.slider_changed) self.name_label = QLabel() self.name_label.setText(self.name) self.name_label.setAlignment(QtCore.Qt.AlignCenter) self.value_label = QLabel() self.value_label.setText('%2.2f' % (self.slider.value() * self.a + self.b)) self.value_label.setAlignment(QtCore.Qt.AlignCenter) self.layout = QGridLayout(self) self.layout.addWidget(self.name_label, 0, 0) self.layout.addWidget(self.slider, 1, 0, QtCore.Qt.AlignHCenter) self.layout.addWidget(self.value_label, 2, 0)
def __init__(self): # how connect super(buttonwidget, self).__init__() self.grid = QGridLayout() self.btnConnect = QPushButton("Connect") self.grid.addWidget(self.btnConnect, 0, 0, 1, 5) self.btnLock = QPushButton("Lock Cassette") self.grid.addWidget(self.btnLock, 1, 0, 1, 5) self.btnPurge = QPushButton("Purge") self.grid.addWidget(self.btnPurge, 2, 0, 1, 2) self.cbxPurgeType = QComboBox() self.cbxPurgeType.addItems(["Normal", "Extended", "Add Conditioner", "Custom"]) self.grid.addWidget(self.cbxPurgeType, 2, 2, 1, 2) self.txtNumPurge = QLineEdit() self.grid.addWidget(self.txtNumPurge, 2, 4, 1, 1) self.btnRecover = QPushButton("Recover") self.grid.addWidget(self.btnRecover, 3, 0, 1, 5) self.btnHelp = QPushButton("Help") self.grid.addWidget(self.btnHelp, 4, 0, 1, 5) self.setLayout(self.grid)
def __init__(self, parent, name, script="", filemodified=0): QWidget.__init__(self) self.parent = parent self.tabWidget = self.parent.ui.tabWidget self.gridlayout = QGridLayout(self) self._dirty = False self.initialize_editor() self.gridlayout.addWidget(self.editor) self.setAcceptDrops(True) self.filename = name self.filemodified = filemodified if self.is_file(): self.title = os.path.basename(name) # if self.equals_saved(): # self.filemodified = os.path.getmtime(self.filename) else: self.filename = "" self.title = name # Show this file in the self.editor self.editor.setText(script) self.clean_txt = self.saved() self.update_dirty() self.editor.keyPressEvent = self.key_press_event
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 _ask_overwrite(self): msg = QDialog() msg.setWindowTitle('Load overwrite') layout = QGridLayout() layout.addWidget(QLabel('Instrument %s already exists in memory. Overwrite this?'), 0, 0, 1, -1) buttons = [QPushButton(label) for label in ['Load and overwrite', 'Cancel Load', 'Load and rename to']] locations = [[1, 0], [1, 1], [2, 0]] self.overwrite_flag = 1 def overwriteCB(idx): self.overwrite_flag = idx msg.accept() for idx, button in enumerate(buttons): button.clicked.connect(lambda _, idx=idx: overwriteCB(idx)) layout.addWidget(button, locations[idx][0], locations[idx][1]) newname = QLineEdit() newname.editingFinished.connect(lambda: overwriteCB(2)) layout.addWidget(newname, 2, 1) msg.setLayout(layout) msg.exec_() newname = str(newname.text()) if not newname or newname in self.instruments: self.errormessage('Invalid instrument name. Cancelling load.') self.overwrite_flag = 1 return self.overwrite_flag, newname
def create_file_combobox(self, text, choices, option, default=NoDefault, tip=None, restart=False, filters=None, adjust_to_contents=False, default_line_edit=False): """choices: couples (name, key)""" combobox = FileComboBox(self, adjust_to_contents=adjust_to_contents, default_line_edit=default_line_edit) combobox.restart_required = restart combobox.label_text = text edit = combobox.lineEdit() edit.label_text = text edit.restart_required = restart self.lineedits[edit] = (option, default) if tip is not None: combobox.setToolTip(tip) combobox.addItems(choices) msg = _('Invalid file path') self.validate_data[edit] = (osp.isfile, msg) browse_btn = QPushButton(ima.icon('FileIcon'), '', self) browse_btn.setToolTip(_("Select file")) browse_btn.clicked.connect(lambda: self.select_file(edit, filters)) layout = QGridLayout() layout.addWidget(combobox, 0, 0, 0, 9) layout.addWidget(browse_btn, 0, 10) layout.setContentsMargins(0, 0, 0, 0) widget = QWidget(self) widget.combobox = combobox widget.browse_btn = browse_btn widget.setLayout(layout) return widget
class ImageWindow(QMainWindow): def __init__(self, arr, mgr): QMainWindow.__init__(self) self.setWindowTitle('skimage') self.mgr = mgr self.main_widget = QWidget() self.layout = QGridLayout(self.main_widget) self.setCentralWidget(self.main_widget) self.label = ImageLabel(self, arr) self.layout.addWidget(self.label, 0, 0) self.layout.addLayout self.mgr.add_window(self) self.main_widget.show() def closeEvent(self, event): # Allow window to be destroyed by removing any # references to it self.mgr.remove_window(self)
def _build_GUI(self, linelist, table_view): panel_layout = QGridLayout() panel_layout.setSizeConstraint(QLayout.SetMaximumSize) self.setLayout(panel_layout) # GUI cannot be completely defined in a .ui file. # It has to be built on-the-fly here. self.button_pane = QWidget() loadUi(os.path.join(os.path.dirname(__file__), "ui", "linelists_panel_buttons.ui"), self.button_pane) # internal signals do not use Hub infrastructure. self.button_pane.create_set_button.clicked.connect(self._create_set) self.button_pane.deselect_button.clicked.connect(table_view.clearSelection) # header with line list metadata. info = QTextBrowser() info.setMaximumHeight(100) info.setAutoFillBackground(True) info.setStyleSheet("background-color: rgb(230,230,230);") for comment in linelist.meta['comments']: info.append(comment) # populate color picker model = self.button_pane.combo_box_color.model() for cname in ID_COLORS: item = QStandardItem(cname) item.setForeground(ID_COLORS[cname]) item.setData(QColor(ID_COLORS[cname]), role=Qt.UserRole) model.appendRow(item) # set validators validator = QDoubleValidator() validator.setRange(0.05, 0.95, decimals=2) self.button_pane.height_textbox.setValidator(validator) validator = QDoubleValidator() validator.setRange(-1.e5, 1.e10, decimals=4) self.button_pane.redshift_textbox.setValidator(validator) model = self.button_pane.combo_box_z_units.model() for uname in ['z', 'km/s']: item = QStandardItem(uname) model.appendRow(item) # put it all together panel_layout.addWidget(info,0,0) panel_layout.addWidget(table_view,1,0) panel_layout.addWidget(self.button_pane,2,0)
def __init__(self, settings, parent=None): super().__init__(parent) self.settings = settings self.serialports = [] # port self.portLabel = QLabel(self.tr("COM Port:")) self.portComboBox = QComboBox() self.portLabel.setBuddy(self.portComboBox) self.refresh_comports(self.portComboBox) # baudrate self.baudrateLabel = QLabel(self.tr("Baudrate:")) self.baudrateComboBox = QComboBox() self.baudrateLabel.setBuddy(self.baudrateComboBox) for br in BAUDRATES: self.baudrateComboBox.addItem(str(br), br) # buttons self.dlgbuttons = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal) self.dlgbuttons.rejected.connect(self.reject) self.dlgbuttons.accepted.connect(self.accept) # layout layout = QGridLayout() layout.addWidget(self.portLabel, 0, 0) layout.addWidget(self.portComboBox, 0, 1) layout.addWidget(self.baudrateLabel, 1, 0) layout.addWidget(self.baudrateComboBox, 1, 1) layout.addWidget(self.dlgbuttons, 2, 0, 1, 2) self.setLayout(layout) self.setWindowTitle(self.tr("Serial Settings")) # settings defaults = { PORT_SETTING: "", BAUDRATE_SETTING: "115200" } self.tmp_settings = ConfigManager() self.tmp_settings.set_defaults(defaults) self.tmp_settings.set_many( {key: self.settings.get(key) for key in defaults.keys()} ) self.tmp_settings.add_handler(PORT_SETTING, self.portComboBox) self.tmp_settings.add_handler(BAUDRATE_SETTING, self.baudrateComboBox)
class IntelligentSlider(QWidget): ''' A slider that adds a 'name' attribute and calls a callback with 'name' as an argument to the registerd callback. This allows you to create large groups of sliders in a loop, but still keep track of the individual events It also prints a label below the slider. The range of the slider is hardcoded from zero - 1000, but it supports a conversion factor so you can scale the results''' def __init__(self, name, a, b, callback): QWidget.__init__(self) self.name = name self.callback = callback self.a = a self.b = b self.manually_triggered = False self.slider = QSlider() self.slider.setRange(0, 1000) self.slider.setValue(500) self.slider.valueChanged.connect(self.slider_changed) self.name_label = QLabel() self.name_label.setText(self.name) self.name_label.setAlignment(QtCore.Qt.AlignCenter) self.value_label = QLabel() self.value_label.setText('%2.2f' % (self.slider.value() * self.a + self.b)) self.value_label.setAlignment(QtCore.Qt.AlignCenter) self.layout = QGridLayout(self) self.layout.addWidget(self.name_label, 0, 0) self.layout.addWidget(self.slider, 1, 0, QtCore.Qt.AlignHCenter) self.layout.addWidget(self.value_label, 2, 0) # bind this to the valueChanged signal of the slider def slider_changed(self, val): val = self.val() self.value_label.setText(str(val)[:4]) if not self.manually_triggered: self.callback(self.name, val) def set_conv_fac(self, a, b): self.a = a self.b = b def set_value(self, val): self.manually_triggered = True self.slider.setValue(int((val - self.b) / self.a)) self.value_label.setText('%2.2f' % val) self.manually_triggered = False def val(self): return self.slider.value() * self.a + self.b
def __init__(self, arr, mgr): QMainWindow.__init__(self) self.setWindowTitle('skimage') self.mgr = mgr self.main_widget = QWidget() self.layout = QGridLayout(self.main_widget) self.setCentralWidget(self.main_widget) self.label = ImageLabel(self, arr) self.layout.addWidget(self.label, 0, 0) self.layout.addLayout self.mgr.add_window(self) self.main_widget.show()
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 setup_ui(self): self.setWindowTitle("Add New Grain") self.setWindowIcon(QIcon(RESOURCE_PATH + "icons/nakka-finocyl.gif")) self.resize(400, 400) controls = QGridLayout() gb_frame = QGroupBox(self.tr("Grain Design")) gb_frame.setLayout(controls) self.cb_grain_type = QComboBox() # TODO: make grain types auto propagate combobox self.cb_grain_type.addItems([self.tr("Cylindrical (BATES)")]) controls.addWidget(QLabel(self.tr("Core Shape")), 0, 0) controls.addWidget(self.cb_grain_type, 0, 1) self.cb_propellant_type = QComboBox() self.cb_propellant_type.addItems(app_context.propellant_db.propellant_names()) controls.addWidget(QLabel(self.tr("Propellant Type")), 1, 0) controls.addWidget(self.cb_propellant_type, 1, 1) # ok and cancel buttons btn_ok = QPushButton(self.tr("Apply")) btn_ok.clicked.connect(self.confirm_grain) btn_cancel = QPushButton(self.tr("Close")) btn_cancel.clicked.connect(self.close) lay_btns = QHBoxLayout() lay_btns.addWidget(btn_ok) lay_btns.addWidget(btn_cancel) frame_btns = QFrame() frame_btns.setLayout(lay_btns) # master layout master = QVBoxLayout() master.addWidget(gb_frame) master.addSpacing(10) master.addWidget(frame_btns) self.setLayout(master)
def setupUI(self, widget): self.ui.setupUi(widget) root_widgets = [w for w in widget.children() if w.__class__.__name__ == "QWidget"] if len(root_widgets) == 0 or widget.layout() is not None: self.ui_widget = self else: self.ui_widget = root_widgets[-1] g = QGridLayout() if qtpy.API=="pyqt5": pass else: if isinstance(self, QtWidgetLoader): g.setMargin(0) g.setSpacing(0) widget.setLayout(g) g.addWidget(self.ui_widget)
def __init__(self, viewer_state=None, session=None): super(BaseCustomOptionsWidget, self).__init__() layout = QGridLayout() for row, (name, (prefix, viewer_cls)) in enumerate(self._widgets.items()): widget = viewer_cls() setattr(self, prefix + name, widget) layout.addWidget(QLabel(name.capitalize()), row, 0) layout.addWidget(widget, row, 1) if len(self._widgets) > 0: layout.setRowStretch(row + 1, 10) self.setLayout(layout) self.viewer_state = viewer_state self.session = session autoconnect_callbacks_to_qt(self.viewer_state, self)
def __init__(self, img, layout='vertical', order=['R', 'G', 'B', 'V']): QFrame.__init__(self) r, g, b, v = histograms(img, 100) self.r_hist = ColorHistogram(r, (255, 0, 0)) self.g_hist = ColorHistogram(g, (0, 255, 0)) self.b_hist = ColorHistogram(b, (0, 0, 255)) self.v_hist = ColorHistogram(v, (0, 0, 0)) self.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken) self.layout = QGridLayout(self) self.layout.setContentsMargins(0, 0, 0, 0) order_map = {'R': self.r_hist, 'G': self.g_hist, 'B': self.b_hist, 'V': self.v_hist} if layout == 'vertical': for i in range(len(order)): self.layout.addWidget(order_map[order[i]], i, 0) elif layout == 'horizontal': for i in range(len(order)): self.layout.addWidget(order_map[order[i]], 0, i)
def __init__(self): QFrame.__init__(self) self.setFrameStyle(QFrame.Box | QFrame.Sunken) self.posx_label = QLabel('X-pos:') self.posx_value = QLabel() self.posy_label = QLabel('Y-pos:') self.posy_value = QLabel() self.r_label = QLabel('R:') self.r_value = QLabel() self.g_label = QLabel('G:') self.g_value = QLabel() self.b_label = QLabel('B:') self.b_value = QLabel() self.h_label = QLabel('H:') self.h_value = QLabel() self.s_label = QLabel('S:') self.s_value = QLabel() self.v_label = QLabel('V:') self.v_value = QLabel() self.layout = QGridLayout(self) self.layout.addWidget(self.posx_label, 0, 0) self.layout.addWidget(self.posx_value, 0, 1) self.layout.addWidget(self.posy_label, 1, 0) self.layout.addWidget(self.posy_value, 1, 1) self.layout.addWidget(self.r_label, 0, 2) self.layout.addWidget(self.r_value, 0, 3) self.layout.addWidget(self.g_label, 1, 2) self.layout.addWidget(self.g_value, 1, 3) self.layout.addWidget(self.b_label, 2, 2) self.layout.addWidget(self.b_value, 2, 3) self.layout.addWidget(self.h_label, 0, 4) self.layout.addWidget(self.h_value, 0, 5) self.layout.addWidget(self.s_label, 1, 4) self.layout.addWidget(self.s_value, 1, 5) self.layout.addWidget(self.v_label, 2, 4) self.layout.addWidget(self.v_value, 2, 5)
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
class QuadHistogram(QFrame): '''A class which uses ColorHistogram to draw the 4 histograms of an image. R, G, B, and Value. The 4 histograms are layout out in a grid, and can be specified horizontal or vertical, and in which order ie. ['R', 'G', 'B', 'V'] ''' def __init__(self, img, layout='vertical', order=['R', 'G', 'B', 'V']): QFrame.__init__(self) r, g, b, v = histograms(img, 100) self.r_hist = ColorHistogram(r, (255, 0, 0)) self.g_hist = ColorHistogram(g, (0, 255, 0)) self.b_hist = ColorHistogram(b, (0, 0, 255)) self.v_hist = ColorHistogram(v, (0, 0, 0)) self.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken) self.layout = QGridLayout(self) self.layout.setContentsMargins(0, 0, 0, 0) order_map = {'R': self.r_hist, 'G': self.g_hist, 'B': self.b_hist, 'V': self.v_hist} if layout == 'vertical': for i in range(len(order)): self.layout.addWidget(order_map[order[i]], i, 0) elif layout == 'horizontal': for i in range(len(order)): self.layout.addWidget(order_map[order[i]], 0, i) def update_hists(self, img): r, g, b, v = histograms(img, 100) self.r_hist.update_hist(r, (255, 0, 0)) self.g_hist.update_hist(g, (0, 255, 0)) self.b_hist.update_hist(b, (0, 0, 255)) self.v_hist.update_hist(v, (0, 0, 0))
def __init__(self, parent, enable_replace=False): QWidget.__init__(self, parent) self.enable_replace = enable_replace self.editor = None self.is_code_editor = None glayout = QGridLayout() glayout.setContentsMargins(0, 0, 0, 0) self.setLayout(glayout) self.close_button = create_toolbutton(self, triggered=self.hide, icon=ima.icon('DialogCloseButton')) glayout.addWidget(self.close_button, 0, 0) # Find layout self.search_text = PatternComboBox(self, tip=_("Search string"), adjust_to_minimum=False) self.return_shift_pressed.connect( lambda: self.find(changed=False, forward=False, rehighlight=False, multiline_replace_check = False)) self.return_pressed.connect( lambda: self.find(changed=False, forward=True, rehighlight=False, multiline_replace_check = False)) self.search_text.lineEdit().textEdited.connect( self.text_has_been_edited) self.number_matches_text = QLabel(self) self.previous_button = create_toolbutton(self, triggered=self.find_previous, icon=ima.icon('ArrowUp')) self.next_button = create_toolbutton(self, triggered=self.find_next, icon=ima.icon('ArrowDown')) self.next_button.clicked.connect(self.update_search_combo) self.previous_button.clicked.connect(self.update_search_combo) self.re_button = create_toolbutton(self, icon=ima.icon('advanced'), tip=_("Regular expression")) self.re_button.setCheckable(True) self.re_button.toggled.connect(lambda state: self.find()) self.case_button = create_toolbutton(self, icon=get_icon("upper_lower.png"), tip=_("Case Sensitive")) self.case_button.setCheckable(True) self.case_button.toggled.connect(lambda state: self.find()) self.words_button = create_toolbutton(self, icon=get_icon("whole_words.png"), tip=_("Whole words")) self.words_button.setCheckable(True) self.words_button.toggled.connect(lambda state: self.find()) self.highlight_button = create_toolbutton(self, icon=get_icon("highlight.png"), tip=_("Highlight matches")) self.highlight_button.setCheckable(True) self.highlight_button.toggled.connect(self.toggle_highlighting) hlayout = QHBoxLayout() self.widgets = [self.close_button, self.search_text, self.number_matches_text, self.previous_button, self.next_button, self.re_button, self.case_button, self.words_button, self.highlight_button] for widget in self.widgets[1:]: hlayout.addWidget(widget) glayout.addLayout(hlayout, 0, 1) # Replace layout replace_with = QLabel(_("Replace with:")) self.replace_text = PatternComboBox(self, adjust_to_minimum=False, tip=_('Replace string')) self.replace_text.valid.connect( lambda _: self.replace_find(focus_replace_text=True)) self.replace_button = create_toolbutton(self, text=_('Replace/find next'), icon=ima.icon('DialogApplyButton'), triggered=self.replace_find, text_beside_icon=True) self.replace_sel_button = create_toolbutton(self, text=_('Replace selection'), icon=ima.icon('DialogApplyButton'), triggered=self.replace_find_selection, text_beside_icon=True) self.replace_sel_button.clicked.connect(self.update_replace_combo) self.replace_sel_button.clicked.connect(self.update_search_combo) self.replace_all_button = create_toolbutton(self, text=_('Replace all'), icon=ima.icon('DialogApplyButton'), triggered=self.replace_find_all, text_beside_icon=True) self.replace_all_button.clicked.connect(self.update_replace_combo) self.replace_all_button.clicked.connect(self.update_search_combo) self.replace_layout = QHBoxLayout() widgets = [replace_with, self.replace_text, self.replace_button, self.replace_sel_button, self.replace_all_button] for widget in widgets: self.replace_layout.addWidget(widget) glayout.addLayout(self.replace_layout, 1, 1) self.widgets.extend(widgets) self.replace_widgets = widgets self.hide_replace() self.search_text.setTabOrder(self.search_text, self.replace_text) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.shortcuts = self.create_shortcuts(parent) self.highlight_timer = QTimer(self) self.highlight_timer.setSingleShot(True) self.highlight_timer.setInterval(1000) self.highlight_timer.timeout.connect(self.highlight_matches) self.search_text.installEventFilter(self)
class ScriptTab(QWidget,): autocomplete_lst = [] def __init__(self, parent, name, script="", filemodified=0): QWidget.__init__(self) self.parent = parent self.tabWidget = self.parent.ui.tabWidget self.gridlayout = QGridLayout(self) self._dirty = False self.initialize_editor() self.gridlayout.addWidget(self.editor) self.setAcceptDrops(True) self.filename = name self.filemodified = filemodified if self.is_file(): self.title = os.path.basename(name) # if self.equals_saved(): # self.filemodified = os.path.getmtime(self.filename) else: self.filename = "" self.title = name # Show this file in the self.editor self.editor.setText(script) self.clean_txt = self.saved() self.update_dirty() self.editor.keyPressEvent = self.key_press_event @property def scriptRunner(self): return self.parent.controller.scriptRunner def wheelEvent(self, event): if event.modifiers() == Qt.ControlModifier: if event.delta() > 0: self.editor.zoomIn() else: self.editor.zoomOut() return QWidget.wheelEvent(self, event) def initialize_editor(self): self.editor = QsciScintilla() # self.editor.cursorPositionChanged.connect(self.e) # self.editor.copyAvailable.connect(self.e) # self.editor.indicatorClicked.connect(self.e) # self.editor.indicatorReleased.connect(self.e) # self.editor.linesChanged.connect(self.e) # self.editor.marginClicked.connect(self.e) # self.editor.modificationAttempted.connect(self.e) # self.editor.modificationChanged.connect(self.e) # self.editor.selectionChanged.connect(self.e) # self.editor.textChanged.connect(self.e) # self.editor.userListActivated.connect(self.e) if self.editor.__class__.__name__ == "LineTextWidget": return # When using PySide without QSciScintilla # define the font to use font = QFont() font.setFamily("Consolas") font.setFixedPitch(True) font.setPointSize(10) # the font metrics here will help # building the margin width later fm = QFontMetrics(font) # set the default font of the self.editor # and take the same font for line numbers self.editor.setFont(font) self.editor.setMarginsFont(font) # Line numbers # conventionnaly, margin 0 is for line numbers self.editor.setMarginWidth(0, fm.width("00000") + 5) self.editor.setMarginLineNumbers(0, True) self.editor.setTabWidth(4) # Folding visual : we will use boxes self.editor.setFolding(QsciScintilla.BoxedTreeFoldStyle) self.editor.setAutoIndent(True) # Braces matching self.editor.setBraceMatching(QsciScintilla.SloppyBraceMatch) # Editing line color self.editor.setCaretLineVisible(True) self.editor.setCaretLineBackgroundColor(QColor("#CDA869")) # Margins colors # line numbers margin self.editor.setMarginsBackgroundColor(QColor("#333333")) self.editor.setMarginsForegroundColor(QColor("#CCCCCC")) # folding margin colors (foreground,background) self.editor.setFoldMarginColors(QColor("#99CC66"), QColor("#333300")) # Choose a lexer self.lexer = QsciLexerPython() self.lexer.setDefaultFont(font) # Set the length of the string before the editor tries to autocomplete # In practise this would be higher than 1 # But its set lower here to make the autocompletion more obvious self.editor.setAutoCompletionThreshold(1) # Tell the editor we are using a QsciAPI for the autocompletion self.editor.setAutoCompletionSource(QsciScintilla.AcsAPIs) self.editor.setLexer(self.lexer) self.editor.setCallTipsStyle(QsciScintilla.CallTipsContext) # self.editor.setCallTipsVisible(0) # Create an API for us to populate with our autocomplete terms self.api = QsciAPIs(self.lexer) # Compile the api for use in the lexer self.api.prepare() # def tefocusInEvent(self, event): # self.parent.focusInEvent(event) # return QTextEdit.focusInEvent(self.textEditScript, event) def is_file(self): return os.path.isfile(self.filename) def is_modified(self): if self.is_file(): if self.equals_saved(): self.filemodified = os.path.getmtime(self.filename) return str(os.path.getmtime(self.filename)) != str(self.filemodified) else: return False def saved(self): if self.is_file(): f = open(self.filename) saved = f.read() f.close() return saved.strip() else: return "" def equals_saved(self): curr_lines = self.get_script().strip().splitlines() saved_lines = self.saved().strip().splitlines() if len(curr_lines) != len(saved_lines): return False for cl, sl in zip(curr_lines, saved_lines): if cl.strip() != sl.strip(): return False return True @property def dirty(self): if not self._dirty: self.dirty = self.clean_txt != self.get_script() return self._dirty @dirty.setter def dirty(self, dirty): if dirty is False: self.clean_txt = self.get_script() if self._dirty != dirty: self._dirty = dirty self.filename_changed() def update_dirty(self): return self.dirty def index(self): return self.tabWidget.indexOf(self) def filename_changed(self): index = self.parent.ui.tabWidget.indexOf(self) if self.dirty: self.tabWidget.setTabText(index, "%s*" % self.title) else: self.tabWidget.setTabText(index, self.title) def reload(self): self.set_script(self.parent._load_script(self.filename)) self.filemodified = os.path.getmtime(self.filename) def close(self): while self.dirty is True: # While avoids data loss, in case save operation is aborted if self.filename == "": text = "Save unsaved changes?" else: text = "Save %s?" % self.filename ans = QMessageBox.question(self, 'Save', text, QMessageBox.Yes, QMessageBox.Cancel, QMessageBox.No) if ans == QMessageBox.Cancel: return elif ans == QMessageBox.Yes: self.parent.actionSave(False) elif ans == QMessageBox.No: break self.tabWidget.removeTab(self.index()) def _save(self,): f = open(self.filename, 'w') f.write(self.get_script()) f.close() self.title = os.path.basename(self.filename) self.dirty = False def key_press_event(self, event): self.update_dirty() if self.editor.__class__.__name__ == "LineTextWidget": return self.editor.edit.keyReleaseEvent(event) # When using PySide without QSciScintilla QsciScintilla.keyPressEvent(self.editor, event) linenr, pos_in_line = self.editor.getCursorPosition() line = str(self.editor.text(linenr)[:pos_in_line]) if event.key() == Qt.Key_F1: try: self.parent.show_documentation(getattr(self.scriptRunner, str(self.editor.selectedText()))) except AttributeError: pass if event.key() == Qt.Key_Enter or event.key() == Qt.Key_Return: for tip in self.autocomplete_lst: try: if line.endswith(tip[:tip.index('(') ]): self.editor.insert(tip[tip.index('('):]) parent, residual = self.scriptRunner.split_line(line) self.parent.show_documentation(self.scriptRunner.get_function_dict(parent, residual)[residual]) return except ValueError: pass if event.key() < 100 or event.key() in [Qt.Key_Backspace, Qt.Key_Shift]: linenr, pos_in_line = self.editor.getCursorPosition() line = str(self.editor.text(linenr)[:pos_in_line]) lst = self.scriptRunner.get_autocomplete_list(line) if lst is not None: self.api.clear() list(map(self.api.add, lst)) self.api.prepare() if len(lst) > 0: self.autocomplete_lst = lst self.editor.autoCompleteFromAll() shift_event = QKeyEvent(QEvent.KeyPress, Qt.Key_Shift, Qt.NoModifier) QsciScintilla.keyPressEvent(self.editor, shift_event) # show autocomplete list def set_script(self, script): self.editor.setText(script) def get_script(self): return str(self.editor.text()).replace("\r", "").replace(">>> ", "").replace("\t", " ") def dropHandler(self, dataItemList, ctrl, shift, event): pass
def _setupIntlkGroup(self, intlktype): if 'General' in intlktype: pvstr = '' elif 'Sum' in intlktype: pvstr = 'MinSum' elif 'Translation' in intlktype: pvstr = 'Trans' elif 'Angulation' in intlktype: pvstr = 'Ang' wid = QGroupBox(intlktype) lay = QGridLayout(wid) lay.setAlignment(Qt.AlignTop | Qt.AlignHCenter) row = 0 ld_enblsel = QLabel('Enable: ', alignment=Qt.AlignRight | Qt.AlignBottom) lay.addWidget(ld_enblsel, row, 0) sel_enbl_wind = create_window_from_widget( BPMIntlkEnblWidget, title='BPM Orbit Interlock - ' + intlktype + ' Enable State') bt_enblsel = QPushButton(qta.icon('fa5s.tasks'), '', self) bt_enblsel.setToolTip('Open window to set BPMs enable state.') bt_enblsel.setObjectName('sel') bt_enblsel.setStyleSheet( '#sel{min-width:25px; max-width:25px; icon-size:20px;}') connect_window(bt_enblsel, sel_enbl_wind, parent=self, propty='Intlk' + pvstr + 'En-Sel', title=intlktype + ' Enable', prefix=self.prefix) lay.addWidget(bt_enblsel, row, 1) ch2vals = dict() for bpm in self.BPM_NAMES: chn = bpm.substitute(prefix=self.prefix, propty='Intlk' + pvstr + 'En-Sts') ch2vals[chn] = 1 led_enblsts = FamBPMIntlkEnblStateLed(self, ch2vals) lay.addWidget(led_enblsts, row, 2) if 'General' not in intlktype: row += 1 ld_lim = QLabel('Thresholds: ', alignment=Qt.AlignRight | Qt.AlignBottom) lay.addWidget(ld_lim, row, 0) sel_lim_wind = create_window_from_widget( BPMIntlkLimSPWidget, title='BPM Orbit Interlock - ' + intlktype + (' Threshold' if 'Thres' not in intlktype else '') + ' Setpoint') bt_lim = QPushButton(qta.icon('fa5s.tasks'), '', self) bt_lim.setToolTip('Open window to set BPMs thresholds.') bt_lim.setObjectName('sel') bt_lim.setStyleSheet( '#sel{min-width:25px; max-width:25px; icon-size:20px;}') connect_window(bt_lim, sel_lim_wind, parent=self, metric=intlktype, prefix=self.prefix) lay.addWidget(bt_lim, row, 1) if 'Sum' not in intlktype: row += 1 ld_clr = QLabel('Reset All: ', self, alignment=Qt.AlignRight | Qt.AlignBottom) lay.addWidget(ld_clr, row, 0) bt_clr = FamBPMButton(self, self.prefix, 'Intlk' + pvstr + 'Clr-Sel', '', value=1) bt_clr.setIcon(qta.icon('fa5s.sync')) bt_clr.setObjectName('clr') bt_clr.setStyleSheet( '#clr{min-width:25px; max-width:25px; icon-size:20px;}') lay.addWidget(bt_clr, row, 1) return wid
class CentralWidget(QWidget): instantRatio = { 0: (2, 0), 1: (10, 1), 2: (5, 2), 3: (2, 2), } def __init__(self, parent): super().__init__() self.parent = parent #self.html = "<h1>UniqueBible.app</h1><p>This is '<b>Main View</b>'.</p>" #self.mainView = WebEngineView(self, "main") #self.mainView.setHtml(self.html, baseUrl) #self.studyView = WebEngineView(self, "study") #self.studyView.setHtml("This is '<b>Study View</b>'.", baseUrl) self.instantSplitter = QSplitter(Qt.Vertical, parent) if config.landscapeMode: self.parallelSplitter = QSplitter(Qt.Horizontal) else: self.parallelSplitter = QSplitter(Qt.Vertical) self.mainView = TabWidget(self, "main") self.parent.mainView = self.mainView for i in range(config.numberOfTab): tabView = WebEngineView(self, "main") self.mainView.addTab( tabView, "{1}{0}".format(i + 1, config.thisTranslation["tabBible"])) tabView.titleChanged.connect(self.parent.mainTextCommandChanged) tabView.loadFinished.connect(self.parent.finishMainViewLoading) self.studyView = TabWidget(self, "study") self.parent.studyView = self.studyView for i in range(config.numberOfTab): tabView = WebEngineView(self, "study") self.studyView.addTab( tabView, "{1}{0}".format(i + 1, config.thisTranslation["tabStudy"])) tabView.titleChanged.connect(self.parent.studyTextCommandChanged) tabView.loadFinished.connect(self.parent.finishStudyViewLoading) self.instantView = WebEngineView(self, "instant") self.instantView.setHtml( "<link id='theme_stylesheet' rel='stylesheet' type='text/css' href='css/{1}.css'><link id='theme_stylesheet' rel='stylesheet' type='text/css' href='css/custom.css'><p style='font-family:{0};'><u><b>Bottom Window</b></u><br>Display instant information on this window by hovering over verse numbers, tagged words or bible reference links.</p>" .format(config.font, config.theme), config.baseUrl) self.parallelSplitter.addWidget(self.mainView) self.parallelSplitter.addWidget(self.studyView) self.parallelSplitter.setHandleWidth(5) self.instantSplitter.setHandleWidth(5) self.instantSplitter.addWidget(self.parallelSplitter) self.instantSplitter.addWidget(self.instantView) # Adding signals self.instantSplitter.splitterMoved.connect(self.onInstantSplitterMoved) self.parallelSplitter.splitterMoved.connect( self.onParallelSplitterMoved) self.layout = QGridLayout() self.layout.setContentsMargins(0, 10, 0, 3) # self.layout.setHorizontalSpacing(0) # self.layout.setVerticalSpacing(2) self.layout.addWidget(self.instantSplitter) self.setLayout(self.layout) def onInstantSplitterMoved(self, pos, index): config.instantMode = -1 config.iModeSplitterSizes = self.instantSplitter.sizes() def onParallelSplitterMoved(self, pos, index): config.parallelMode = -1 config.pModeSplitterSizes = self.parallelSplitter.sizes() def switchLandscapeMode(self): if config.landscapeMode: # Switch to Landscape self.parallelSplitter.setOrientation(Qt.Horizontal) else: #Switch to Portrait self.parallelSplitter.setOrientation(Qt.Vertical) def resizeMe(self): if config.landscapeMode: self.resizeAsLandscape() else: self.resizeAsPortrait() def resizeAsLandscape(self): parallelRatio = { 0: (1, 0), 1: (2, 1), 2: (1, 1), 3: (1, 2), 4: (0, 1), } # The total space we have. w, h = [self.parallelSplitter.width(), self.instantSplitter.height()] if config.parallelMode == -1: left, right = config.pModeSplitterSizes w = left + right else: left, right = parallelRatio[config.parallelMode] self.parallelSplitter.setSizes( [w * left // (left + right), w * right // (left + right)]) if config.parallelMode: self.studyView.show() else: self.studyView.hide() if config.instantMode == -1: top, bottom = config.iModeSplitterSizes h = top + bottom else: top, bottom = CentralWidget.instantRatio[config.instantMode] self.instantSplitter.setSizes( [h * top // (top + bottom), h * bottom // (top + bottom)]) if config.instantMode: self.instantView.show() else: self.instantView.hide() def resizeAsPortrait(self): parallelRatio = { (0, 0): (10, 0, 0), (0, 1): (10, 5, 0), (0, 2): (5, 5, 0), (0, 3): (5, 10, 0), (1, 0): (10, 0, 3), (1, 1): (20, 10, 9), (1, 2): (5, 5, 3), (1, 3): (10, 20, 9), (2, 0): (10, 0, 10), (2, 1): (10, 5, 15), (2, 2): (10, 10, 20), (2, 3): (5, 10, 15), } h = self.instantSplitter.height() if config.instantMode == -1: i1, i2 = config.iModeSplitterSizes h = i1 + i2 bottom = i2 * h // (i1 + i2) remaining = h - bottom if config.parallelMode == -1: s1, s2 = config.pModeSplitterSizes top = s1 * remaining // (s1 + s2) middle = s2 * remaining // (s1 + s2) else: # i.e. config.parallelMode is not custom _top, _middle, _bottom = parallelRatio[(0, config.parallelMode)] top = _top * remaining // (_top + _middle) middle = _middle * remaining // (_top + _middle) else: # i.e. config.instantMode is set if config.parallelMode == -1: s1, s2 = config.pModeSplitterSizes _top, _middle, _bottom = parallelRatio[(config.instantMode, 0)] bottom = h * _bottom // (_top + _middle + _bottom) remaining = h - bottom top = s1 * remaining // (s1 + s2) middle = s2 * remaining // (s1 + s2) else: _top, _middle, _bottom = parallelRatio[(config.instantMode, config.parallelMode)] top = h * _top // (_top + _middle + _bottom) middle = h * _middle // (_top + _middle + _bottom) bottom = h * _bottom // (_top + _middle + _bottom) self.instantSplitter.setSizes([top + middle, bottom]) self.parallelSplitter.setSizes([top, middle]) if config.parallelMode: self.studyView.show() else: self.studyView.hide() if config.instantMode: self.instantView.show() else: self.instantView.hide()
def __init__(self, mask_names): """ :type mask_names: set :param mask_names: iterable collection of all available mask names """ super().__init__() self.mask_names = mask_names completer = QCompleter(list(mask_names)) completer.setCaseSensitivity(Qt.CaseInsensitive) self.setWindowTitle("Masks name choose") self.mask1_name = QLineEdit() self.mask2_name = QLineEdit() self.cancel_btn = QPushButton("Cancel") self.ok_btn = QPushButton("Ok") self.mask1_name.setCompleter(completer) self.mask1_name.textChanged.connect(self.text_changed) self.mask2_name.setCompleter(completer) self.mask2_name.textChanged.connect(self.text_changed) self.cancel_btn.clicked.connect(self.close) self.ok_btn.clicked.connect(self.accept) self.ok_btn.setDisabled(True) layout = QGridLayout() layout.addWidget(right_label("Mask 1 name:"), 0, 0) layout.addWidget(self.mask1_name, 0, 1) layout.addWidget(right_label("Mask 2 name:"), 1, 0) layout.addWidget(self.mask2_name, 1, 1) layout.addWidget(self.cancel_btn, 2, 0) layout.addWidget(self.ok_btn, 2, 1) self.setLayout(layout)
def setup_page(self): newcb = self.create_checkbox # --- Introspection --- # Basic features group basic_features_group = QGroupBox(_("Basic features")) completion_box = newcb(_("Enable code completion"), 'code_completion') enable_hover_hints_box = newcb( _("Enable hover hints"), 'enable_hover_hints', tip=_("If enabled, hovering the mouse pointer over an object\n" "name will display that object's signature and/or\n" "docstring (if present).")) goto_definition_box = newcb( _("Enable Go to definition"), 'jedi_definition', tip=_("If enabled, left-clicking on an object name while \n" "pressing the {} key will go to that object's definition\n" "(if resolved).".format(self.CTRL))) follow_imports_box = newcb( _("Follow imports when going to a " "definition"), 'jedi_definition/follow_imports') show_signature_box = newcb(_("Show calltips"), 'jedi_signature_help') basic_features_layout = QVBoxLayout() basic_features_layout.addWidget(completion_box) basic_features_layout.addWidget(enable_hover_hints_box) basic_features_layout.addWidget(goto_definition_box) basic_features_layout.addWidget(follow_imports_box) basic_features_layout.addWidget(show_signature_box) basic_features_group.setLayout(basic_features_layout) # Advanced group advanced_group = QGroupBox(_("Advanced")) modules_textedit = self.create_textedit( _("Preload the following modules to make completion faster " "and more accurate:"), 'preload_modules') if is_dark_interface(): modules_textedit.textbox.setStyleSheet( "border: 1px solid #32414B;") advanced_layout = QVBoxLayout() advanced_layout.addWidget(modules_textedit) advanced_group.setLayout(advanced_layout) # --- Linting --- # Linting options linting_label = QLabel( _("Spyder can optionally highlight syntax " "errors and possible problems with your " "code in the editor.")) linting_label.setOpenExternalLinks(True) linting_label.setWordWrap(True) linting_check = self.create_checkbox(_("Enable basic linting"), 'pyflakes') linting_complexity_box = self.create_checkbox( _("Enable complexity linting with " "the Mccabe package"), 'mccabe') # Linting layout linting_layout = QVBoxLayout() linting_layout.addWidget(linting_label) linting_layout.addWidget(linting_check) linting_layout.addWidget(linting_complexity_box) linting_widget = QWidget() linting_widget.setLayout(linting_layout) # --- Code style tab --- # Code style label pep_url = ( '<a href="https://www.python.org/dev/peps/pep-0008">PEP 8</a>') code_style_codes_url = _( "<a href='http://pycodestyle.pycqa.org/en/stable" "/intro.html#error-codes'>pycodestyle error codes</a>") code_style_label = QLabel( _("Spyder can use pycodestyle to analyze your code for " "conformance to the {} convention. You can also " "manually show or hide specific warnings by their " "{}.").format(pep_url, code_style_codes_url)) code_style_label.setOpenExternalLinks(True) code_style_label.setWordWrap(True) # Code style checkbox self.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')) self.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(self.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 self.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')) self.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(self.docstring_style_check) docstring_style_layout.addWidget(docstring_style_g_widget) docstring_style_widget = QWidget() docstring_style_widget.setLayout(docstring_style_layout) # --- Advanced tab --- # Advanced label advanced_label = QLabel( _("<b>Warning</b>: Only modify these values if " "you know what you're doing!")) advanced_label.setWordWrap(True) advanced_label.setAlignment(Qt.AlignJustify) # Advanced options self.advanced_command_launch = self.create_lineedit( _("Command to launch the Python language server: "), 'advanced/command_launch', alignment=Qt.Horizontal, word_wrap=False) self.advanced_host = self.create_lineedit( _("IP Address and port to bind the server to: "), 'advanced/host', alignment=Qt.Horizontal, word_wrap=False) self.advanced_port = self.create_spinbox(":", "", 'advanced/port', min_=1, max_=65535, step=1) self.external_server = self.create_checkbox( _("This is an external server"), 'advanced/external') self.use_stdio = self.create_checkbox( _("Use stdio pipes to communicate with server"), 'advanced/stdio') self.use_stdio.stateChanged.connect(self.disable_tcp) self.external_server.stateChanged.connect(self.disable_stdio) # Advanced layout advanced_g_layout = QGridLayout() advanced_g_layout.addWidget(self.advanced_command_launch.label, 1, 0) advanced_g_layout.addWidget(self.advanced_command_launch.textbox, 1, 1) advanced_g_layout.addWidget(self.advanced_host.label, 2, 0) advanced_host_port_g_layout = QGridLayout() advanced_host_port_g_layout.addWidget(self.advanced_host.textbox, 1, 0) advanced_host_port_g_layout.addWidget(self.advanced_port.plabel, 1, 1) advanced_host_port_g_layout.addWidget(self.advanced_port.spinbox, 1, 2) advanced_g_layout.addLayout(advanced_host_port_g_layout, 2, 1) advanced_widget = QWidget() advanced_layout = QVBoxLayout() advanced_layout.addWidget(advanced_label) advanced_layout.addSpacing(12) advanced_layout.addLayout(advanced_g_layout) advanced_layout.addWidget(self.external_server) advanced_layout.addWidget(self.use_stdio) advanced_widget.setLayout(advanced_layout) # --- Other servers tab --- # Section label servers_label = QLabel( _("Spyder uses the <a href=\"{lsp_url}\">Language Server " "Protocol</a> to provide code completion and linting " "for its Editor. Here, you can setup and configure LSP servers " "for languages other than Python, so Spyder can provide such " "features for those languages as well.").format(lsp_url=LSP_URL)) servers_label.setOpenExternalLinks(True) servers_label.setWordWrap(True) servers_label.setAlignment(Qt.AlignJustify) # Servers table table_group = QGroupBox(_('Available servers:')) self.table = LSPServerTable(self, text_color=ima.MAIN_FG_COLOR) self.table.setMaximumHeight(150) table_layout = QVBoxLayout() table_layout.addWidget(self.table) table_group.setLayout(table_layout) # Buttons self.reset_btn = QPushButton(_("Reset to default values")) self.new_btn = QPushButton(_("Set up a new server")) self.delete_btn = QPushButton(_("Delete currently selected server")) self.delete_btn.setEnabled(False) # Slots connected to buttons self.new_btn.clicked.connect(self.create_new_server) self.reset_btn.clicked.connect(self.reset_to_default) self.delete_btn.clicked.connect(self.delete_server) # Buttons layout btns = [self.new_btn, self.delete_btn, self.reset_btn] buttons_layout = QGridLayout() for i, btn in enumerate(btns): buttons_layout.addWidget(btn, i, 1) buttons_layout.setColumnStretch(0, 1) buttons_layout.setColumnStretch(1, 2) buttons_layout.setColumnStretch(2, 1) # Combined layout servers_widget = QWidget() servers_layout = QVBoxLayout() servers_layout.addSpacing(-10) servers_layout.addWidget(servers_label) servers_layout.addWidget(table_group) servers_layout.addSpacing(10) servers_layout.addLayout(buttons_layout) servers_widget.setLayout(servers_layout) # --- Tabs organization --- self.tabs = QTabWidget() self.tabs.addTab(self.create_tab(basic_features_group, advanced_group), _('Introspection')) self.tabs.addTab(self.create_tab(linting_widget), _('Linting')) self.tabs.addTab(self.create_tab(code_style_widget), _('Code style')) self.tabs.addTab(self.create_tab(docstring_style_widget), _('Docstring style')) self.tabs.addTab(self.create_tab(advanced_widget), _('Advanced')) self.tabs.addTab(self.create_tab(servers_widget), _('Other languages')) vlayout = QVBoxLayout() vlayout.addWidget(self.tabs) self.setLayout(vlayout)
def __init__(self, parent=None): super(KernelConnectionDialog, self).__init__(parent) self.setWindowTitle(_('Connect to an existing kernel')) main_label = QLabel(_( "<p>Please select the JSON connection file (<i>e.g.</i> " "<tt>kernel-1234.json</tt>) of the existing kernel, and enter " "the SSH information if connecting to a remote machine. " "To learn more about starting external kernels and connecting " "to them, see <a href=\"https://docs.spyder-ide.org/" "ipythonconsole.html#connect-to-an-external-kernel\">" "our documentation</a>.</p>")) main_label.setWordWrap(True) main_label.setAlignment(Qt.AlignJustify) main_label.setOpenExternalLinks(True) # Connection file cf_label = QLabel(_('Connection file:')) self.cf = QLineEdit() self.cf.setPlaceholderText(_('Kernel connection file path')) self.cf.setMinimumWidth(350) cf_open_btn = QPushButton(_('Browse')) cf_open_btn.clicked.connect(self.select_connection_file) cf_layout = QHBoxLayout() cf_layout.addWidget(cf_label) cf_layout.addWidget(self.cf) cf_layout.addWidget(cf_open_btn) # Remote kernel groupbox self.rm_group = QGroupBox(_("This is a remote kernel (via SSH)")) # SSH connection hn_label = QLabel(_('Hostname:')) self.hn = QLineEdit() pn_label = QLabel(_('Port:')) self.pn = QLineEdit() self.pn.setMaximumWidth(75) self.pn.setText('22') un_label = QLabel(_('Username:'******'Password:'******'SSH keyfile:')) self.pw = QLineEdit() self.pw.setEchoMode(QLineEdit.Password) self.pw_radio.toggled.connect(self.pw.setEnabled) self.kf_radio.toggled.connect(self.pw.setDisabled) self.kf = QLineEdit() kf_open_btn = QPushButton(_('Browse')) kf_open_btn.clicked.connect(self.select_ssh_key) kf_layout = QHBoxLayout() kf_layout.addWidget(self.kf) kf_layout.addWidget(kf_open_btn) kfp_label = QLabel(_('Passphase:')) self.kfp = QLineEdit() self.kfp.setPlaceholderText(_('Optional')) self.kfp.setEchoMode(QLineEdit.Password) self.kf_radio.toggled.connect(self.kf.setEnabled) self.kf_radio.toggled.connect(self.kfp.setEnabled) self.kf_radio.toggled.connect(kf_open_btn.setEnabled) self.kf_radio.toggled.connect(kfp_label.setEnabled) self.pw_radio.toggled.connect(self.kf.setDisabled) self.pw_radio.toggled.connect(self.kfp.setDisabled) self.pw_radio.toggled.connect(kf_open_btn.setDisabled) self.pw_radio.toggled.connect(kfp_label.setDisabled) # SSH layout ssh_layout = QGridLayout() ssh_layout.addWidget(hn_label, 0, 0, 1, 2) ssh_layout.addWidget(self.hn, 0, 2) ssh_layout.addWidget(pn_label, 0, 3) ssh_layout.addWidget(self.pn, 0, 4) ssh_layout.addWidget(un_label, 1, 0, 1, 2) ssh_layout.addWidget(self.un, 1, 2, 1, 3) # SSH authentication layout auth_layout = QGridLayout() auth_layout.addWidget(self.pw_radio, 1, 0) auth_layout.addWidget(pw_label, 1, 1) auth_layout.addWidget(self.pw, 1, 2) auth_layout.addWidget(self.kf_radio, 2, 0) auth_layout.addWidget(kf_label, 2, 1) auth_layout.addLayout(kf_layout, 2, 2) auth_layout.addWidget(kfp_label, 3, 1) auth_layout.addWidget(self.kfp, 3, 2) auth_group.setLayout(auth_layout) # Remote kernel layout rm_layout = QVBoxLayout() rm_layout.addLayout(ssh_layout) rm_layout.addSpacerItem(QSpacerItem(QSpacerItem(0, 8))) rm_layout.addWidget(auth_group) self.rm_group.setLayout(rm_layout) self.rm_group.setCheckable(True) self.rm_group.setChecked(False) self.rm_group.toggled.connect(self.pw_radio.setChecked) # Ok and Cancel buttons self.accept_btns = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self) self.accept_btns.accepted.connect(self.accept) self.accept_btns.rejected.connect(self.reject) # Dialog layout layout = QVBoxLayout(self) layout.addWidget(main_label) layout.addSpacerItem(QSpacerItem(QSpacerItem(0, 8))) layout.addLayout(cf_layout) layout.addSpacerItem(QSpacerItem(QSpacerItem(0, 12))) layout.addWidget(self.rm_group) layout.addWidget(self.accept_btns)
def __init__(self, settings: PartSettings): super().__init__() self.settings = settings self.save_translate_dict: typing.Dict[str, SaveBase] = { x.get_short_name(): x for x in save_dict.values() } self.plan = PlanPreview(self) self.save_plan_btn = QPushButton("Save") self.clean_plan_btn = QPushButton("Remove all") self.remove_btn = QPushButton("Remove") self.update_element_chk = QCheckBox("Update element") self.change_root = QEnumComboBox(enum_class=RootType) self.save_choose = QComboBox() self.save_choose.addItem("<none>") self.save_choose.addItems(list(self.save_translate_dict.keys())) self.save_btn = QPushButton("Save") self.segment_profile = SearchableListWidget() self.pipeline_profile = SearchableListWidget() self.segment_stack = QTabWidget() self.segment_stack.addTab(self.segment_profile, "Profile") self.segment_stack.addTab(self.pipeline_profile, "Pipeline") self.generate_mask_btn = QPushButton("Add mask") self.generate_mask_btn.setToolTip("Mask need to have unique name") self.mask_name = QLineEdit() self.mask_operation = QEnumComboBox(enum_class=MaskOperation) self.chanel_num = QSpinBox() self.choose_channel_for_measurements = QComboBox() self.choose_channel_for_measurements.addItems( ["Same as segmentation"] + [str(x + 1) for x in range(MAX_CHANNEL_NUM)]) self.units_choose = QEnumComboBox(enum_class=Units) self.units_choose.setCurrentEnum( self.settings.get("units_value", Units.nm)) self.chanel_num.setRange(0, 10) self.expected_node_type = None self.save_constructor = None self.chose_profile_btn = QPushButton("Add Profile") self.get_big_btn = QPushButton("Leave the biggest") self.get_big_btn.hide() self.get_big_btn.setDisabled(True) self.measurements_list = SearchableListWidget(self) self.measurement_name_prefix = QLineEdit(self) self.add_calculation_btn = QPushButton("Add measurement calculation") self.information = QTextEdit() self.information.setReadOnly(True) self.protect = False self.mask_set = set() self.calculation_plan = CalculationPlan() self.plan.set_plan(self.calculation_plan) self.segmentation_mask = MaskWidget(settings) self.file_mask = FileMask() self.change_root.currentIndexChanged.connect(self.change_root_type) self.save_choose.currentTextChanged.connect(self.save_changed) self.measurements_list.currentTextChanged.connect( self.show_measurement) self.segment_profile.currentTextChanged.connect(self.show_segment) self.measurements_list.currentTextChanged.connect( self.show_measurement_info) self.segment_profile.currentTextChanged.connect(self.show_segment_info) self.pipeline_profile.currentTextChanged.connect( self.show_segment_info) self.pipeline_profile.currentTextChanged.connect(self.show_segment) self.mask_name.textChanged.connect(self.mask_name_changed) self.generate_mask_btn.clicked.connect(self.create_mask) self.clean_plan_btn.clicked.connect(self.clean_plan) self.remove_btn.clicked.connect(self.remove_element) self.mask_name.textChanged.connect(self.mask_text_changed) self.chose_profile_btn.clicked.connect(self.add_segmentation) self.get_big_btn.clicked.connect(self.add_leave_biggest) self.add_calculation_btn.clicked.connect(self.add_measurement) self.save_plan_btn.clicked.connect(self.add_calculation_plan) # self.forgot_mask_btn.clicked.connect(self.forgot_mask) # self.cmap_save_btn.clicked.connect(self.save_to_cmap) self.save_btn.clicked.connect(self.add_save_to_project) self.update_element_chk.stateChanged.connect(self.mask_text_changed) self.update_element_chk.stateChanged.connect(self.show_measurement) self.update_element_chk.stateChanged.connect(self.show_segment) self.update_element_chk.stateChanged.connect(self.update_names) self.segment_stack.currentChanged.connect( self.change_segmentation_table) self.settings.measurement_profiles_changed.connect( self._refresh_measurement) self.settings.roi_profiles_changed.connect(self._refresh_profiles) self.settings.roi_pipelines_changed.connect(self._refresh_pipelines) plan_box = QGroupBox("Prepare workflow:") lay = QVBoxLayout() lay.addWidget(self.plan) bt_lay = QGridLayout() bt_lay.setSpacing(1) bt_lay.addWidget(self.save_plan_btn, 0, 0) bt_lay.addWidget(self.clean_plan_btn, 0, 1) bt_lay.addWidget(self.remove_btn, 1, 0) bt_lay.addWidget(self.update_element_chk, 1, 1) lay.addLayout(bt_lay) plan_box.setLayout(lay) plan_box.setStyleSheet(group_sheet) other_box = QGroupBox("Other operations:") other_box.setContentsMargins(0, 0, 0, 0) bt_lay = QVBoxLayout() bt_lay.setSpacing(0) bt_lay.addWidget(QLabel("Root type:")) bt_lay.addWidget(self.change_root) bt_lay.addStretch(1) bt_lay.addWidget(QLabel("Saving:")) bt_lay.addWidget(self.save_choose) bt_lay.addWidget(self.save_btn) other_box.setLayout(bt_lay) other_box.setStyleSheet(group_sheet) mask_box = QGroupBox("Use mask from:") mask_box.setStyleSheet(group_sheet) self.mask_stack = QTabWidget() self.mask_stack.addTab(stretch_widget(self.file_mask), "File") self.mask_stack.addTab(stretch_widget(self.segmentation_mask), "Current ROI") self.mask_stack.addTab(stretch_widget(self.mask_operation), "Operations on masks") self.mask_stack.setTabToolTip( 2, "Allows to create mask which is based on masks previously added to plan." ) lay = QGridLayout() lay.setSpacing(0) lay.addWidget(self.mask_stack, 0, 0, 1, 2) label = QLabel("Mask name:") label.setToolTip( "Needed if you would like to reuse this mask in tab 'Operations on masks'" ) self.mask_name.setToolTip( "Needed if you would like to reuse this mask in tab 'Operations on masks'" ) lay.addWidget(label, 1, 0) lay.addWidget(self.mask_name, 1, 1) lay.addWidget(self.generate_mask_btn, 2, 0, 1, 2) mask_box.setLayout(lay) segment_box = QGroupBox("ROI extraction:") segment_box.setStyleSheet(group_sheet) lay = QVBoxLayout() lay.setSpacing(0) lay.addWidget(self.segment_stack) lay.addWidget(self.chose_profile_btn) lay.addWidget(self.get_big_btn) segment_box.setLayout(lay) measurement_box = QGroupBox("Set of measurements:") measurement_box.setStyleSheet(group_sheet) lay = QGridLayout() lay.setSpacing(0) lay.addWidget(self.measurements_list, 0, 0, 1, 2) lab = QLabel("Name prefix:") lab.setToolTip("Prefix added before each column name") lay.addWidget(lab, 1, 0) lay.addWidget(self.measurement_name_prefix, 1, 1) lay.addWidget(QLabel("Channel:"), 2, 0) lay.addWidget(self.choose_channel_for_measurements, 2, 1) lay.addWidget(QLabel("Units:"), 3, 0) lay.addWidget(self.units_choose, 3, 1) lay.addWidget(self.add_calculation_btn, 4, 0, 1, 2) measurement_box.setLayout(lay) info_box = QGroupBox("Information") info_box.setStyleSheet(group_sheet) lay = QVBoxLayout() lay.addWidget(self.information) info_box.setLayout(lay) layout = QGridLayout() fst_col = QVBoxLayout() fst_col.addWidget(plan_box, 1) fst_col.addWidget(mask_box) layout.addWidget(plan_box, 0, 0, 5, 1) # layout.addWidget(plan_box, 0, 0, 3, 1) # layout.addWidget(mask_box, 3, 0, 2, 1) # layout.addWidget(segmentation_mask_box, 1, 1) layout.addWidget(mask_box, 0, 2, 1, 2) layout.addWidget(other_box, 0, 1) layout.addWidget(segment_box, 1, 1, 1, 2) layout.addWidget(measurement_box, 1, 3) layout.addWidget(info_box, 3, 1, 1, 3) self.setLayout(layout) self.generate_mask_btn.setDisabled(True) self.chose_profile_btn.setDisabled(True) self.add_calculation_btn.setDisabled(True) self.mask_allow = False self.segment_allow = False self.file_mask_allow = False self.node_type = NodeType.root self.node_name = "" self.plan_node_changed.connect(self.mask_text_changed) self.plan.changed_node.connect(self.node_type_changed) self.plan_node_changed.connect(self.show_segment) self.plan_node_changed.connect(self.show_measurement) self.plan_node_changed.connect(self.mask_stack_change) self.mask_stack.currentChanged.connect(self.mask_stack_change) self.file_mask.value_changed.connect(self.mask_stack_change) self.mask_name.textChanged.connect(self.mask_stack_change) self.node_type_changed() self.refresh_all_profiles()
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) screen_resolution_label.setOpenExternalLinks(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 _setupUi(self): self._ld_ilkistop = QLabel('Stop\n(Input)', self) self._led_ilkistop = PyDMLed( self, self.dev_pref.substitute(propty='IntlkInStop-Mon')) self._led_ilkistop.offColor = PyDMLed.LightGreen self._led_ilkistop.onColor = PyDMLed.Red self._lb_ilkistop = PyDMLabel( self, self.dev_pref.substitute(propty='IntlkInStop-Mon')) hbox_ilkistop = QHBoxLayout() hbox_ilkistop.addWidget(self._led_ilkistop) hbox_ilkistop.addWidget(self._lb_ilkistop) self._ld_ilkieopn = QLabel('Emergency Open Gap\n(Input)', self) self._led_ilkieopn = PyDMLed( self, self.dev_pref.substitute(propty='IntlkInEOpnGap-Mon')) self._led_ilkieopn.offColor = PyDMLed.LightGreen self._led_ilkieopn.onColor = PyDMLed.Red self._lb_ilkieopn = PyDMLabel( self, self.dev_pref.substitute(propty='IntlkInEOpnGap-Mon')) hbox_eopngap = QHBoxLayout() hbox_eopngap.addWidget(self._led_ilkieopn) hbox_eopngap.addWidget(self._lb_ilkieopn) self._ld_ilkogapopn = QLabel('Gap Opened\n(Output)', self) self._lb_ilkogapopn = PyDMLabel( self, self.dev_pref.substitute(propty='IntlkOutGapStt-Mon')) self._lb_ilkogapopn.setAlignment(Qt.AlignCenter) self._ld_ilkopwr = QLabel('Power Enabled\n(Output)', self) self._led_ilkopwr = PyDMLed( self, self.dev_pref.substitute(propty='IntlkOutPwrEnbld-Mon')) self._led_ilkopwr.offColor = PyDMLed.Red self._led_ilkopwr.onColor = PyDMLed.LightGreen lay = QGridLayout(self) lay.addWidget( QLabel('<h4>Interlock status</h4>', self, alignment=Qt.AlignCenter), 0, 0, 1, 2) lay.addWidget(self._ld_ilkistop, 1, 0) lay.addLayout(hbox_ilkistop, 1, 1) lay.addWidget(self._ld_ilkieopn, 2, 0) lay.addLayout(hbox_eopngap, 2, 1) lay.addWidget(self._ld_ilkogapopn, 3, 0) lay.addWidget(self._lb_ilkogapopn, 3, 1) lay.addWidget(self._ld_ilkopwr, 4, 0) lay.addWidget(self._led_ilkopwr, 4, 1)
def setup_page(self): newcb = self.create_checkbox # Interface Group interface_group = QGroupBox(_("Interface")) banner_box = newcb(_("Display initial banner"), 'show_banner', tip=_("This option lets you hide the message " "shown at\nthe top of the console when " "it's opened.")) calltips_box = newcb(_("Show calltips"), 'show_calltips') ask_box = newcb(_("Ask for confirmation before closing"), 'ask_before_closing') reset_namespace_box = newcb( _("Ask for confirmation before removing all user-defined " "variables"), 'show_reset_namespace_warning', tip=_("This option lets you hide the warning message shown\n" "when resetting the namespace from Spyder.")) show_time_box = newcb(_("Show elapsed time"), 'show_elapsed_time') ask_restart_box = newcb( _("Ask for confirmation before restarting"), 'ask_before_restart', tip=_("This option lets you hide the warning message shown\n" "when restarting the kernel.")) interface_layout = QVBoxLayout() interface_layout.addWidget(banner_box) interface_layout.addWidget(calltips_box) interface_layout.addWidget(ask_box) interface_layout.addWidget(reset_namespace_box) interface_layout.addWidget(show_time_box) interface_layout.addWidget(ask_restart_box) interface_group.setLayout(interface_layout) comp_group = QGroupBox(_("Completion type")) comp_label = QLabel(_("Decide what type of completion to use")) comp_label.setWordWrap(True) completers = [(_("Graphical"), 0), (_("Terminal"), 1), (_("Plain"), 2)] comp_box = self.create_combobox(_("Completion:")+" ", completers, 'completion_type') comp_layout = QVBoxLayout() comp_layout.addWidget(comp_label) comp_layout.addWidget(comp_box) comp_group.setLayout(comp_layout) # Source Code Group source_code_group = QGroupBox(_("Source code")) buffer_spin = self.create_spinbox( _("Buffer: "), _(" lines"), 'buffer_size', min_=-1, max_=1000000, step=100, tip=_("Set the maximum number of lines of text shown in the\n" "console before truncation. Specifying -1 disables it\n" "(not recommended!)")) source_code_layout = QVBoxLayout() source_code_layout.addWidget(buffer_spin) source_code_group.setLayout(source_code_layout) # --- Graphics --- # Pylab Group pylab_group = QGroupBox(_("Support for graphics (Matplotlib)")) pylab_box = newcb(_("Activate support"), 'pylab') autoload_pylab_box = newcb( _("Automatically load Pylab and NumPy modules"), 'pylab/autoload', tip=_("This lets you load graphics support without importing\n" "the commands to do plots. Useful to work with other\n" "plotting libraries different to Matplotlib or to develop\n" "GUIs with Spyder.")) autoload_pylab_box.setEnabled(self.get_option('pylab')) pylab_box.toggled.connect(autoload_pylab_box.setEnabled) pylab_layout = QVBoxLayout() pylab_layout.addWidget(pylab_box) pylab_layout.addWidget(autoload_pylab_box) pylab_group.setLayout(pylab_layout) # Pylab backend Group inline = _("Inline") automatic = _("Automatic") backend_group = QGroupBox(_("Graphics backend")) bend_label = QLabel(_("Decide how graphics are going to be displayed " "in the console. If unsure, please select " "<b>%s</b> to put graphics inside the " "console or <b>%s</b> to interact with " "them (through zooming and panning) in a " "separate window.") % (inline, automatic)) bend_label.setWordWrap(True) backends = [(inline, 0), (automatic, 1), ("Qt5", 2), ("Qt4", 3)] if sys.platform == 'darwin': backends.append(("OS X", 4)) if sys.platform.startswith('linux'): backends.append(("Gtk3", 5)) backends.append(("Gtk", 6)) if PY2: backends.append(("Wx", 7)) backends.append(("Tkinter", 8)) backends = tuple(backends) backend_box = self.create_combobox( _("Backend:") + " ", backends, 'pylab/backend', default=0, tip=_("This option will be applied the next time a console is " "opened.")) backend_layout = QVBoxLayout() backend_layout.addWidget(bend_label) backend_layout.addWidget(backend_box) backend_group.setLayout(backend_layout) backend_group.setEnabled(self.get_option('pylab')) pylab_box.toggled.connect(backend_group.setEnabled) # Inline backend Group inline_group = QGroupBox(_("Inline backend")) inline_label = QLabel(_("Decide how to render the figures created by " "this backend")) inline_label.setWordWrap(True) formats = (("PNG", 0), ("SVG", 1)) format_box = self.create_combobox(_("Format:")+" ", formats, 'pylab/inline/figure_format', default=0) resolution_spin = self.create_spinbox( _("Resolution:")+" ", " "+_("dpi"), 'pylab/inline/resolution', min_=50, max_=999, step=0.1, tip=_("Only used when the format is PNG. Default is " "72")) width_spin = self.create_spinbox( _("Width:")+" ", " "+_("inches"), 'pylab/inline/width', min_=2, max_=20, step=1, tip=_("Default is 6")) height_spin = self.create_spinbox( _("Height:")+" ", " "+_("inches"), 'pylab/inline/height', min_=1, max_=20, step=1, tip=_("Default is 4")) bbox_inches_box = newcb( _("Use a tight layout for inline plots"), 'pylab/inline/bbox_inches', tip=_("Sets bbox_inches to \"tight\" when\n" "plotting inline with matplotlib.\n" "When enabled, can cause discrepancies\n" "between the image displayed inline and\n" "that created using savefig.")) inline_v_layout = QVBoxLayout() inline_v_layout.addWidget(inline_label) inline_layout = QGridLayout() inline_layout.addWidget(format_box.label, 1, 0) inline_layout.addWidget(format_box.combobox, 1, 1) inline_layout.addWidget(resolution_spin.plabel, 2, 0) inline_layout.addWidget(resolution_spin.spinbox, 2, 1) inline_layout.addWidget(resolution_spin.slabel, 2, 2) inline_layout.addWidget(width_spin.plabel, 3, 0) inline_layout.addWidget(width_spin.spinbox, 3, 1) inline_layout.addWidget(width_spin.slabel, 3, 2) inline_layout.addWidget(height_spin.plabel, 4, 0) inline_layout.addWidget(height_spin.spinbox, 4, 1) inline_layout.addWidget(height_spin.slabel, 4, 2) inline_layout.addWidget(bbox_inches_box, 5, 0, 1, 4) inline_h_layout = QHBoxLayout() inline_h_layout.addLayout(inline_layout) inline_h_layout.addStretch(1) inline_v_layout.addLayout(inline_h_layout) inline_group.setLayout(inline_v_layout) inline_group.setEnabled(self.get_option('pylab')) pylab_box.toggled.connect(inline_group.setEnabled) # --- Startup --- # Run lines Group run_lines_group = QGroupBox(_("Run code")) run_lines_label = QLabel(_("You can run several lines of code when " "a console is started. Please introduce " "each one separated by semicolons and a " "space, for example:<br>" "<i>import os; import sys</i>")) run_lines_label.setWordWrap(True) run_lines_edit = self.create_lineedit(_("Lines:"), 'startup/run_lines', '', alignment=Qt.Horizontal) run_lines_layout = QVBoxLayout() run_lines_layout.addWidget(run_lines_label) run_lines_layout.addWidget(run_lines_edit) run_lines_group.setLayout(run_lines_layout) # Run file Group run_file_group = QGroupBox(_("Run a file")) run_file_label = QLabel(_("You can also run a whole file at startup " "instead of just some lines (This is " "similar to have a PYTHONSTARTUP file).")) run_file_label.setWordWrap(True) file_radio = newcb(_("Use the following file:"), 'startup/use_run_file', False) run_file_browser = self.create_browsefile('', 'startup/run_file', '') run_file_browser.setEnabled(False) file_radio.toggled.connect(run_file_browser.setEnabled) run_file_layout = QVBoxLayout() run_file_layout.addWidget(run_file_label) run_file_layout.addWidget(file_radio) run_file_layout.addWidget(run_file_browser) run_file_group.setLayout(run_file_layout) # ---- Debug ---- # Pdb run lines Group pdb_run_lines_group = QGroupBox(_("Run code while debugging")) pdb_run_lines_label = QLabel(_( "You can run several lines of code on each " "new prompt while debugging. Please " "introduce each one separated by semicolons " "and a space, for example:<br>" "<i>import matplotlib.pyplot as plt</i>")) pdb_run_lines_label.setWordWrap(True) pdb_run_lines_edit = self.create_lineedit( _("Lines:"), 'startup/pdb_run_lines', '', alignment=Qt.Horizontal) pdb_run_lines_layout = QVBoxLayout() pdb_run_lines_layout.addWidget(pdb_run_lines_label) pdb_run_lines_layout.addWidget(pdb_run_lines_edit) pdb_run_lines_group.setLayout(pdb_run_lines_layout) # Debug Group debug_group = QGroupBox(_("Debug")) debug_layout = QVBoxLayout() prevent_closing_box = newcb( _("Prevent editor from closing files while debugging"), 'pdb_prevent_closing', tip=_("This option prevents the user from closing a file while" " it is debugged.")) debug_layout.addWidget(prevent_closing_box) continue_box = newcb( _("Stop debugging on first line of files without breakpoints"), 'pdb_stop_first_line', tip=_("This option lets you decide if the debugger should" " stop on the first line while debugging if no breakpoints" " are present.")) debug_layout.addWidget(continue_box) libraries_box = newcb( _("Ignore Python libraries while debugging"), 'pdb_ignore_lib', tip=_("This option lets you decide if the debugger should " "ignore the system libraries while debugging.")) debug_layout.addWidget(libraries_box) execute_events_box = newcb( _("Process execute events while debugging"), 'pdb_execute_events', tip=_("This option lets you decide if the debugger should " "process the 'execute events' after each prompt, such as " "matplotlib 'show' command.")) debug_layout.addWidget(execute_events_box) exclamation_mark_box = newcb( _("Use exclamation mark prefix for Pdb commands"), 'pdb_use_exclamation_mark', tip=_("This option lets you decide if the Pdb commands should " "be prefixed by an exclamation mark. This helps in " "separating Pdb commands from Python code.")) debug_layout.addWidget(exclamation_mark_box) debug_group.setLayout(debug_layout) # ---- Advanced settings ---- # Enable Jedi completion jedi_group = QGroupBox(_("Jedi completion")) jedi_label = QLabel(_("Enable Jedi-based <tt>Tab</tt> completion " "in the IPython console; similar to the " "greedy completer, but without evaluating " "the code.<br>" "<b>Warning:</b> Slows down your console " "when working with large dataframes!")) jedi_label.setWordWrap(True) jedi_box = newcb(_("Use Jedi completion in the IPython console"), "jedi_completer", tip=_("<b>Warning</b>: " "Slows down your console when working with " "large dataframes!<br>" "Allows completion of nested lists etc.")) jedi_layout = QVBoxLayout() jedi_layout.addWidget(jedi_label) jedi_layout.addWidget(jedi_box) jedi_group.setLayout(jedi_layout) # Greedy completer group greedy_group = QGroupBox(_("Greedy completion")) greedy_label = QLabel(_("Enable <tt>Tab</tt> completion on elements " "of lists, results of function calls, etc, " "<i>without</i> assigning them to a variable, " "like <tt>li[0].<Tab></tt> or " "<tt>ins.meth().<Tab></tt> <br>" "<b>Warning:</b> Due to a bug, IPython's " "greedy completer requires a leading " "<tt><Space></tt> for some completions; " "e.g. <tt>np.sin(<Space>np.<Tab>" "</tt> works while <tt>np.sin(np.<Tab> " "</tt> doesn't.")) greedy_label.setWordWrap(True) greedy_box = newcb(_("Use greedy completion in the IPython console"), "greedy_completer", tip="<b>Warning</b>: It can be unsafe because the " "code is actually evaluated when you press " "<tt>Tab</tt>.") greedy_layout = QVBoxLayout() greedy_layout.addWidget(greedy_label) greedy_layout.addWidget(greedy_box) greedy_group.setLayout(greedy_layout) # Autocall group autocall_group = QGroupBox(_("Autocall")) autocall_label = QLabel(_("Autocall makes IPython automatically call " "any callable object even if you didn't " "type explicit parentheses.<br>" "For example, if you type <i>str 43</i> it " "becomes <i>str(43)</i> automatically.")) autocall_label.setWordWrap(True) smart = _('Smart') full = _('Full') autocall_opts = ((_('Off'), 0), (smart, 1), (full, 2)) autocall_box = self.create_combobox( _("Autocall: "), autocall_opts, 'autocall', default=0, tip=_("On <b>%s</b> mode, Autocall is not applied if " "there are no arguments after the callable. On " "<b>%s</b> mode, all callable objects are " "automatically called (even if no arguments are " "present).") % (smart, full)) autocall_layout = QVBoxLayout() autocall_layout.addWidget(autocall_label) autocall_layout.addWidget(autocall_box) autocall_group.setLayout(autocall_layout) # Sympy group sympy_group = QGroupBox(_("Symbolic mathematics")) sympy_label = QLabel(_("Perfom symbolic operations in the console " "(e.g. integrals, derivatives, vector " "calculus, etc) and get the outputs in a " "beautifully printed style (it requires the " "Sympy module).")) sympy_label.setWordWrap(True) sympy_box = newcb(_("Use symbolic math"), "symbolic_math", tip=_("This option loads the Sympy library to work " "with.<br>Please refer to its documentation " "to learn how to use it.")) sympy_layout = QVBoxLayout() sympy_layout.addWidget(sympy_label) sympy_layout.addWidget(sympy_box) sympy_group.setLayout(sympy_layout) # Prompts group prompts_group = QGroupBox(_("Prompts")) prompts_label = QLabel(_("Modify how Input and Output prompts are " "shown in the console.")) prompts_label.setWordWrap(True) in_prompt_edit = self.create_lineedit( _("Input prompt:"), 'in_prompt', '', _('Default is<br>' 'In [<span class="in-prompt-number">' '%i</span>]:'), alignment=Qt.Horizontal) out_prompt_edit = self.create_lineedit( _("Output prompt:"), 'out_prompt', '', _('Default is<br>' 'Out[<span class="out-prompt-number">' '%i</span>]:'), alignment=Qt.Horizontal) prompts_layout = QVBoxLayout() prompts_layout.addWidget(prompts_label) prompts_g_layout = QGridLayout() prompts_g_layout.addWidget(in_prompt_edit.label, 0, 0) prompts_g_layout.addWidget(in_prompt_edit.textbox, 0, 1) prompts_g_layout.addWidget(out_prompt_edit.label, 1, 0) prompts_g_layout.addWidget(out_prompt_edit.textbox, 1, 1) prompts_layout.addLayout(prompts_g_layout) prompts_group.setLayout(prompts_layout) # Windows adjustments windows_group = QGroupBox(_("Windows adjustments")) hide_cmd_windows = newcb( _("Hide command line output windows " "generated by the subprocess module."), 'hide_cmd_windows') windows_layout = QVBoxLayout() windows_layout.addWidget(hide_cmd_windows) windows_group.setLayout(windows_layout) # --- Tabs organization --- tabs = QTabWidget() tabs.addTab(self.create_tab(interface_group, comp_group, source_code_group), _("Display")) tabs.addTab(self.create_tab(pylab_group, backend_group, inline_group), _("Graphics")) tabs.addTab(self.create_tab(run_lines_group, run_file_group), _("Startup")) tabs.addTab(self.create_tab(debug_group, pdb_run_lines_group), _("Debugger")) tabs.addTab(self.create_tab(jedi_group, greedy_group, autocall_group, sympy_group, prompts_group, windows_group), _("Advanced settings")) vlayout = QVBoxLayout() vlayout.addWidget(tabs) self.setLayout(vlayout)
def setup_and_check(self, data, title='', readonly=False, xlabels=None, ylabels=None): """ Setup ArrayEditor: return False if data is not supported, True otherwise """ self.data = data readonly = readonly or not self.data.flags.writeable is_record_array = data.dtype.names is not None is_masked_array = isinstance(data, np.ma.MaskedArray) if data.ndim > 3: self.error(_("Arrays with more than 3 dimensions are not " "supported")) return False if xlabels is not None and len(xlabels) != self.data.shape[1]: self.error(_("The 'xlabels' argument length do no match array " "column number")) return False if ylabels is not None and len(ylabels) != self.data.shape[0]: self.error(_("The 'ylabels' argument length do no match array row " "number")) return False if not is_record_array: dtn = data.dtype.name if dtn == 'object': # If the array doesn't have shape, we can't display it if data.shape == (): self.error(_("Object arrays without shape are not " "supported")) return False # We don't know what's inside these arrays, so we can't handle # edits self.readonly = readonly = True elif (dtn not in SUPPORTED_FORMATS and not dtn.startswith('str') and not dtn.startswith('unicode')): arr = _("%s arrays") % data.dtype.name self.error(_("%s are currently not supported") % arr) return False self.layout = QGridLayout() self.setLayout(self.layout) self.setWindowIcon(ima.icon('arredit')) if title: title = to_text_string(title) + " - " + _("NumPy object array") else: title = _("Array editor") if readonly: title += ' (' + _('read only') + ')' self.setWindowTitle(title) # Stack widget self.stack = QStackedWidget(self) if is_record_array: for name in data.dtype.names: self.stack.addWidget(ArrayEditorWidget(self, data[name], readonly, xlabels, ylabels)) elif is_masked_array: self.stack.addWidget(ArrayEditorWidget(self, data, readonly, xlabels, ylabels)) self.stack.addWidget(ArrayEditorWidget(self, data.data, readonly, xlabels, ylabels)) self.stack.addWidget(ArrayEditorWidget(self, data.mask, readonly, xlabels, ylabels)) elif data.ndim == 3: pass else: self.stack.addWidget(ArrayEditorWidget(self, data, readonly, xlabels, ylabels)) self.arraywidget = self.stack.currentWidget() if self.arraywidget: self.arraywidget.model.dataChanged.connect( self.save_and_close_enable) self.stack.currentChanged.connect(self.current_widget_changed) self.layout.addWidget(self.stack, 1, 0) # Buttons configuration btn_layout = QHBoxLayout() if is_record_array or is_masked_array or data.ndim == 3: if is_record_array: btn_layout.addWidget(QLabel(_("Record array fields:"))) names = [] for name in data.dtype.names: field = data.dtype.fields[name] text = name if len(field) >= 3: title = field[2] if not is_text_string(title): title = repr(title) text += ' - '+title names.append(text) else: names = [_('Masked data'), _('Data'), _('Mask')] if data.ndim == 3: # QSpinBox self.index_spin = QSpinBox(self, keyboardTracking=False) self.index_spin.valueChanged.connect(self.change_active_widget) # QComboBox names = [str(i) for i in range(3)] ra_combo = QComboBox(self) ra_combo.addItems(names) ra_combo.currentIndexChanged.connect(self.current_dim_changed) # Adding the widgets to layout label = QLabel(_("Axis:")) btn_layout.addWidget(label) btn_layout.addWidget(ra_combo) self.shape_label = QLabel() btn_layout.addWidget(self.shape_label) label = QLabel(_("Index:")) btn_layout.addWidget(label) btn_layout.addWidget(self.index_spin) self.slicing_label = QLabel() btn_layout.addWidget(self.slicing_label) # set the widget to display when launched self.current_dim_changed(self.last_dim) else: ra_combo = QComboBox(self) ra_combo.currentIndexChanged.connect(self.stack.setCurrentIndex) ra_combo.addItems(names) btn_layout.addWidget(ra_combo) if is_masked_array: label = QLabel(_( "<u>Warning</u>: changes are applied separately")) label.setToolTip(_("For performance reasons, changes applied "\ "to masked array won't be reflected in "\ "array's data (and vice-versa).")) btn_layout.addWidget(label) btn_layout.addStretch() if not readonly: self.btn_save_and_close = QPushButton(_('Save and Close')) self.btn_save_and_close.setDisabled(True) self.btn_save_and_close.clicked.connect(self.accept) btn_layout.addWidget(self.btn_save_and_close) self.btn_close = QPushButton(_('Close')) self.btn_close.setAutoDefault(True) self.btn_close.setDefault(True) self.btn_close.clicked.connect(self.reject) btn_layout.addWidget(self.btn_close) self.layout.addLayout(btn_layout, 2, 0) self.setMinimumSize(400, 300) # Make the dialog act as a window self.setWindowFlags(Qt.Window) return True
class ArrayEditor(BaseDialog): """Array Editor Dialog""" 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.data = None self.arraywidget = None self.stack = None self.layout = None self.btn_save_and_close = None self.btn_close = None # Values for 3d array editor self.dim_indexes = [{}, {}, {}] self.last_dim = 0 # Adjust this for changing the startup dimension def setup_and_check(self, data, title='', readonly=False, xlabels=None, ylabels=None): """ Setup ArrayEditor: return False if data is not supported, True otherwise """ self.data = data readonly = readonly or not self.data.flags.writeable is_record_array = data.dtype.names is not None is_masked_array = isinstance(data, np.ma.MaskedArray) if data.ndim > 3: self.error(_("Arrays with more than 3 dimensions are not " "supported")) return False if xlabels is not None and len(xlabels) != self.data.shape[1]: self.error(_("The 'xlabels' argument length do no match array " "column number")) return False if ylabels is not None and len(ylabels) != self.data.shape[0]: self.error(_("The 'ylabels' argument length do no match array row " "number")) return False if not is_record_array: dtn = data.dtype.name if dtn == 'object': # If the array doesn't have shape, we can't display it if data.shape == (): self.error(_("Object arrays without shape are not " "supported")) return False # We don't know what's inside these arrays, so we can't handle # edits self.readonly = readonly = True elif (dtn not in SUPPORTED_FORMATS and not dtn.startswith('str') and not dtn.startswith('unicode')): arr = _("%s arrays") % data.dtype.name self.error(_("%s are currently not supported") % arr) return False self.layout = QGridLayout() self.setLayout(self.layout) self.setWindowIcon(ima.icon('arredit')) if title: title = to_text_string(title) + " - " + _("NumPy object array") else: title = _("Array editor") if readonly: title += ' (' + _('read only') + ')' self.setWindowTitle(title) # Stack widget self.stack = QStackedWidget(self) if is_record_array: for name in data.dtype.names: self.stack.addWidget(ArrayEditorWidget(self, data[name], readonly, xlabels, ylabels)) elif is_masked_array: self.stack.addWidget(ArrayEditorWidget(self, data, readonly, xlabels, ylabels)) self.stack.addWidget(ArrayEditorWidget(self, data.data, readonly, xlabels, ylabels)) self.stack.addWidget(ArrayEditorWidget(self, data.mask, readonly, xlabels, ylabels)) elif data.ndim == 3: pass else: self.stack.addWidget(ArrayEditorWidget(self, data, readonly, xlabels, ylabels)) self.arraywidget = self.stack.currentWidget() if self.arraywidget: self.arraywidget.model.dataChanged.connect( self.save_and_close_enable) self.stack.currentChanged.connect(self.current_widget_changed) self.layout.addWidget(self.stack, 1, 0) # Buttons configuration btn_layout = QHBoxLayout() if is_record_array or is_masked_array or data.ndim == 3: if is_record_array: btn_layout.addWidget(QLabel(_("Record array fields:"))) names = [] for name in data.dtype.names: field = data.dtype.fields[name] text = name if len(field) >= 3: title = field[2] if not is_text_string(title): title = repr(title) text += ' - '+title names.append(text) else: names = [_('Masked data'), _('Data'), _('Mask')] if data.ndim == 3: # QSpinBox self.index_spin = QSpinBox(self, keyboardTracking=False) self.index_spin.valueChanged.connect(self.change_active_widget) # QComboBox names = [str(i) for i in range(3)] ra_combo = QComboBox(self) ra_combo.addItems(names) ra_combo.currentIndexChanged.connect(self.current_dim_changed) # Adding the widgets to layout label = QLabel(_("Axis:")) btn_layout.addWidget(label) btn_layout.addWidget(ra_combo) self.shape_label = QLabel() btn_layout.addWidget(self.shape_label) label = QLabel(_("Index:")) btn_layout.addWidget(label) btn_layout.addWidget(self.index_spin) self.slicing_label = QLabel() btn_layout.addWidget(self.slicing_label) # set the widget to display when launched self.current_dim_changed(self.last_dim) else: ra_combo = QComboBox(self) ra_combo.currentIndexChanged.connect(self.stack.setCurrentIndex) ra_combo.addItems(names) btn_layout.addWidget(ra_combo) if is_masked_array: label = QLabel(_( "<u>Warning</u>: changes are applied separately")) label.setToolTip(_("For performance reasons, changes applied "\ "to masked array won't be reflected in "\ "array's data (and vice-versa).")) btn_layout.addWidget(label) btn_layout.addStretch() if not readonly: self.btn_save_and_close = QPushButton(_('Save and Close')) self.btn_save_and_close.setDisabled(True) self.btn_save_and_close.clicked.connect(self.accept) btn_layout.addWidget(self.btn_save_and_close) self.btn_close = QPushButton(_('Close')) self.btn_close.setAutoDefault(True) self.btn_close.setDefault(True) self.btn_close.clicked.connect(self.reject) btn_layout.addWidget(self.btn_close) self.layout.addLayout(btn_layout, 2, 0) self.setMinimumSize(400, 300) # Make the dialog act as a window self.setWindowFlags(Qt.Window) return True @Slot(QModelIndex, QModelIndex) def save_and_close_enable(self, left_top, bottom_right): """Handle the data change event to enable the save and close button.""" if self.btn_save_and_close: self.btn_save_and_close.setEnabled(True) self.btn_save_and_close.setAutoDefault(True) self.btn_save_and_close.setDefault(True) def current_widget_changed(self, index): self.arraywidget = self.stack.widget(index) self.arraywidget.model.dataChanged.connect(self.save_and_close_enable) def change_active_widget(self, index): """ This is implemented for handling negative values in index for 3d arrays, to give the same behavior as slicing """ string_index = [':']*3 string_index[self.last_dim] = '<font color=red>%i</font>' self.slicing_label.setText((r"Slicing: [" + ", ".join(string_index) + "]") % index) if index < 0: data_index = self.data.shape[self.last_dim] + index else: data_index = index slice_index = [slice(None)]*3 slice_index[self.last_dim] = data_index stack_index = self.dim_indexes[self.last_dim].get(data_index) if stack_index is None: stack_index = self.stack.count() try: self.stack.addWidget(ArrayEditorWidget( self, self.data[tuple(slice_index)])) except IndexError: # Handle arrays of size 0 in one axis self.stack.addWidget(ArrayEditorWidget(self, self.data)) self.dim_indexes[self.last_dim][data_index] = stack_index self.stack.update() self.stack.setCurrentIndex(stack_index) def current_dim_changed(self, index): """ This change the active axis the array editor is plotting over in 3D """ self.last_dim = index string_size = ['%i']*3 string_size[index] = '<font color=red>%i</font>' self.shape_label.setText(('Shape: (' + ', '.join(string_size) + ') ') % self.data.shape) if self.index_spin.value() != 0: self.index_spin.setValue(0) else: # this is done since if the value is currently 0 it does not emit # currentIndexChanged(int) self.change_active_widget(0) self.index_spin.setRange(-self.data.shape[index], self.data.shape[index]-1) @Slot() def accept(self): """Reimplement Qt method.""" try: for index in range(self.stack.count()): self.stack.widget(index).accept_changes() QDialog.accept(self) except RuntimeError: # Sometimes under CI testing the object the following error appears # RuntimeError: wrapped C/C++ object has been deleted pass def get_value(self): """Return modified array -- this is *not* a copy""" # It is important to avoid accessing Qt C++ object as it has probably # already been destroyed, due to the Qt.WA_DeleteOnClose attribute return self.data def error(self, message): """An error occurred, closing the dialog box""" QMessageBox.critical(self, _("Array editor"), message) self.setAttribute(Qt.WA_DeleteOnClose) self.reject() @Slot() def reject(self): """Reimplement Qt method""" if self.arraywidget is not None: for index in range(self.stack.count()): self.stack.widget(index).reject_changes() QDialog.reject(self)
def __init__(self, parent, language=None, cmd='', host='127.0.0.1', port=2084, args='', external=False, stdio=False, configurations={}, **kwargs): super(LSPServerEditor, self).__init__(parent) description = _( "To create a new server configuration, you need to select a " "programming language, set the command to start its associated " "server and enter any arguments that should be passed to it on " "startup. Additionally, you can set the server's hostname and " "port if connecting to an external server, " "or to a local one using TCP instead of stdio pipes." "<br><br>" "<i>Note</i>: You can use the placeholders <tt>{host}</tt> and " "<tt>{port}</tt> in the server arguments field to automatically " "fill in the respective values.<br>") self.parent = parent self.external = external # Widgets self.server_settings_description = QLabel(description) self.lang_cb = QComboBox(self) self.external_cb = QCheckBox(_('External server'), self) self.host_label = QLabel(_('Host:')) self.host_input = QLineEdit(self) self.port_label = QLabel(_('Port:')) self.port_spinner = QSpinBox(self) self.cmd_label = QLabel(_('Command:')) self.cmd_input = QLineEdit(self) self.args_label = QLabel(_('Arguments:')) self.args_input = QLineEdit(self) self.json_label = QLabel(self.JSON_VALID, self) self.conf_label = QLabel(_('<b>Server Configuration:</b>')) self.conf_input = CodeEditor(None) self.bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.button_ok = self.bbox.button(QDialogButtonBox.Ok) self.button_cancel = self.bbox.button(QDialogButtonBox.Cancel) # Widget setup self.setMinimumSize(self.MIN_SIZE) self.setWindowTitle(_('LSP server editor')) self.server_settings_description.setWordWrap(True) self.lang_cb.setToolTip( _('Programming language provided by the LSP server')) self.lang_cb.addItem(_('Select a language')) self.lang_cb.addItems(LSP_LANGUAGES) self.button_ok.setEnabled(False) if language is not None: idx = LSP_LANGUAGES.index(language) self.lang_cb.setCurrentIndex(idx + 1) self.button_ok.setEnabled(True) self.host_input.setPlaceholderText('127.0.0.1') self.host_input.setText(host) self.host_input.textChanged.connect(lambda x: self.validate()) self.port_spinner.setToolTip(_('TCP port number of the server')) self.port_spinner.setMinimum(1) self.port_spinner.setMaximum(60000) self.port_spinner.setValue(port) self.cmd_input.setText(cmd) self.cmd_input.setPlaceholderText('/absolute/path/to/command') self.args_input.setToolTip( _('Additional arguments required to start the server')) self.args_input.setText(args) self.args_input.setPlaceholderText(r'--host {host} --port {port}') self.conf_input.setup_editor(language='json', color_scheme=CONF.get( 'appearance', 'selected'), wrap=False, edge_line=True, highlight_current_line=True, highlight_current_cell=True, occurrence_highlighting=True, auto_unindent=True, font=get_font(), filename='config.json', folding=False) self.conf_input.set_language('json', 'config.json') self.conf_input.setToolTip( _('Additional LSP server configuration ' 'set at runtime. JSON required')) try: conf_text = json.dumps(configurations, indent=4, sort_keys=True) except Exception: conf_text = '{}' self.conf_input.set_text(conf_text) self.external_cb.setToolTip( _('Check if the server runs on a remote location')) self.external_cb.setChecked(external) self.stdio_cb = QCheckBox(_('Use stdio pipes for communication'), self) self.stdio_cb.setToolTip( _('Check if the server communicates ' 'using stdin/out pipes')) self.stdio_cb.setChecked(stdio) # Layout setup hlayout = QHBoxLayout() general_vlayout = QVBoxLayout() general_vlayout.addWidget(self.server_settings_description) vlayout = QVBoxLayout() lang_group = QGroupBox(_('Language')) lang_layout = QVBoxLayout() lang_layout.addWidget(self.lang_cb) lang_group.setLayout(lang_layout) vlayout.addWidget(lang_group) server_group = QGroupBox(_('Language server')) server_layout = QGridLayout() server_layout.addWidget(self.cmd_label, 0, 0) server_layout.addWidget(self.cmd_input, 0, 1) server_layout.addWidget(self.args_label, 1, 0) server_layout.addWidget(self.args_input, 1, 1) server_group.setLayout(server_layout) vlayout.addWidget(server_group) address_group = QGroupBox(_('Server address')) host_layout = QVBoxLayout() host_layout.addWidget(self.host_label) host_layout.addWidget(self.host_input) port_layout = QVBoxLayout() port_layout.addWidget(self.port_label) port_layout.addWidget(self.port_spinner) conn_info_layout = QHBoxLayout() conn_info_layout.addLayout(host_layout) conn_info_layout.addLayout(port_layout) address_group.setLayout(conn_info_layout) vlayout.addWidget(address_group) advanced_group = QGroupBox(_('Advanced')) advanced_layout = QVBoxLayout() advanced_layout.addWidget(self.external_cb) advanced_layout.addWidget(self.stdio_cb) advanced_group.setLayout(advanced_layout) vlayout.addWidget(advanced_group) conf_layout = QVBoxLayout() conf_layout.addWidget(self.conf_label) conf_layout.addWidget(self.conf_input) conf_layout.addWidget(self.json_label) vlayout.addStretch() hlayout.addLayout(vlayout, 2) hlayout.addLayout(conf_layout, 3) general_vlayout.addLayout(hlayout) general_vlayout.addWidget(self.bbox) self.setLayout(general_vlayout) self.form_status(False) # Signals if not external: self.cmd_input.textChanged.connect(lambda x: self.validate()) self.external_cb.stateChanged.connect(self.set_local_options) self.stdio_cb.stateChanged.connect(self.set_stdio_options) self.lang_cb.currentIndexChanged.connect(self.lang_selection_changed) self.conf_input.textChanged.connect(self.validate) self.bbox.accepted.connect(self.accept) self.bbox.rejected.connect(self.reject) # Final setup if language is not None: self.form_status(True) self.validate() if stdio: self.set_stdio_options(True) if external: self.set_local_options(True)
def __init__(self, parent=None): super(KernelConnectionDialog, self).__init__(parent) self.setWindowTitle(_('Connect to an existing kernel')) main_label = QLabel(_( "<p>Please select the JSON connection file (<i>e.g.</i> " "<tt>kernel-1234.json</tt>) of the existing kernel, and enter " "the SSH information if connecting to a remote machine. " "To learn more about starting external kernels and connecting " "to them, see <a href=\"https://docs.spyder-ide.org/" "ipythonconsole.html#connect-to-an-external-kernel\">" "our documentation</a>.</p>")) main_label.setWordWrap(True) main_label.setAlignment(Qt.AlignJustify) main_label.setOpenExternalLinks(True) # Connection file cf_label = QLabel(_('Connection file:')) self.cf = QLineEdit() self.cf.setPlaceholderText(_('Kernel connection file path')) self.cf.setMinimumWidth(350) cf_open_btn = QPushButton(_('Browse')) cf_open_btn.clicked.connect(self.select_connection_file) cf_layout = QHBoxLayout() cf_layout.addWidget(cf_label) cf_layout.addWidget(self.cf) cf_layout.addWidget(cf_open_btn) # Remote kernel groupbox self.rm_group = QGroupBox(_("This is a remote kernel (via SSH)")) # SSH connection hn_label = QLabel(_('Hostname:')) self.hn = QLineEdit() pn_label = QLabel(_('Port:')) self.pn = QLineEdit() self.pn.setMaximumWidth(75) un_label = QLabel(_('Username:'******'Password:'******'SSH keyfile:')) self.pw = QLineEdit() self.pw.setEchoMode(QLineEdit.Password) self.pw_radio.toggled.connect(self.pw.setEnabled) self.kf_radio.toggled.connect(self.pw.setDisabled) self.kf = QLineEdit() kf_open_btn = QPushButton(_('Browse')) kf_open_btn.clicked.connect(self.select_ssh_key) kf_layout = QHBoxLayout() kf_layout.addWidget(self.kf) kf_layout.addWidget(kf_open_btn) kfp_label = QLabel(_('Passphase:')) self.kfp = QLineEdit() self.kfp.setPlaceholderText(_('Optional')) self.kfp.setEchoMode(QLineEdit.Password) self.kf_radio.toggled.connect(self.kf.setEnabled) self.kf_radio.toggled.connect(self.kfp.setEnabled) self.kf_radio.toggled.connect(kf_open_btn.setEnabled) self.kf_radio.toggled.connect(kfp_label.setEnabled) self.pw_radio.toggled.connect(self.kf.setDisabled) self.pw_radio.toggled.connect(self.kfp.setDisabled) self.pw_radio.toggled.connect(kf_open_btn.setDisabled) self.pw_radio.toggled.connect(kfp_label.setDisabled) # SSH layout ssh_layout = QGridLayout() ssh_layout.addWidget(hn_label, 0, 0, 1, 2) ssh_layout.addWidget(self.hn, 0, 2) ssh_layout.addWidget(pn_label, 0, 3) ssh_layout.addWidget(self.pn, 0, 4) ssh_layout.addWidget(un_label, 1, 0, 1, 2) ssh_layout.addWidget(self.un, 1, 2, 1, 3) # SSH authentication layout auth_layout = QGridLayout() auth_layout.addWidget(self.pw_radio, 1, 0) auth_layout.addWidget(pw_label, 1, 1) auth_layout.addWidget(self.pw, 1, 2) auth_layout.addWidget(self.kf_radio, 2, 0) auth_layout.addWidget(kf_label, 2, 1) auth_layout.addLayout(kf_layout, 2, 2) auth_layout.addWidget(kfp_label, 3, 1) auth_layout.addWidget(self.kfp, 3, 2) auth_group.setLayout(auth_layout) # Remote kernel layout rm_layout = QVBoxLayout() rm_layout.addLayout(ssh_layout) rm_layout.addSpacerItem(QSpacerItem(QSpacerItem(0, 8))) rm_layout.addWidget(auth_group) self.rm_group.setLayout(rm_layout) self.rm_group.setCheckable(True) self.rm_group.toggled.connect(self.pw_radio.setChecked) # Ok and Cancel buttons self.accept_btns = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self) self.accept_btns.accepted.connect(self.save_connection_settings) self.accept_btns.accepted.connect(self.accept) self.accept_btns.rejected.connect(self.reject) # Save connection settings checkbox self.save_layout = QCheckBox(self) self.save_layout.setText(_("Save connection settings")) btns_layout = QHBoxLayout() btns_layout.addWidget(self.save_layout) btns_layout.addWidget(self.accept_btns) # Dialog layout layout = QVBoxLayout(self) layout.addWidget(main_label) layout.addSpacerItem(QSpacerItem(QSpacerItem(0, 8))) layout.addLayout(cf_layout) layout.addSpacerItem(QSpacerItem(QSpacerItem(0, 12))) layout.addWidget(self.rm_group) layout.addLayout(btns_layout) self.load_connection_settings()
def __init__(self, napari_viewer): super().__init__() self.viewer = napari_viewer self.viewer.events.layers_change.connect(self._on_layer_change) # thread self.thread = QThread() self.worker = SPipelineWorker() self.worker.moveToThread(self.thread) self.thread.started.connect(self.worker.run) self.worker.finished.connect(self.thread.quit) self.worker.finished.connect(self.set_outputs) layout = QGridLayout() # input image layer self._images_layers = QComboBox() # pipeline file self._pipeline_edit = QLineEdit() browse_button = QPushButton('...') browse_button.released.connect(self._browser_pipeline) # run self.run_btn = QPushButton('Run') self.run_btn.released.connect(self._run) # progress self.log_widget = SLogWidget() self.worker.progress.connect(self.log_widget.set_progress) self.worker.log.connect(self.log_widget.add_log) layout.addWidget(QLabel('Image:'), 0, 0) layout.addWidget(self._images_layers, 0, 1, 1, 2) layout.addWidget(QLabel('Pipeline:'), 1, 0) layout.addWidget(self._pipeline_edit, 1, 1) layout.addWidget(browse_button, 1, 2) layout.addWidget(self.run_btn, 2, 0, 1, 3) layout.addWidget(self.log_widget, 3, 0, 1, 3) layout.addWidget(QWidget(), 4, 0, 1, 3, QtCore.Qt.AlignTop) self.setLayout(layout) self._on_layer_change(None)
def create_statistics(self, wid, typ='pos'): text, unit, names, _ = self._get_properties(typ) wid = QWidget(wid) hbl = QHBoxLayout(wid) hbl.addStretch() grpbx = QGroupBox('Statistics', wid) hbl.addWidget(grpbx) hbl.addStretch() gdl = QGridLayout(grpbx) gdl.setHorizontalSpacing(20) gdl.setVerticalSpacing(20) stats = ('MeanValue', 'Sigma', 'MinValue', 'MaxValue') for j, stat in enumerate(('Average', 'Sigma', 'Minimum', 'Maximum')): lab = QLabel(stat, wid) lab.setAlignment(Qt.AlignCenter) gdl.addWidget(lab, 0, j + 1) for i, name in enumerate(names): lab = QLabel(text[:3] + name, wid) lab.setAlignment(Qt.AlignCenter) gdl.addWidget(lab, i + 1, 0) for j, stat in enumerate(stats): lab = SiriusLabel( wid, init_channel=self.get_pvname(name + '_STATS' + stat + '_RBV')) lab.setAlignment(Qt.AlignCenter) lab.unit_changed(unit) lab.showUnits = True lab.precisionFromPV = False lab.precision = 3 gdl.addWidget(lab, i + 1, j + 1) return wid
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 _setupIOCControlLayout(self): lay = QGridLayout() lb_sts = QLabel('<h4>Status</h4>', self) self.led_sts = _StatusLed(self, self.ioc_prefix.substitute( propty='Status-Mon')) lay.addWidget(lb_sts, 0, 0) lay.addWidget(self.led_sts, 0, 1, alignment=Qt.AlignLeft) lb_conf = QLabel('<h4>Configuration</h4>') self.bt_dtls = QPushButton(qta.icon('fa5s.list-ul'), '', self) _hlautil.connect_window( self.bt_dtls, _CorrParamsDetailWindow, parent=self, acc=self.acc, opticsparam=self.param, prefix=self.prefix, fams=self.fams) lay.addWidget(lb_conf, 2, 0, 1, 2) lay.addWidget(self.bt_dtls, 2, 2, alignment=Qt.AlignRight) lb_cname = QLabel('Name', self) self.le_cname = _ConfigLineEdit( self, self.ioc_prefix.substitute( propty='ConfigName-SP')) self.lb_cname = PyDMLabel(self, self.ioc_prefix.substitute( propty='ConfigName-RB')) lay.addWidget(lb_cname, 3, 0) lay.addWidget(self.le_cname, 3, 1, 1, 2) lay.addWidget(self.lb_cname, 4, 1, 1, 2) row = 5 if self.acc == 'SI': lay.addItem( QSpacerItem(1, 20, QSzPly.Ignored, QSzPly.Fixed), 5, 0) row = 6 if self.param == 'chrom': lb_meas_chrom = QLabel('<h4>Chrom. Measurement</h4>') lay.addWidget(lb_meas_chrom, 6, 0, 1, 3) lb_meas_chrom_dfRF = QLabel('ΔFreq RF [Hz]', self) self.sb_meas_chrom_dfRF = PyDMSpinbox( self, self.ioc_prefix.substitute( propty='MeasChromDeltaFreqRF-SP')) self.sb_meas_chrom_dfRF.showStepExponent = False self.lb_meas_chrom_dfRF = PyDMLabel( self, self.ioc_prefix.substitute( propty='MeasChromDeltaFreqRF-RB')) lay.addWidget(lb_meas_chrom_dfRF, 7, 0) lay.addWidget(self.sb_meas_chrom_dfRF, 7, 1) lay.addWidget(self.lb_meas_chrom_dfRF, 7, 2) lb_meas_chrom_wait = QLabel('Wait Tune [s]', self) self.sb_meas_chrom_wait = PyDMSpinbox( self, self.ioc_prefix.substitute( propty='MeasChromWaitTune-SP')) self.sb_meas_chrom_wait.showStepExponent = False self.lb_meas_chrom_wait = PyDMLabel( self, self.ioc_prefix.substitute( propty='MeasChromWaitTune-RB')) lay.addWidget(lb_meas_chrom_wait, 8, 0) lay.addWidget(self.sb_meas_chrom_wait, 8, 1) lay.addWidget(self.lb_meas_chrom_wait, 8, 2) lb_meas_chrom_nrsteps = QLabel('Nr Steps', self) self.sb_meas_chrom_nrsteps = PyDMSpinbox( self, self.ioc_prefix.substitute( propty='MeasChromNrSteps-SP')) self.sb_meas_chrom_nrsteps.showStepExponent = False self.lb_meas_chrom_nrsteps = PyDMLabel( self, self.ioc_prefix.substitute( propty='MeasChromNrSteps-RB')) lay.addWidget(lb_meas_chrom_nrsteps, 9, 0) lay.addWidget(self.sb_meas_chrom_nrsteps, 9, 1) lay.addWidget(self.lb_meas_chrom_nrsteps, 9, 2) lay.addItem( QSpacerItem(1, 20, QSzPly.Ignored, QSzPly.Fixed), 10, 0) lb_meas_chrom_x = QLabel('Meas. Chrom X', self) self.lb_meas_chrom_x = PyDMLabel( self, self.ioc_prefix.substitute( propty='MeasChromX-Mon')) lay.addWidget(lb_meas_chrom_x, 11, 0) lay.addWidget(self.lb_meas_chrom_x, 11, 1) lb_meas_chrom_y = QLabel('Meas. Chrom Y', self) self.lb_meas_chrom_y = PyDMLabel( self, self.ioc_prefix.substitute( propty='MeasChromY-Mon')) lay.addWidget(lb_meas_chrom_y, 12, 0) lay.addWidget(self.lb_meas_chrom_y, 12, 1) lay.addItem( QSpacerItem(1, 20, QSzPly.Ignored, QSzPly.Fixed), 13, 0) self.lb_meas_chrom_sts = PyDMLabel( self, self.ioc_prefix.substitute( propty='MeasChromStatus-Mon')) self.bt_meas_chrom_start = PyDMPushButton( self, icon=qta.icon('fa5s.play'), label='', init_channel=self.ioc_prefix.substitute( propty='MeasChrom-Cmd'), pressValue=_Const.MeasCmd.Start) self.bt_meas_chrom_start.setObjectName('start') self.bt_meas_chrom_start.setStyleSheet( '#start{min-width:25px; max-width:25px; icon-size:20px;}') self.bt_meas_chrom_stop = PyDMPushButton( self, icon=qta.icon('fa5s.stop'), label='', init_channel=self.ioc_prefix.substitute( propty='MeasChrom-Cmd'), pressValue=_Const.MeasCmd.Stop) self.bt_meas_chrom_stop.setObjectName('stop') self.bt_meas_chrom_stop.setStyleSheet( '#stop{min-width:25px; max-width:25px; icon-size:20px;}') self.bt_meas_chrom_rst = PyDMPushButton( self, icon=qta.icon('fa5s.sync'), label='', init_channel=self.ioc_prefix.substitute( propty='MeasChrom-Cmd'), pressValue=_Const.MeasCmd.Reset) self.bt_meas_chrom_rst.setObjectName('rst') self.bt_meas_chrom_rst.setStyleSheet( '#rst{min-width:25px; max-width:25px; icon-size:20px;}') hbox_cmd = QHBoxLayout() hbox_cmd.addWidget(self.bt_meas_chrom_start) hbox_cmd.addWidget(self.bt_meas_chrom_stop) hbox_cmd.addWidget(self.bt_meas_chrom_rst) lay.addWidget(self.lb_meas_chrom_sts, 14, 0, 1, 2) lay.addLayout(hbox_cmd, 14, 2) lay.addItem( QSpacerItem(1, 20, QSzPly.Ignored, QSzPly.Fixed), 15, 0) row = 15 # configuration measurement lb_meas_conf = QLabel('<h4>Config. Measurement</h4>') lay.addWidget(lb_meas_conf, row+1, 0, 1, 3) mag_type = 'Q' if self.param == 'tune' else 'S' unit = '[1/m]' if self.param == 'tune' else '[1/m2]' lb_meas_conf_dfamF = QLabel( 'Fam. Δ'+self.intstrength+' '+mag_type+'F '+unit, self) self.sb_meas_conf_dfamF = PyDMSpinbox( self, self.ioc_prefix.substitute( propty='MeasConfigDelta'+self.intstrength + 'Fam'+mag_type+'F-SP')) self.sb_meas_conf_dfamF.showStepExponent = False self.lb_meas_conf_dfamF = PyDMLabel( self, self.ioc_prefix.substitute( propty='MeasConfigDelta'+self.intstrength + 'Fam'+mag_type+'F-RB')) lay.addWidget(lb_meas_conf_dfamF, row+2, 0) lay.addWidget(self.sb_meas_conf_dfamF, row+2, 1) lay.addWidget(self.lb_meas_conf_dfamF, row+2, 2) lb_meas_conf_dfamD = QLabel( 'Fam. Δ'+self.intstrength+' '+mag_type+'D '+unit, self) self.sb_meas_conf_dfamD = PyDMSpinbox( self, self.ioc_prefix.substitute( propty='MeasConfigDelta'+self.intstrength + 'Fam'+mag_type+'D-SP')) self.sb_meas_conf_dfamD.showStepExponent = False self.lb_meas_conf_dfamD = PyDMLabel( self, self.ioc_prefix.substitute( propty='MeasConfigDelta'+self.intstrength + 'Fam'+mag_type+'D-RB')) lay.addWidget(lb_meas_conf_dfamD, row+3, 0) lay.addWidget(self.sb_meas_conf_dfamD, row+3, 1) lay.addWidget(self.lb_meas_conf_dfamD, row+3, 2) lb_meas_conf_wait = QLabel('Wait [s]', self) self.sb_meas_conf_wait = PyDMSpinbox( self, self.ioc_prefix.substitute(propty='MeasConfigWait-SP')) self.sb_meas_conf_wait.showStepExponent = False self.lb_meas_conf_wait = PyDMLabel( self, self.ioc_prefix.substitute(propty='MeasConfigWait-RB')) lay.addWidget(lb_meas_conf_wait, row+4, 0) lay.addWidget(self.sb_meas_conf_wait, row+4, 1) lay.addWidget(self.lb_meas_conf_wait, row+4, 2) lb_meas_conf_cname = QLabel('Name to save', self) self.le_meas_conf_name = PyDMLineEdit( self, self.ioc_prefix.substitute(propty='MeasConfigName-SP')) self.lb_meas_conf_name = PyDMLabel( self, self.ioc_prefix.substitute(propty='MeasConfigName-RB')) lay.addWidget(lb_meas_conf_cname, row+5, 0) lay.addWidget(self.le_meas_conf_name, row+5, 1, 1, 2) lay.addWidget(self.lb_meas_conf_name, row+6, 1, 1, 2) lb_meas_conf_save = QLabel('Force Save', self) self.bt_meas_conf_save = PyDMPushButton( self, icon=qta.icon('mdi.content-save'), label='', init_channel=self.ioc_prefix.substitute( propty='MeasConfigSave-Cmd'), pressValue=1) self.bt_meas_conf_save.setObjectName('save') self.bt_meas_conf_save.setStyleSheet( '#save{min-width:25px; max-width:25px; icon-size:20px;}') lay.addWidget(lb_meas_conf_save, row+7, 0) lay.addWidget( self.bt_meas_conf_save, row+7, 1, alignment=Qt.AlignLeft) lay.addItem( QSpacerItem(1, 20, QSzPly.Ignored, QSzPly.Fixed), row+8, 0) self.lb_meas_conf_sts = PyDMLabel( self, self.ioc_prefix.substitute( propty='MeasConfigStatus-Mon')) self.bt_meas_conf_start = PyDMPushButton( self, icon=qta.icon('fa5s.play'), label='', init_channel=self.ioc_prefix.substitute( propty='MeasConfig-Cmd'), pressValue=_Const.MeasCmd.Start) self.bt_meas_conf_start.setObjectName('start') self.bt_meas_conf_start.setStyleSheet( '#start{min-width:25px; max-width:25px; icon-size:20px;}') self.bt_meas_conf_stop = PyDMPushButton( self, icon=qta.icon('fa5s.stop'), label='', init_channel=self.ioc_prefix.substitute( propty='MeasConfig-Cmd'), pressValue=_Const.MeasCmd.Stop) self.bt_meas_conf_stop.setObjectName('stop') self.bt_meas_conf_stop.setStyleSheet( '#stop{min-width:25px; max-width:25px; icon-size:20px;}') self.bt_meas_conf_rst = PyDMPushButton( self, icon=qta.icon('fa5s.sync'), label='', init_channel=self.ioc_prefix.substitute( propty='MeasConfig-Cmd'), pressValue=_Const.MeasCmd.Reset) self.bt_meas_conf_rst.setObjectName('rst') self.bt_meas_conf_rst.setStyleSheet( '#rst{min-width:25px; max-width:25px; icon-size:20px;}') hbox_cmd = QHBoxLayout() hbox_cmd.addWidget(self.bt_meas_conf_start) hbox_cmd.addWidget(self.bt_meas_conf_stop) hbox_cmd.addWidget(self.bt_meas_conf_rst) lay.addWidget(self.lb_meas_conf_sts, row+9, 0, 1, 2) lay.addLayout(hbox_cmd, row+9, 2) lay.addItem( QSpacerItem(1, 20, QSzPly.Ignored, QSzPly.Fixed), row+10, 0) # correction settings lb_corr = QLabel('<h4>Settings</h4>') lay.addWidget(lb_corr, row+11, 0, 1, 3) lb_meth = QLabel('Method', self) self.cb_method = PyDMEnumComboBox( self, self.ioc_prefix.substitute(propty='CorrMeth-Sel')) self.lb_method = PyDMLabel( self, self.ioc_prefix.substitute(propty='CorrMeth-Sts')) lay.addWidget(lb_meth, row+12, 0) lay.addWidget(self.cb_method, row+12, 1) lay.addWidget(self.lb_method, row+12, 2) lb_grp = QLabel('Grouping', self) self.cb_group = PyDMEnumComboBox( self, self.ioc_prefix.substitute(propty='CorrGroup-Sel')) self.lb_group = PyDMLabel( self, self.ioc_prefix.substitute(propty='CorrGroup-Sts')) lay.addWidget(lb_grp, row+13, 0) lay.addWidget(self.cb_group, row+13, 1) lay.addWidget(self.lb_group, row+13, 2) if self.param == 'tune': lb_sync = QLabel('Sync', self) self.bt_sync = PyDMStateButton( self, self.ioc_prefix.substitute(propty='SyncCorr-Sel')) self.bt_sync.shape = 1 self.lb_sync = PyDMLabel( self, self.ioc_prefix.substitute(propty='SyncCorr-Sts')) lay.addWidget(lb_sync, row+14, 0) lay.addWidget(self.bt_sync, row+14, 1) lay.addWidget(self.lb_sync, row+14, 2) row = row + 15 lay.addItem( QSpacerItem(1, 20, QSzPly.Ignored, QSzPly.Expanding), row, 0) return lay
def add_color_scheme_stack(self, scheme_name, custom=False): """Add a stack for a given scheme and connects the CONF values.""" color_scheme_groups = [(_('Text'), [ "normal", "comment", "string", "number", "keyword", "builtin", "definition", "instance", ]), (_('Highlight'), [ "currentcell", "currentline", "occurrence", "matched_p", "unmatched_p", "ctrlclick" ]), (_('Background'), ["background", "sideareas"])] parent = self.parent line_edit = parent.create_lineedit(_("Scheme name:"), '{0}/name'.format(scheme_name)) self.widgets[scheme_name] = {} # Widget setup line_edit.label.setAlignment(Qt.AlignRight | Qt.AlignVCenter) self.setWindowTitle(_('Color scheme editor')) # Layout name_layout = QHBoxLayout() name_layout.addWidget(line_edit.label) name_layout.addWidget(line_edit.textbox) self.scheme_name_textbox[scheme_name] = line_edit.textbox if not custom: line_edit.textbox.setDisabled(True) if not self.isVisible(): line_edit.setVisible(False) cs_layout = QVBoxLayout() cs_layout.addLayout(name_layout) h_layout = QHBoxLayout() v_layout = QVBoxLayout() for index, item in enumerate(color_scheme_groups): group_name, keys = item group_layout = QGridLayout() for row, key in enumerate(keys): option = "{0}/{1}".format(scheme_name, key) value = self.parent.get_option(option) name = syntaxhighlighters.COLOR_SCHEME_KEYS[key] if is_text_string(value): label, clayout = parent.create_coloredit( name, option, without_layout=True, ) label.setAlignment(Qt.AlignRight | Qt.AlignVCenter) group_layout.addWidget(label, row + 1, 0) group_layout.addLayout(clayout, row + 1, 1) # Needed to update temp scheme to obtain instant preview self.widgets[scheme_name][key] = [clayout] else: label, clayout, cb_bold, cb_italic = parent.create_scedit( name, option, without_layout=True, ) label.setAlignment(Qt.AlignRight | Qt.AlignVCenter) group_layout.addWidget(label, row + 1, 0) group_layout.addLayout(clayout, row + 1, 1) group_layout.addWidget(cb_bold, row + 1, 2) group_layout.addWidget(cb_italic, row + 1, 3) # Needed to update temp scheme to obtain instant preview self.widgets[scheme_name][key] = [ clayout, cb_bold, cb_italic ] group_box = QGroupBox(group_name) group_box.setLayout(group_layout) if index == 0: h_layout.addWidget(group_box) else: v_layout.addWidget(group_box) h_layout.addLayout(v_layout) cs_layout.addLayout(h_layout) stackitem = QWidget() stackitem.setLayout(cs_layout) self.stack.addWidget(stackitem) self.order.append(scheme_name)
class PyDMScaleIndicator(QFrame, TextFormatter, PyDMWidget): """ A bar-shaped indicator for scalar value with support for Channels and more from PyDM. Configurable features include indicator type (bar/pointer), scale tick marks and orientation (horizontal/vertical). Parameters ---------- parent : QWidget The parent widget for the Scale init_channel : str, optional The channel to be used by the widget. """ def __init__(self, parent=None, init_channel=None): QFrame.__init__(self, parent) PyDMWidget.__init__(self, init_channel=init_channel) self._show_value = True self._show_limits = True self.scale_indicator = QScale() self.value_label = QLabel() self.lower_label = QLabel() self.upper_label = QLabel() self.value_label.setText('<val>') self.lower_label.setText('<min>') self.upper_label.setText('<max>') self._value_position = Qt.TopEdge self._limits_from_channel = True self._user_lower_limit = 0 self._user_upper_limit = 0 self.value_label.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) self.setup_widgets_for_orientation(Qt.Horizontal, False, False, self._value_position) def update_labels(self): """ Update the limits and value labels with the correct values. """ self.lower_label.setText(str(self.scale_indicator._lower_limit)) self.upper_label.setText(str(self.scale_indicator._upper_limit)) self.value_label.setText(self.format_string.format(self.scale_indicator._value)) def value_changed(self, new_value): """ Callback invoked when the Channel value is changed. Parameters ---------- new_val : int or float The new value from the channel. """ super(PyDMScaleIndicator, self).value_changed(new_value) self.scale_indicator.set_value(new_value) self.update_labels() def upperCtrlLimitChanged(self, new_limit): """ PyQT Slot for changes on the upper control limit value of the Channel This slot sends the new limit value to the ```ctrl_limit_changed``` callback. Parameters ---------- new_limit : float """ super(PyDMScaleIndicator, self).upperCtrlLimitChanged(new_limit) if self.limitsFromChannel: self.scale_indicator.set_upper_limit(new_limit) self.update_labels() def lowerCtrlLimitChanged(self, new_limit): """ PyQT Slot for changes on the lower control limit value of the Channel This slot sends the new limit value to the ```ctrl_limit_changed``` callback. Parameters ---------- new_limit : float """ super(PyDMScaleIndicator, self).lowerCtrlLimitChanged(new_limit) if self.limitsFromChannel: self.scale_indicator.set_lower_limit(new_limit) self.update_labels() def setup_widgets_for_orientation(self, new_orientation, flipped, inverted, value_position): """ Reconstruct the widget given the orientation. Parameters ---------- new_orientation : int Qt.Horizontal or Qt.Vertical flipped : bool Indicates if scale tick marks are flipped to the other side inverted : bool Indicates if scale appearance is inverted """ self.limits_layout = None self.widget_layout = None if new_orientation == Qt.Horizontal: self.limits_layout = QHBoxLayout() if not inverted: self.limits_layout.addWidget(self.lower_label) self.limits_layout.addWidget(self.upper_label) else: self.limits_layout.addWidget(self.upper_label) self.limits_layout.addWidget(self.lower_label) self.widget_layout = QGridLayout() if not flipped: if value_position == Qt.LeftEdge: self.widget_layout.addWidget(self.value_label, 0, 0) self.widget_layout.addWidget(self.scale_indicator, 0, 1) self.widget_layout.addItem(self.limits_layout, 1, 1) elif value_position == Qt.RightEdge: self.widget_layout.addWidget(self.value_label, 0, 1) self.widget_layout.addWidget(self.scale_indicator, 0, 0) self.widget_layout.addItem(self.limits_layout, 1, 0) elif value_position == Qt.TopEdge: self.widget_layout.addWidget(self.value_label, 0, 0) self.widget_layout.addWidget(self.scale_indicator, 1, 0) self.widget_layout.addItem(self.limits_layout, 2, 0) elif value_position == Qt.BottomEdge: self.widget_layout.addWidget(self.scale_indicator, 0, 0) self.widget_layout.addItem(self.limits_layout, 1, 0) self.widget_layout.addWidget(self.value_label, 2, 0) if not inverted: self.lower_label.setAlignment(Qt.AlignTop | Qt.AlignLeft) self.upper_label.setAlignment(Qt.AlignTop | Qt.AlignRight) elif inverted: self.lower_label.setAlignment(Qt.AlignTop | Qt.AlignRight) self.upper_label.setAlignment(Qt.AlignTop | Qt.AlignLeft) else: if value_position == Qt.LeftEdge: self.widget_layout.addItem(self.limits_layout, 0, 1) self.widget_layout.addWidget(self.scale_indicator, 1, 1) self.widget_layout.addWidget(self.value_label, 1, 0) elif value_position == Qt.RightEdge: self.widget_layout.addItem(self.limits_layout, 0, 0) self.widget_layout.addWidget(self.scale_indicator, 1, 0) self.widget_layout.addWidget(self.value_label, 1, 1) elif value_position == Qt.TopEdge: self.widget_layout.addWidget(self.value_label, 0, 0) self.widget_layout.addItem(self.limits_layout, 1, 0) self.widget_layout.addWidget(self.scale_indicator, 2, 0) elif value_position == Qt.BottomEdge: self.widget_layout.addItem(self.limits_layout, 0, 0) self.widget_layout.addWidget(self.scale_indicator, 1, 0) self.widget_layout.addWidget(self.value_label, 2, 0) if not inverted: self.lower_label.setAlignment(Qt.AlignBottom | Qt.AlignLeft) self.upper_label.setAlignment(Qt.AlignBottom | Qt.AlignRight) elif inverted: self.lower_label.setAlignment(Qt.AlignBottom | Qt.AlignRight) self.upper_label.setAlignment(Qt.AlignBottom | Qt.AlignLeft) elif new_orientation == Qt.Vertical: self.limits_layout = QVBoxLayout() if (value_position == Qt.RightEdge and flipped == False) or \ (value_position == Qt.LeftEdge and flipped == True): add_value_between_limits = True else: add_value_between_limits = False if not inverted: self.limits_layout.addWidget(self.upper_label) if add_value_between_limits: self.limits_layout.addWidget(self.value_label) self.limits_layout.addWidget(self.lower_label) self.lower_label.setAlignment(Qt.AlignHCenter | Qt.AlignBottom) self.upper_label.setAlignment(Qt.AlignHCenter | Qt.AlignTop) else: self.limits_layout.addWidget(self.lower_label) if add_value_between_limits: self.limits_layout.addWidget(self.value_label) self.limits_layout.addWidget(self.upper_label) self.lower_label.setAlignment(Qt.AlignHCenter | Qt.AlignTop) self.upper_label.setAlignment(Qt.AlignHCenter | Qt.AlignBottom) self.widget_layout = QGridLayout() if not flipped: if value_position == Qt.LeftEdge: self.widget_layout.addWidget(self.value_label, 0, 0) self.widget_layout.addWidget(self.scale_indicator, 0, 1) self.widget_layout.addItem(self.limits_layout, 0, 2) elif value_position == Qt.RightEdge: self.widget_layout.addWidget(self.scale_indicator, 0, 0) self.widget_layout.addItem(self.limits_layout, 0, 1) elif value_position == Qt.TopEdge: self.widget_layout.addWidget(self.value_label, 0, 0, 1, 2) self.widget_layout.addWidget(self.scale_indicator, 1, 0) self.widget_layout.addItem(self.limits_layout, 1, 1) elif value_position == Qt.BottomEdge: self.widget_layout.addWidget(self.scale_indicator, 0, 0) self.widget_layout.addItem(self.limits_layout, 0, 1) self.widget_layout.addWidget(self.value_label, 1, 0, 1, 2) if not inverted: self.lower_label.setAlignment(Qt.AlignLeft | Qt.AlignBottom) self.upper_label.setAlignment(Qt.AlignLeft | Qt.AlignTop) elif inverted: self.lower_label.setAlignment(Qt.AlignLeft | Qt.AlignTop) self.upper_label.setAlignment(Qt.AlignLeft | Qt.AlignBottom) else: if value_position == Qt.LeftEdge: self.widget_layout.addItem(self.limits_layout, 0, 1) self.widget_layout.addWidget(self.scale_indicator, 0, 2) elif value_position == Qt.RightEdge: self.widget_layout.addItem(self.limits_layout, 0, 0) self.widget_layout.addWidget(self.scale_indicator, 0, 1) self.widget_layout.addWidget(self.value_label, 0, 2) elif value_position == Qt.TopEdge: self.widget_layout.addWidget(self.value_label, 0, 0, 1, 2) self.widget_layout.addItem(self.limits_layout, 1, 0) self.widget_layout.addWidget(self.scale_indicator, 1, 1) elif value_position == Qt.BottomEdge: self.widget_layout.addItem(self.limits_layout, 0, 0) self.widget_layout.addWidget(self.scale_indicator, 0, 1) self.widget_layout.addWidget(self.value_label, 1, 0, 1, 2) if not inverted: self.lower_label.setAlignment(Qt.AlignRight | Qt.AlignBottom) self.upper_label.setAlignment(Qt.AlignRight | Qt.AlignTop) elif inverted: self.lower_label.setAlignment(Qt.AlignRight | Qt.AlignTop) self.upper_label.setAlignment(Qt.AlignRight | Qt.AlignBottom) self.value_label.setAlignment(Qt.AlignCenter) if self.layout() is not None: # Trick to remove the existing layout by re-parenting it in an empty widget. QWidget().setLayout(self.layout()) self.widget_layout.setContentsMargins(1, 1, 1, 1) self.setLayout(self.widget_layout) @Property(bool) def showValue(self): """ Whether or not the current value should be displayed on the scale. Returns ------- bool """ return self._show_value @showValue.setter def showValue(self, checked): """ Whether or not the current value should be displayed on the scale. Parameters ---------- checked : bool """ if self._show_value != bool(checked): self._show_value = checked if checked: self.value_label.show() else: self.value_label.hide() @Property(bool) def showLimits(self): """ Whether or not the high and low limits should be displayed on the scale. Returns ------- bool """ return self._show_limits @showLimits.setter def showLimits(self, checked): """ Whether or not the high and low limits should be displayed on the scale. Parameters ---------- checked : bool """ if self._show_limits != bool(checked): self._show_limits = checked if checked: self.lower_label.show() self.upper_label.show() else: self.lower_label.hide() self.upper_label.hide() @Property(bool) def showTicks(self): """ Whether or not the tick marks should be displayed on the scale. Returns ------- bool """ return self.scale_indicator.get_show_ticks() @showTicks.setter def showTicks(self, checked): """ Whether or not the tick marks should be displayed on the scale. Parameters ---------- checked : bool """ self.scale_indicator.set_show_ticks(checked) @Property(Qt.Orientation) def orientation(self): """ The scale orientation (Horizontal or Vertical) Returns ------- int Qt.Horizontal or Qt.Vertical """ return self.scale_indicator.get_orientation() @orientation.setter def orientation(self, orientation): """ The scale orientation (Horizontal or Vertical) Parameters ---------- new_orientation : int Qt.Horizontal or Qt.Vertical """ self.scale_indicator.set_orientation(orientation) self.setup_widgets_for_orientation(orientation, self.flipScale, self.invertedAppearance, self._value_position) @Property(bool) def flipScale(self): """ Whether or not the scale should be flipped. Returns ------- bool """ return self.scale_indicator.get_flip_scale() @flipScale.setter def flipScale(self, checked): """ Whether or not the scale should be flipped. Parameters ---------- checked : bool """ self.scale_indicator.set_flip_scale(checked) self.setup_widgets_for_orientation(self.orientation, checked, self.invertedAppearance, self._value_position) @Property(bool) def invertedAppearance(self): """ Whether or not the scale appearence should be inverted. Returns ------- bool """ return self.scale_indicator.get_inverted_appearance() @invertedAppearance.setter def invertedAppearance(self, inverted): """ Whether or not the scale appearence should be inverted. Parameters ---------- inverted : bool """ self.scale_indicator.set_inverted_appearance(inverted) self.setup_widgets_for_orientation(self.orientation, self.flipScale, inverted, self._value_position) @Property(bool) def barIndicator(self): """ Whether or not the scale indicator should be a bar instead of a pointer. Returns ------- bool """ return self.scale_indicator.get_bar_indicator() @barIndicator.setter def barIndicator(self, checked): """ Whether or not the scale indicator should be a bar instead of a pointer. Parameters ---------- checked : bool """ self.scale_indicator.set_bar_indicator(checked) @Property(QColor) def backgroundColor(self): """ The color of the scale background. Returns ------- QColor """ return self.scale_indicator.get_background_color() @backgroundColor.setter def backgroundColor(self, color): """ The color of the scale background. Parameters ------- color : QColor """ self.scale_indicator.set_background_color(color) @Property(QColor) def indicatorColor(self): """ The color of the scale indicator. Returns ------- QColor """ return self.scale_indicator.get_indicator_color() @indicatorColor.setter def indicatorColor(self, color): """ The color of the scale indicator. Parameters ------- color : QColor """ self.scale_indicator.set_indicator_color(color) @Property(QColor) def tickColor(self): """ The color of the scale tick marks. Returns ------- QColor """ return self.scale_indicator.get_tick_color() @tickColor.setter def tickColor(self, color): """ The color of the scale tick marks. Parameters ------- color : QColor """ self.scale_indicator.set_tick_color(color) @Property(float) def backgroundSizeRate(self): """ The rate of background height size (from top to bottom). Returns ------- float """ return self.scale_indicator.get_background_size_rate() @backgroundSizeRate.setter def backgroundSizeRate(self, rate): """ The rate of background height size (from top to bottom). Parameters ------- rate : float Between 0 and 1. """ self.scale_indicator.set_background_size_rate(rate) @Property(float) def tickSizeRate(self): """ The rate of tick marks height size (from bottom to top). Returns ------- float """ return self.scale_indicator.get_tick_size_rate() @tickSizeRate.setter def tickSizeRate(self, rate): """ The rate of tick marks height size (from bottom to top). Parameters ------- rate : float Between 0 and 1. """ self.scale_indicator.set_tick_size_rate(rate) @Property(int) def numDivisions(self): """ The number in which the scale is divided. Returns ------- int """ return self.scale_indicator.get_num_divisions() @numDivisions.setter def numDivisions(self, divisions): """ The number in which the scale is divided. Parameters ------- divisions : int The number of scale divisions. """ self.scale_indicator.set_num_divisions(divisions) @Property(int) def scaleHeight(self): """ The scale height, fixed so it do not wiggle when value label resizes. Returns ------- int """ return self.scale_indicator.get_scale_height() @scaleHeight.setter def scaleHeight(self, value): """ The scale height, fixed so it do not wiggle when value label resizes. Parameters ------- divisions : int The scale height. """ self.scale_indicator.set_scale_height(value) @Property(Qt.Edge) def valuePosition(self): """ The position of the value label (Top, Bottom, Left or Right). Returns ------- int Qt.TopEdge, Qt.BottomEdge, Qt.LeftEdge or Qt.RightEdge """ return self._value_position @valuePosition.setter def valuePosition(self, position): """ The position of the value label (Top, Bottom, Left or Right). Parameters ---------- position : int Qt.TopEdge, Qt.BottomEdge, Qt.LeftEdge or Qt.RightEdge """ self._value_position = position self.setup_widgets_for_orientation(self.orientation, self.flipScale, self.invertedAppearance, position) @Property(bool) def originAtZero(self): """ Whether or not the scale indicator should start at zero value. Applies only for bar indicator. Returns ------- bool """ return self.scale_indicator.get_origin_at_zero() @originAtZero.setter def originAtZero(self, checked): """ Whether or not the scale indicator should start at zero value. Applies only for bar indicator. Parameters ---------- checked : bool """ self.scale_indicator.set_origin_at_zero(checked) @Property(bool) def limitsFromChannel(self): """ Whether or not the scale indicator should use the limits information from the channel. Returns ------- bool """ return self._limits_from_channel @limitsFromChannel.setter def limitsFromChannel(self, checked): """ Whether or not the scale indicator should use the limits information from the channel. Parameters ---------- checked : bool True to use the limits from the Channel, False to use the user-defined values. """ if self._limits_from_channel != checked: self._limits_from_channel = checked if checked: if self._lower_ctrl_limit: self.scale_indicator.set_lower_limit(self._lower_ctrl_limit) if self._upper_ctrl_limit: self.scale_indicator.set_upper_limit(self._upper_ctrl_limit) else: self.scale_indicator.set_lower_limit(self._user_lower_limit) self.scale_indicator.set_upper_limit(self._user_upper_limit) self.update_labels() @Property(float) def userLowerLimit(self): """ The user-defined lower limit for the scale. Returns ------- float """ return self._user_lower_limit @userLowerLimit.setter def userLowerLimit(self, value): """ The user-defined lower limit for the scale. Parameters ---------- value : float The new lower limit value. """ if self._limits_from_channel: return self._user_lower_limit = value self.scale_indicator.set_lower_limit(self._user_lower_limit) self.update_labels() @Property(float) def userUpperLimit(self): """ The user-defined upper limit for the scale. Returns ------- float """ return self._user_upper_limit @userUpperLimit.setter def userUpperLimit(self, value): """ The user-defined upper limit for the scale. Parameters ---------- value : float The new upper limit value. """ if self._limits_from_channel: return self._user_upper_limit = value self.scale_indicator.set_upper_limit(self._user_upper_limit) self.update_labels()
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 # See spyder-ide/spyder#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_group) 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_layout.setRowStretch(fonts_layout.rowCount(), 1) # 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()
class buttonwidget(QWidget): def __init__(self): # how connect super(buttonwidget, self).__init__() self.grid = QGridLayout() self.btnConnect = QPushButton("Connect") self.grid.addWidget(self.btnConnect, 0, 0, 1, 5) self.btnLock = QPushButton("Lock Cassette") self.grid.addWidget(self.btnLock, 1, 0, 1, 5) self.btnPurge = QPushButton("Purge") self.grid.addWidget(self.btnPurge, 2, 0, 1, 2) self.cbxPurgeType = QComboBox() self.cbxPurgeType.addItems(["Normal", "Extended", "Add Conditioner", "Custom"]) self.grid.addWidget(self.cbxPurgeType, 2, 2, 1, 2) self.txtNumPurge = QLineEdit() self.grid.addWidget(self.txtNumPurge, 2, 4, 1, 1) self.btnRecover = QPushButton("Recover") self.grid.addWidget(self.btnRecover, 3, 0, 1, 5) self.btnHelp = QPushButton("Help") self.grid.addWidget(self.btnHelp, 4, 0, 1, 5) self.setLayout(self.grid) def updateButtonText(self): print('updating text') def EnableDisableButtons(self): print('enabeling,disabeling buttons')
def _setupUi(self): wid = QWidget(self) lay = QGridLayout(wid) self.setCentralWidget(wid) # title self.title = QLabel('<h3>Orbit Interlock</h3>', self, alignment=Qt.AlignCenter) # General self._gb_gen = self._setupIntlkGroup('General') # Min.Sum. Threshold self._gb_minsum = self._setupIntlkGroup('Min.Sum.Threshold') # Translation self._gb_trans = self._setupIntlkGroup('Translation') # Angulation self._gb_ang = self._setupIntlkGroup('Angulation') # Graphs self._graphs = GraphMonitorWidget(self, self.prefix) # layout lay.addWidget(self.title, 0, 0, 1, 4) lay.addWidget(self._gb_gen, 1, 0) lay.addWidget(self._gb_minsum, 1, 1) lay.addWidget(self._gb_trans, 1, 2) lay.addWidget(self._gb_ang, 1, 3) lay.addWidget(self._graphs, 2, 0, 1, 4)
def __init__(self, *args, **kwargs): super(MainWidget, self).__init__(*args, **kwargs) #Widgets self.label_Title1 = QLabel() self.label_Title1.setText("INGRESE LOS DATOS") self.label_Title2 = QLabel() self.label_Title2.setText("DATOS BOMBILLOS ESTANDAR") self.label_Title3 = QLabel() self.label_Title3.setText("DATOS BOMBILLOS LED") self.label_Data1 = QLabel() self.label_Data1.setText("Costo de la electricidad (kW/hora)") self.label_Data2 = QLabel() self.label_Data2.setText("Numero de bombillos a reemplazar") self.label_Data3 = QLabel() self.label_Data3.setText("Vatios del bombillo existente") self.label_Data4 = QLabel() self.label_Data4.setText("Numero de Horas por Dia encendido") self.label_Data5 = QLabel() self.label_Data5.setText("Vida util bombillo actual") self.label_Data6 = QLabel() self.label_Data6.setText("Costo Bombillo actual") self.label_Data7 = QLabel() self.label_Data7.setText("Costo estimado mantenimiento por bombillo") self.label_Data8 = QLabel() self.label_Data8.setText("Vatios del bombillo LED") self.label_Data9 = QLabel() self.label_Data9.setText("Vida util estimada del bombillo") self.label_Data10 = QLabel() self.label_Data10.setText("Costo del bombillo led") #Widgets Titulos del Form self.label_Titlef1 = QLabel() self.label_Titlef1.setText("INFORMACION DE COSTOS CALCULADOS") self.label_Titlef2 = QLabel() self.label_Titlef2.setText("INFORMACION DE AHORROS CALCULADOS") self.line_Data1 = QLineEdit() #self.line_Data1.setValidator() self.line_Data2 = QLineEdit() self.line_Data2.setValidator(QIntValidator()) self.line_Data3 = QLineEdit() self.line_Data3.setValidator(QIntValidator()) self.line_Data4 = QLineEdit() self.line_Data4.setValidator(QIntValidator()) self.line_Data5 = QLineEdit() self.line_Data5.setValidator(QIntValidator()) self.line_Data6 = QLineEdit() #self.line_Data6.setValidator() self.line_Data7 = QLineEdit() #self.line_Data7.setValidator() self.line_Data8 = QLineEdit() #self.line_Data8.setValidator() self.line_Data9 = QLineEdit() #self.line_Data9.setValidator() self.line_Data10 = QLineEdit() #self.line_Data10.setValidator() #Widget Informacion Calculada Form1 Costos self.line_Inf1 = QLineEdit() self.line_Inf1.setValidator(QIntValidator()) self.line_Inf2 = QLineEdit() self.line_Inf2.setValidator(QIntValidator()) self.line_Inf3 = QLineEdit() self.line_Inf3.setValidator(QIntValidator()) self.line_Inf4 = QLineEdit() self.line_Inf4.setValidator(QIntValidator()) self.line_Inf5 = QLineEdit() self.line_Inf5.setValidator(QIntValidator()) self.line_Inf6 = QLineEdit() self.line_Inf6.setValidator(QIntValidator()) self.line_Inf7 = QLineEdit() self.line_Inf7.setValidator(QIntValidator()) self.line_Inf8 = QLineEdit() self.line_Inf8.setValidator(QIntValidator()) self.line_Inf9 = QLineEdit() self.line_Inf9.setValidator(QIntValidator()) #Widget Informacion Calculada Form2 Ahorros self.line_Sav1 = QLineEdit() self.line_Sav1.setValidator(QIntValidator()) self.line_Sav2 = QLineEdit() self.line_Sav2.setValidator(QIntValidator()) self.line_Sav3 = QLineEdit() self.line_Sav3.setValidator(QIntValidator()) self.line_Sav4 = QLineEdit() self.line_Sav4.setValidator(QIntValidator()) self.line_Sav5 = QLineEdit() self.line_Sav5.setValidator(QIntValidator()) self.line_Sav6 = QLineEdit() self.line_Sav6.setValidator(QIntValidator()) self.button_Calc = QPushButton('Calcular Ahorro', parent=self) self.button_Impr = QPushButton('Imprimir', parent=self) #Layouts layout = QGridLayout() layout.addWidget(self.label_Title1,0,0) layout.addWidget(self.label_Data1,1,0) layout.addWidget(self.line_Data1,1,1) layout.addWidget(self.label_Title2,2,0) layout.addWidget(self.label_Data2,3,0) layout.addWidget(self.line_Data2,3,1) layout.addWidget(self.label_Data5,3,2) layout.addWidget(self.line_Data5,3,3) layout.addWidget(self.label_Data3,4,0) layout.addWidget(self.line_Data3,4,1) layout.addWidget(self.label_Data6,4,2) layout.addWidget(self.line_Data6,4,3) layout.addWidget(self.label_Data4,5,0) layout.addWidget(self.line_Data4,5,1) layout.addWidget(self.label_Data7,5,2) layout.addWidget(self.line_Data7,5,3) layout.addWidget(self.label_Title3,6,0) layout.addWidget(self.label_Data8,7,0) layout.addWidget(self.line_Data8,7,1) layout.addWidget(self.label_Data10,7,2) layout.addWidget(self.line_Data10,7,3) layout.addWidget(self.label_Data9,8,0) layout.addWidget(self.line_Data9,8,1) layout.addWidget(self.button_Calc,8,3) layout1 = QFormLayout() layout1.addRow("Horas por año",self.line_Inf1) layout1.addRow("Costo de Energia por Dia",self.line_Inf2) layout1.addRow("Costo de Energia por Año",self.line_Inf3) layout1.addRow("Costo total de la Compra",self.line_Inf4) layout1.addRow("Costo Total de la compra con mantenimiento",self.line_Inf5) layout1.addRow("Costo Reemplazo Actuales Año",self.line_Inf6) layout1.addRow("Costo Energia por Dia LED",self.line_Inf7) layout1.addRow("Costo de Energia por Año LED",self.line_Inf8) layout1.addRow("Costo Total de la Compra LED",self.line_Inf9) layout2 = QFormLayout() layout2.addRow("Ahorro Energia Anual",self.line_Sav1) layout2.addRow("Ahorro Energia Mensual",self.line_Sav2) layout2.addRow("Periodo Retorno Inversion en Años",self.line_Sav3) layout2.addRow("Periodo Retorno Inversion en Meses",self.line_Sav4) layout2.addWidget(self.button_Impr) #Layout Horizontal Titulos del Form self.LayoutTitle = QHBoxLayout() self.LayoutTitle.addWidget(self.label_Titlef1) self.LayoutTitle.addWidget(self.label_Titlef2) ### Layout HOrizontal que une los dos Form self.LayoutForm = QHBoxLayout() self.LayoutForm.addLayout(layout1) self.LayoutForm.addLayout(layout2) ## LAyout Vertical Final self.myLayout = QVBoxLayout() self.myLayout.setMargin(20) self.myLayout.addLayout(layout) self.myLayout.addLayout(self.LayoutTitle) self.myLayout.addLayout(self.LayoutForm) self.setLayout(self.myLayout) # Signals self.button_Calc.clicked.connect(self.result_method)
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(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.label_warning.setMinimumHeight( 3 * self.label_warning.sizeHint().height()) 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) 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_widgets_for_orientation(self, new_orientation, flipped, inverted, value_position): """ Reconstruct the widget given the orientation. Parameters ---------- new_orientation : int Qt.Horizontal or Qt.Vertical flipped : bool Indicates if scale tick marks are flipped to the other side inverted : bool Indicates if scale appearance is inverted """ self.limits_layout = None self.widget_layout = None if new_orientation == Qt.Horizontal: self.limits_layout = QHBoxLayout() if not inverted: self.limits_layout.addWidget(self.lower_label) self.limits_layout.addWidget(self.upper_label) else: self.limits_layout.addWidget(self.upper_label) self.limits_layout.addWidget(self.lower_label) self.widget_layout = QGridLayout() if not flipped: if value_position == Qt.LeftEdge: self.widget_layout.addWidget(self.value_label, 0, 0) self.widget_layout.addWidget(self.scale_indicator, 0, 1) self.widget_layout.addItem(self.limits_layout, 1, 1) elif value_position == Qt.RightEdge: self.widget_layout.addWidget(self.value_label, 0, 1) self.widget_layout.addWidget(self.scale_indicator, 0, 0) self.widget_layout.addItem(self.limits_layout, 1, 0) elif value_position == Qt.TopEdge: self.widget_layout.addWidget(self.value_label, 0, 0) self.widget_layout.addWidget(self.scale_indicator, 1, 0) self.widget_layout.addItem(self.limits_layout, 2, 0) elif value_position == Qt.BottomEdge: self.widget_layout.addWidget(self.scale_indicator, 0, 0) self.widget_layout.addItem(self.limits_layout, 1, 0) self.widget_layout.addWidget(self.value_label, 2, 0) if not inverted: self.lower_label.setAlignment(Qt.AlignTop | Qt.AlignLeft) self.upper_label.setAlignment(Qt.AlignTop | Qt.AlignRight) elif inverted: self.lower_label.setAlignment(Qt.AlignTop | Qt.AlignRight) self.upper_label.setAlignment(Qt.AlignTop | Qt.AlignLeft) else: if value_position == Qt.LeftEdge: self.widget_layout.addItem(self.limits_layout, 0, 1) self.widget_layout.addWidget(self.scale_indicator, 1, 1) self.widget_layout.addWidget(self.value_label, 1, 0) elif value_position == Qt.RightEdge: self.widget_layout.addItem(self.limits_layout, 0, 0) self.widget_layout.addWidget(self.scale_indicator, 1, 0) self.widget_layout.addWidget(self.value_label, 1, 1) elif value_position == Qt.TopEdge: self.widget_layout.addWidget(self.value_label, 0, 0) self.widget_layout.addItem(self.limits_layout, 1, 0) self.widget_layout.addWidget(self.scale_indicator, 2, 0) elif value_position == Qt.BottomEdge: self.widget_layout.addItem(self.limits_layout, 0, 0) self.widget_layout.addWidget(self.scale_indicator, 1, 0) self.widget_layout.addWidget(self.value_label, 2, 0) if not inverted: self.lower_label.setAlignment(Qt.AlignBottom | Qt.AlignLeft) self.upper_label.setAlignment(Qt.AlignBottom | Qt.AlignRight) elif inverted: self.lower_label.setAlignment(Qt.AlignBottom | Qt.AlignRight) self.upper_label.setAlignment(Qt.AlignBottom | Qt.AlignLeft) elif new_orientation == Qt.Vertical: self.limits_layout = QVBoxLayout() if (value_position == Qt.RightEdge and flipped == False) or \ (value_position == Qt.LeftEdge and flipped == True): add_value_between_limits = True else: add_value_between_limits = False if not inverted: self.limits_layout.addWidget(self.upper_label) if add_value_between_limits: self.limits_layout.addWidget(self.value_label) self.limits_layout.addWidget(self.lower_label) self.lower_label.setAlignment(Qt.AlignHCenter | Qt.AlignBottom) self.upper_label.setAlignment(Qt.AlignHCenter | Qt.AlignTop) else: self.limits_layout.addWidget(self.lower_label) if add_value_between_limits: self.limits_layout.addWidget(self.value_label) self.limits_layout.addWidget(self.upper_label) self.lower_label.setAlignment(Qt.AlignHCenter | Qt.AlignTop) self.upper_label.setAlignment(Qt.AlignHCenter | Qt.AlignBottom) self.widget_layout = QGridLayout() if not flipped: if value_position == Qt.LeftEdge: self.widget_layout.addWidget(self.value_label, 0, 0) self.widget_layout.addWidget(self.scale_indicator, 0, 1) self.widget_layout.addItem(self.limits_layout, 0, 2) elif value_position == Qt.RightEdge: self.widget_layout.addWidget(self.scale_indicator, 0, 0) self.widget_layout.addItem(self.limits_layout, 0, 1) elif value_position == Qt.TopEdge: self.widget_layout.addWidget(self.value_label, 0, 0, 1, 2) self.widget_layout.addWidget(self.scale_indicator, 1, 0) self.widget_layout.addItem(self.limits_layout, 1, 1) elif value_position == Qt.BottomEdge: self.widget_layout.addWidget(self.scale_indicator, 0, 0) self.widget_layout.addItem(self.limits_layout, 0, 1) self.widget_layout.addWidget(self.value_label, 1, 0, 1, 2) if not inverted: self.lower_label.setAlignment(Qt.AlignLeft | Qt.AlignBottom) self.upper_label.setAlignment(Qt.AlignLeft | Qt.AlignTop) elif inverted: self.lower_label.setAlignment(Qt.AlignLeft | Qt.AlignTop) self.upper_label.setAlignment(Qt.AlignLeft | Qt.AlignBottom) else: if value_position == Qt.LeftEdge: self.widget_layout.addItem(self.limits_layout, 0, 1) self.widget_layout.addWidget(self.scale_indicator, 0, 2) elif value_position == Qt.RightEdge: self.widget_layout.addItem(self.limits_layout, 0, 0) self.widget_layout.addWidget(self.scale_indicator, 0, 1) self.widget_layout.addWidget(self.value_label, 0, 2) elif value_position == Qt.TopEdge: self.widget_layout.addWidget(self.value_label, 0, 0, 1, 2) self.widget_layout.addItem(self.limits_layout, 1, 0) self.widget_layout.addWidget(self.scale_indicator, 1, 1) elif value_position == Qt.BottomEdge: self.widget_layout.addItem(self.limits_layout, 0, 0) self.widget_layout.addWidget(self.scale_indicator, 0, 1) self.widget_layout.addWidget(self.value_label, 1, 0, 1, 2) if not inverted: self.lower_label.setAlignment(Qt.AlignRight | Qt.AlignBottom) self.upper_label.setAlignment(Qt.AlignRight | Qt.AlignTop) elif inverted: self.lower_label.setAlignment(Qt.AlignRight | Qt.AlignTop) self.upper_label.setAlignment(Qt.AlignRight | Qt.AlignBottom) self.value_label.setAlignment(Qt.AlignCenter) if self.layout() is not None: # Trick to remove the existing layout by re-parenting it in an empty widget. QWidget().setLayout(self.layout()) self.widget_layout.setContentsMargins(1, 1, 1, 1) self.setLayout(self.widget_layout)
def _setupFamiliesLayout(self): lay = QGridLayout() lb_family = QLabel('<h4>Family</h4>', self, alignment=Qt.AlignCenter) lb_family.setStyleSheet('max-height:1.29em;') lay.addWidget(lb_family, 0, 1) lb_rbdesc = QLabel('<h4>'+self.intstrength+'-RB</h4>', self, alignment=Qt.AlignCenter) lb_rbdesc.setStyleSheet('max-height:1.29em;') lay.addWidget(lb_rbdesc, 0, 2) if self.param == 'tune': lb_refdesc = QLabel('<h4>RefKL-Mon</h4>', self, alignment=Qt.AlignCenter) lb_refdesc.setStyleSheet('max-height:1.29em;') lay.addWidget(lb_refdesc, 0, 3) lb_lastddesc = QLabel('<h4>'+self.intstrength_calcdesc+'</h4>', self, alignment=Qt.AlignCenter) lb_lastddesc.setStyleSheet('max-height:1.29em;') lay.addWidget(lb_lastddesc, 0, 4) row = 1 for fam in self.fams: dev_name = _PVName(self.acc+'-Fam:PS-'+fam) pref_name = dev_name.substitute(prefix=self.prefix) pbt = QPushButton(qta.icon('fa5s.list-ul'), '', self) pbt.setObjectName('pbt') pbt.setStyleSheet(""" #pbt{ min-width:25px; max-width:25px; min-height:25px; max-height:25px; icon-size:20px;}""") _hlautil.connect_window( pbt, _PSDetailWindow, parent=self, psname=dev_name) lay.addWidget(pbt, row, 0) lb_name = QLabel(fam, self, alignment=Qt.AlignCenter) lay.addWidget(lb_name, row, 1) lb_rb = PyDMLabel(self, pref_name.substitute( propty=self.intstrength+'-RB')) lay.addWidget(lb_rb, row, 2) if self.param == 'tune': lb_ref = PyDMLabel(self, self.ioc_prefix.substitute( propty='RefKL'+fam+'-Mon')) lay.addWidget(lb_ref, row, 3) lb_calc = PyDMLabel(self, self.ioc_prefix.substitute( propty=self.intstrength_calcpv.format(fam))) lay.addWidget(lb_calc, row, 4) row += 1 return lay
def __init__(self, parent): super().__init__() self.parent = parent #self.html = "<h1>UniqueBible.app</h1><p>This is '<b>Main View</b>'.</p>" #self.mainView = WebEngineView(self, "main") #self.mainView.setHtml(self.html, baseUrl) #self.studyView = WebEngineView(self, "study") #self.studyView.setHtml("This is '<b>Study View</b>'.", baseUrl) self.instantSplitter = QSplitter(Qt.Vertical, parent) if config.landscapeMode: self.parallelSplitter = QSplitter(Qt.Horizontal) else: self.parallelSplitter = QSplitter(Qt.Vertical) self.mainView = TabWidget(self, "main") self.parent.mainView = self.mainView for i in range(config.numberOfTab): tabView = WebEngineView(self, "main") self.mainView.addTab( tabView, "{1}{0}".format(i + 1, config.thisTranslation["tabBible"])) tabView.titleChanged.connect(self.parent.mainTextCommandChanged) tabView.loadFinished.connect(self.parent.finishMainViewLoading) self.studyView = TabWidget(self, "study") self.parent.studyView = self.studyView for i in range(config.numberOfTab): tabView = WebEngineView(self, "study") self.studyView.addTab( tabView, "{1}{0}".format(i + 1, config.thisTranslation["tabStudy"])) tabView.titleChanged.connect(self.parent.studyTextCommandChanged) tabView.loadFinished.connect(self.parent.finishStudyViewLoading) self.instantView = WebEngineView(self, "instant") self.instantView.setHtml( "<link id='theme_stylesheet' rel='stylesheet' type='text/css' href='css/{1}.css'><link id='theme_stylesheet' rel='stylesheet' type='text/css' href='css/custom.css'><p style='font-family:{0};'><u><b>Bottom Window</b></u><br>Display instant information on this window by hovering over verse numbers, tagged words or bible reference links.</p>" .format(config.font, config.theme), config.baseUrl) self.parallelSplitter.addWidget(self.mainView) self.parallelSplitter.addWidget(self.studyView) self.parallelSplitter.setHandleWidth(5) self.instantSplitter.setHandleWidth(5) self.instantSplitter.addWidget(self.parallelSplitter) self.instantSplitter.addWidget(self.instantView) # Adding signals self.instantSplitter.splitterMoved.connect(self.onInstantSplitterMoved) self.parallelSplitter.splitterMoved.connect( self.onParallelSplitterMoved) self.layout = QGridLayout() self.layout.setContentsMargins(0, 10, 0, 3) # self.layout.setHorizontalSpacing(0) # self.layout.setVerticalSpacing(2) self.layout.addWidget(self.instantSplitter) self.setLayout(self.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 insert_row(self, row=-1, title='', sample_runs='', sample_mass_density='N/A', sample_chemical_formula='N/A', packing_fraction='N/A', align_and_focus_args={}, sample_placzek_arguments={}, normalization_placzek_arguments={}): self.table_ui.insertRow(row) self.set_row_height(row, COLUMN_DEFAULT_HEIGHT) _list_ui_to_unlock = [self.table_ui] _dimension_widgets = {'label': None, 'value': 'N/A', 'units': None} _full_dimension_widgets = { 'radius': copy.deepcopy(_dimension_widgets), 'radius2': copy.deepcopy(_dimension_widgets), 'height': copy.deepcopy(_dimension_widgets) } _text_button = {'text': None, 'button': None} _mass_density_options = {'value': "N/A", "selected": False} _mass_density_infos = { 'number_density': copy.deepcopy(_mass_density_options), 'mass_density': copy.deepcopy(_mass_density_options), 'mass': copy.deepcopy(_mass_density_options), 'molecular_mass': np.NaN, 'total_number_of_atoms': np.NaN, } _material_infos = {'mantid_format': None, 'addie_format': None} _mass_density_infos['mass_density']["selected"] = True _master_table_row_ui = { 'active': None, 'title': None, 'sample': { 'runs': None, 'background': { 'runs': None, 'background': None, }, 'material': copy.deepcopy(_text_button), 'material_infos': copy.deepcopy(_material_infos), 'mass_density': copy.deepcopy(_text_button), 'mass_density_infos': copy.deepcopy(_mass_density_infos), 'packing_fraction': None, 'geometry': copy.deepcopy(_full_dimension_widgets), 'shape': None, 'abs_correction': None, 'mult_scat_correction': None, 'inelastic_correction': None, 'placzek_button': None, 'placzek_infos': None, }, 'normalization': { 'runs': None, 'background': { 'runs': None, 'background': None, }, 'material': copy.deepcopy(_text_button), 'material_infos': copy.deepcopy(_material_infos), 'mass_density': copy.deepcopy(_text_button), 'mass_density_infos': copy.deepcopy(_mass_density_infos), 'packing_fraction': None, 'geometry': copy.deepcopy(_full_dimension_widgets), 'shape': None, 'abs_correction': None, 'mult_scat_correction': None, 'inelastic_correction': None, 'placzek_button': None, 'placzek_infos': None, }, 'align_and_focus_args_button': None, 'align_and_focus_args_infos': {}, 'align_and_focus_args_use_global': True, } random_key = self.generate_random_key() self.key = random_key # block main table events self.table_ui.blockSignals(True) # column 0 (active or not checkBox) _layout = QHBoxLayout() _widget = QCheckBox() _widget.setCheckState(QtCore.Qt.Checked) _widget.setEnabled(True) _master_table_row_ui['active'] = _widget _spacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) _layout.addItem(_spacer) _layout.addWidget(_widget) _spacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) _layout.addItem(_spacer) _layout.addStretch() _new_widget = QWidget() _new_widget.setLayout(_layout) _widget.stateChanged.connect( lambda state=0, key=random_key: self.main_window. master_table_select_state_changed(state, key)) column = 0 self.table_ui.setCellWidget(row, column, _new_widget) # sample column += 1 # column 1 - title _item = QTableWidgetItem(title) _master_table_row_ui['title'] = _item self.table_ui.setItem(row, column, _item) # column 2 - sample runs column += 1 _item = QTableWidgetItem(sample_runs) _master_table_row_ui['sample']['runs'] = _item self.table_ui.setItem(row, column, _item) # column 3 - background runs column += 1 _item = QTableWidgetItem("") _master_table_row_ui['sample']['background']['runs'] = _item self.table_ui.setItem(row, column, _item) # column 4 - background background column += 1 _item = QTableWidgetItem("") _master_table_row_ui['sample']['background']['background'] = _item self.table_ui.setItem(row, column, _item) # column 5 - material (chemical formula) column += 1 clean_sample_chemical_formula = format_chemical_formula_equation( sample_chemical_formula) _material_text = QLineEdit(clean_sample_chemical_formula) _material_text = QLabel(clean_sample_chemical_formula) _material_button = QPushButton("...") _material_button.setFixedHeight(CONFIG_BUTTON_HEIGHT) _material_button.setFixedWidth(CONFIG_BUTTON_WIDTH) _material_button.pressed.connect( lambda key=random_key: self.main_window. master_table_sample_material_button_pressed(key)) _verti_layout = QVBoxLayout() _verti_layout.addWidget(_material_text) _verti_layout.addWidget(_material_button) _material_widget = QWidget() _material_widget.setLayout(_verti_layout) self.table_ui.setCellWidget(row, column, _material_widget) _master_table_row_ui['sample']['material']['text'] = _material_text _master_table_row_ui['sample']['material']['button'] = _material_button # column 6 - mass density column += 1 _mass_text = QLineEdit(sample_mass_density) _mass_text.returnPressed.connect( lambda key=random_key: self.main_window. master_table_sample_mass_density_line_edit_entered(key)) _mass_units = QLabel("g/cc") _top_widget = QWidget() _top_layout = QHBoxLayout() _top_layout.addWidget(_mass_text) _top_layout.addWidget(_mass_units) _top_widget.setLayout(_top_layout) _mass_button = QPushButton("...") _mass_button.setFixedHeight(CONFIG_BUTTON_HEIGHT) _mass_button.setFixedWidth(CONFIG_BUTTON_WIDTH) _mass_button.pressed.connect( lambda key=random_key: self.main_window. master_table_sample_mass_density_button_pressed(key)) _verti_layout = QVBoxLayout() _verti_layout.addWidget(_top_widget) _verti_layout.addWidget(_mass_button) _mass_widget = QWidget() _mass_widget.setLayout(_verti_layout) self.table_ui.setCellWidget(row, column, _mass_widget) _master_table_row_ui['sample']['mass_density']['text'] = _mass_text _master_table_row_ui['sample']['mass_density']['button'] = _mass_button # column 7 - packing fraction column += 1 if packing_fraction == "N/A": packing_fraction = "{}".format(self.main_window.packing_fraction) _item = QTableWidgetItem(packing_fraction) _master_table_row_ui['sample']['packing_fraction'] = _item self.table_ui.setItem(row, column, _item) # column 8 - shape (cylinder or sphere) column += 1 _layout = QHBoxLayout() _layout.setContentsMargins(0, 0, 0, 0) _widget = QComboBox() _shape_default_index = 0 _widget.currentIndexChanged.connect( lambda index=_shape_default_index, key=random_key: self.main_window .master_table_sample_shape_changed(index, key)) _list_ui_to_unlock.append(_widget) _widget.blockSignals(True) _widget.addItem("Cylinder") _widget.addItem("Sphere") _widget.addItem("Hollow Cylinder") _master_table_row_ui['sample']['shape'] = _widget _layout.addWidget(_widget) _w = QWidget() _w.setLayout(_layout) self.table_ui.setCellWidget(row, column, _w) # column 9 - dimensions column += 1 # layout 1 _grid_layout = QGridLayout() _label1 = QLabel("Radius:") _grid_layout.addWidget(_label1, 1, 0) _value1 = QLabel("N/A") _grid_layout.addWidget(_value1, 1, 1) _dim1 = QLabel("cm") _grid_layout.addWidget(_dim1, 1, 2) _label2 = QLabel("Radius:") _label2.setVisible(False) _grid_layout.addWidget(_label2, 2, 0) _value2 = QLabel("N/A") _value2.setVisible(False) _grid_layout.addWidget(_value2, 2, 1) _dim2 = QLabel("cm") _dim2.setVisible(False) _grid_layout.addWidget(_dim2, 2, 2) _label3 = QLabel("Height:") _grid_layout.addWidget(_label3, 3, 0) _value3 = QLabel("N/A") _grid_layout.addWidget(_value3, 3, 1) _dim3 = QLabel("cm") _grid_layout.addWidget(_dim3, 3, 2) _master_table_row_ui['sample']['geometry']['radius']['value'] = _value1 _master_table_row_ui['sample']['geometry']['radius2'][ 'value'] = _value2 _master_table_row_ui['sample']['geometry']['height']['value'] = _value3 _master_table_row_ui['sample']['geometry']['radius']['label'] = _label1 _master_table_row_ui['sample']['geometry']['radius2'][ 'label'] = _label2 _master_table_row_ui['sample']['geometry']['height']['label'] = _label3 _master_table_row_ui['sample']['geometry']['radius']['units'] = _dim1 _master_table_row_ui['sample']['geometry']['radius2']['units'] = _dim2 _master_table_row_ui['sample']['geometry']['height']['units'] = _dim3 _geometry_widget = QWidget() _geometry_widget.setLayout(_grid_layout) _set_dimensions_button = QPushButton("...") _set_dimensions_button.setFixedHeight(CONFIG_BUTTON_HEIGHT) _set_dimensions_button.setFixedWidth(CONFIG_BUTTON_WIDTH) _verti_layout = QVBoxLayout() _verti_layout.addWidget(_geometry_widget) _verti_layout.addWidget(_set_dimensions_button) _verti_widget = QWidget() _verti_widget.setLayout(_verti_layout) _set_dimensions_button.pressed.connect( lambda key=random_key: self.main_window. master_table_sample_dimensions_setter_button_pressed(key)) self.table_ui.setCellWidget(row, column, _verti_widget) # column 10 - abs. correction column += 1 _layout = QHBoxLayout() _layout.setContentsMargins(0, 0, 0, 0) _widget = QComboBox() _shape_default_value = 0 list_abs_correction = self.get_absorption_correction_list( shape=_shape_default_value) _widget.currentIndexChanged.connect( lambda value=list_abs_correction[0], key=random_key: self. main_window.master_table_sample_abs_correction_changed(value, key)) _widget.blockSignals(True) _list_ui_to_unlock.append(_widget) for _item in list_abs_correction: _widget.addItem(_item) _master_table_row_ui['sample']['abs_correction'] = _widget _layout.addWidget(_widget) _w = QWidget() _w.setLayout(_layout) self.table_ui.setCellWidget(row, column, _w) # column 11 - multi. scattering correction column += 1 _layout = QHBoxLayout() _layout.setContentsMargins(0, 0, 0, 0) _widget = QComboBox() list_multi_scat_correction = self.get_multi_scat_correction_list( shape=_shape_default_value) _widget.currentIndexChanged.connect( lambda value=list_multi_scat_correction[ 0], key=random_key: self.main_window. master_table_sample_multi_scattering_correction_changed( value, key)) _widget.blockSignals(True) _list_ui_to_unlock.append(_widget) for _item in list_multi_scat_correction: _widget.addItem(_item) _master_table_row_ui['sample']['mult_scat_correction'] = _widget _layout.addWidget(_widget) _w = QWidget() _w.setLayout(_layout) self.table_ui.setCellWidget(row, column, _w) # column 12 - inelastic correction column += 1 _layout = QHBoxLayout() _layout.setContentsMargins(0, 0, 0, 0) _widget1 = QComboBox() _widget1.setMinimumHeight(20) list_inelastic_correction = self.get_inelastic_scattering_list( shape=_shape_default_value) for _item in list_inelastic_correction: _widget1.addItem(_item) _master_table_row_ui['sample']['inelastic_correction'] = _widget1 _button = QPushButton("...") _button.setFixedHeight(CONFIG_BUTTON_HEIGHT) _button.setFixedWidth(CONFIG_BUTTON_WIDTH) _button.pressed.connect( lambda key=random_key: self.main_window. master_table_sample_placzek_button_pressed(key)) _master_table_row_ui['sample']['placzek_button'] = _button _button.setVisible(False) _master_table_row_ui['sample']['placzek_button'] = _button _layout.addWidget(_widget1) _layout.addWidget(_button) _widget = QWidget() _widget.setLayout(_layout) _default_value = 'None' _widget1.currentIndexChanged.connect( lambda value=_default_value, key=random_key: self.main_window. master_table_sample_inelastic_correction_changed(value, key)) _widget.blockSignals(True) _list_ui_to_unlock.append(_widget) self.table_ui.setCellWidget(row, column, _widget) # save default placzek settings _sample_formated_placzek_default = self.formated_placzek_default( sample_placzek_arguments) _master_table_row_ui['sample'][ 'placzek_infos'] = _sample_formated_placzek_default ## normalization # column 13 - sample runs column += 1 _item = QTableWidgetItem("") self.table_ui.setItem(row, column, _item) # column 14 - background runs column += 1 _item = QTableWidgetItem("") self.table_ui.setItem(row, column, _item) # column 15 - background background column += 1 _item = QTableWidgetItem("") self.table_ui.setItem(row, column, _item) # column 16 - material (chemical formula) column += 1 #_material_text = QLineEdit("") _material_text = QLabel("N/A") _material_button = QPushButton("...") _material_button.setFixedHeight(CONFIG_BUTTON_HEIGHT) _material_button.setFixedWidth(CONFIG_BUTTON_WIDTH) _material_button.pressed.connect( lambda key=random_key: self.main_window. master_table_normalization_material_button_pressed(key)) _verti_layout = QVBoxLayout() _verti_layout.addWidget(_material_text) _verti_layout.addWidget(_material_button) _material_widget = QWidget() _material_widget.setLayout(_verti_layout) self.table_ui.setCellWidget(row, column, _material_widget) _master_table_row_ui['normalization']['material'][ 'text'] = _material_text _master_table_row_ui['normalization']['material'][ 'button'] = _material_button # column 17 - mass density column += 1 _mass_text = QLineEdit("N/A") _mass_text.returnPressed.connect( lambda key=random_key: self.main_window. master_table_normalization_mass_density_line_edit_entered(key)) _mass_units = QLabel("g/cc") _top_widget = QWidget() _top_layout = QHBoxLayout() _top_layout.addWidget(_mass_text) _top_layout.addWidget(_mass_units) _top_widget.setLayout(_top_layout) _mass_button = QPushButton("...") _mass_button.setFixedWidth(CONFIG_BUTTON_WIDTH) _mass_button.setFixedHeight(CONFIG_BUTTON_HEIGHT) _mass_button.pressed.connect( lambda key=random_key: self.main_window. master_table_normalization_mass_density_button_pressed(key)) _verti_layout = QVBoxLayout() _verti_layout.addWidget(_top_widget) _verti_layout.addWidget(_mass_button) _mass_widget = QWidget() _mass_widget.setLayout(_verti_layout) self.table_ui.setCellWidget(row, column, _mass_widget) _master_table_row_ui['normalization']['mass_density'][ 'text'] = _mass_text _master_table_row_ui['normalization']['mass_density'][ 'button'] = _mass_button # column 18 - packing fraction column += 1 _item = QTableWidgetItem("") self.table_ui.setItem(row, column, _item) # column 19 - shape (cylinder or sphere) column += 1 _layout = QHBoxLayout() _layout.setContentsMargins(0, 0, 0, 0) _widget = QComboBox() _widget.currentIndexChanged.connect( lambda value=_shape_default_value, key=random_key: self.main_window .master_table_normalization_shape_changed(value, key)) _widget.blockSignals(True) _list_ui_to_unlock.append(_widget) _widget.addItem("Cylinder") _widget.addItem("Sphere") _widget.addItem("Hollow Cylinder") _master_table_row_ui['normalization']['shape'] = _widget _layout.addWidget(_widget) _w = QWidget() _w.setLayout(_layout) self.table_ui.setCellWidget(row, column, _w) # column 20 - dimensions column += 1 # layout 1 _grid_layout = QGridLayout() _label1 = QLabel("Radius:") _grid_layout.addWidget(_label1, 1, 0) _value1 = QLabel("N/A") _grid_layout.addWidget(_value1, 1, 1) _dim1 = QLabel("cm") _grid_layout.addWidget(_dim1, 1, 2) _label2 = QLabel("Radius:") _label2.setVisible(False) _grid_layout.addWidget(_label2, 2, 0) _value2 = QLabel("N/A") _value2.setVisible(False) _grid_layout.addWidget(_value2, 2, 1) _dim2 = QLabel("cm") _dim2.setVisible(False) _grid_layout.addWidget(_dim2, 2, 2) _label3 = QLabel("Height:") _grid_layout.addWidget(_label3, 3, 0) _value3 = QLabel("N/A") _grid_layout.addWidget(_value3, 3, 1) _dim3 = QLabel("cm") _grid_layout.addWidget(_dim3, 3, 2) _master_table_row_ui['normalization']['geometry']['radius'][ 'value'] = _value1 _master_table_row_ui['normalization']['geometry']['radius2'][ 'value'] = _value2 _master_table_row_ui['normalization']['geometry']['height'][ 'value'] = _value3 _master_table_row_ui['normalization']['geometry']['radius'][ 'label'] = _label1 _master_table_row_ui['normalization']['geometry']['radius2'][ 'label'] = _label2 _master_table_row_ui['normalization']['geometry']['height'][ 'label'] = _label3 _master_table_row_ui['normalization']['geometry']['radius'][ 'units'] = _dim1 _master_table_row_ui['normalization']['geometry']['radius2'][ 'units'] = _dim2 _master_table_row_ui['normalization']['geometry']['height'][ 'units'] = _dim3 _geometry_widget = QWidget() _geometry_widget.setLayout(_grid_layout) _set_dimensions_button = QPushButton("...") _set_dimensions_button.setFixedHeight(CONFIG_BUTTON_HEIGHT) _set_dimensions_button.setFixedWidth(CONFIG_BUTTON_WIDTH) _verti_layout = QVBoxLayout() _verti_layout.addWidget(_geometry_widget) _verti_layout.addWidget(_set_dimensions_button) _verti_widget = QWidget() _verti_widget.setLayout(_verti_layout) _set_dimensions_button.pressed.connect( lambda key=random_key: self.main_window. master_table_normalization_dimensions_setter_button_pressed( key)) # noqa self.table_ui.setCellWidget(row, column, _verti_widget) # column 21 - abs. correction column += 1 _layout = QHBoxLayout() _layout.setContentsMargins(0, 0, 0, 0) _widget = QComboBox() _widget.currentIndexChanged.connect( lambda value=list_abs_correction[0], key=random_key: self. main_window.master_table_normalization_abs_correction_changed( value, key)) # noqa _widget.blockSignals(True) _list_ui_to_unlock.append(_widget) for _item in list_abs_correction: _widget.addItem(_item) _widget.setCurrentIndex(0) _master_table_row_ui['normalization']['abs_correction'] = _widget _layout.addWidget(_widget) _w = QWidget() _w.setLayout(_layout) self.table_ui.setCellWidget(row, column, _w) # column 24 - multi. scattering correction column += 1 _layout = QHBoxLayout() _layout.setContentsMargins(0, 0, 0, 0) _widget = QComboBox() _widget.currentIndexChanged.connect( lambda value=list_multi_scat_correction[ 0], key=random_key: self.main_window. master_table_normalization_multi_scattering_correction_changed( value, key)) # noqa _widget.blockSignals(True) _list_ui_to_unlock.append(_widget) for _item in list_multi_scat_correction: _widget.addItem(_item) _widget.setCurrentIndex(0) _master_table_row_ui['normalization']['mult_scat_correction'] = _widget _layout.addWidget(_widget) _w = QWidget() _w.setLayout(_layout) self.table_ui.setCellWidget(row, column, _w) # column 22 - inelastic correction column += 1 _layout = QHBoxLayout() _layout.setContentsMargins(0, 0, 0, 0) _widget1 = QComboBox() _widget1.setMinimumHeight(20) list_inelastic_correction = self.get_inelastic_scattering_list( shape=_shape_default_value) for _item in list_inelastic_correction: _widget1.addItem(_item) _widget1.setCurrentIndex(0) _master_table_row_ui['normalization'][ 'inelastic_correction'] = _widget1 _button = QPushButton("...") _button.setFixedWidth(CONFIG_BUTTON_WIDTH) _button.setFixedHeight(CONFIG_BUTTON_HEIGHT) _button.pressed.connect( lambda key=random_key: self.main_window. master_table_normalization_placzek_button_pressed(key)) _master_table_row_ui['normalization']['placzek_button'] = _button _button.setVisible(False) _layout.addWidget(_widget1) _layout.addWidget(_button) _widget = QWidget() _widget.setLayout(_layout) _default_value = 'None' _widget1.currentIndexChanged.connect( lambda value=_default_value, key=random_key: self.main_window. master_table_normalization_inelastic_correction_changed( value, key)) # noqa _widget.blockSignals(True) _list_ui_to_unlock.append(_widget) self.table_ui.setCellWidget(row, column, _widget) # automatically populate placzek infos with default values _norm_formated_placzek_default = self.formated_placzek_default( normalization_placzek_arguments) _master_table_row_ui['normalization'][ 'placzek_infos'] = _norm_formated_placzek_default # column 23 - key/value pair column += 1 _layout = QHBoxLayout() _spacer_kv1 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) _layout.addItem(_spacer_kv1) _button = QPushButton("...") _layout.addWidget(_button) _button.setFixedWidth(CONFIG_BUTTON_WIDTH) _button.setFixedHeight(CONFIG_BUTTON_HEIGHT) _button.pressed.connect(lambda key=random_key: self.main_window. master_table_keyvalue_button_pressed(key)) _new_widget = QWidget() _new_widget.setLayout(_layout) self.table_ui.setCellWidget(row, column, _new_widget) _master_table_row_ui['align_and_focus_args_button'] = _button _spacer_kv2 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) _layout.addItem(_spacer_kv2) _layout.addStretch() align_and_focus_args = self.add_global_key_value_to_local_key_value( align_and_focus_args) _master_table_row_ui[ 'align_and_focus_args_infos'] = align_and_focus_args # Recap. self.main_window.master_table_list_ui[ random_key] = _master_table_row_ui self.unlock_signals_ui(list_ui=_list_ui_to_unlock) self.main_window.check_status_of_right_click_buttons()
def _setupOpticsParamLayout(self): self.lb_x = QLabel('<h4>X</h4>', self, alignment=Qt.AlignCenter) self.lb_y = QLabel('<h4>Y</h4>', self, alignment=Qt.AlignCenter) self.lb_sp = QLabel('<h4>SP</h4>', self, alignment=Qt.AlignCenter) self.lb_rb = QLabel('<h4>RB</h4>', self, alignment=Qt.AlignCenter) self.lb_mon = QLabel( '<h4>Estimative</h4>', self, alignment=Qt.AlignCenter) self.sb_paramx = PyDMSpinbox(self, self.ioc_prefix.substitute( propty=self.param_pv.format('X', 'SP'))) self.sb_paramx.showStepExponent = False self.sb_paramy = PyDMSpinbox(self, self.ioc_prefix.substitute( propty=self.param_pv.format('Y', 'SP'))) self.sb_paramy.showStepExponent = False self.lb_paramx = PyDMLabel(self, self.ioc_prefix.substitute( propty=self.param_pv.format('X', 'RB'))) self.lb_paramy = PyDMLabel(self, self.ioc_prefix.substitute( propty=self.param_pv.format('Y', 'RB'))) self.lb_prmmonx = PyDMLabel(self, self.ioc_prefix.substitute( propty=self.param_pv.format('X', 'Mon'))) self.lb_prmmony = PyDMLabel(self, self.ioc_prefix.substitute( propty=self.param_pv.format('Y', 'Mon'))) self.bt_apply = PyDMPushButton( self, label='Apply', pressValue=1, init_channel=self.ioc_prefix.substitute( propty='ApplyDelta-Cmd')) lay = QGridLayout() lay.addWidget(self.lb_sp, 0, 1) lay.addWidget(self.lb_rb, 0, 2) lay.addWidget(self.lb_x, 1, 0) lay.addWidget(self.sb_paramx, 1, 1) lay.addWidget(self.lb_paramx, 1, 2) lay.addWidget(self.lb_y, 2, 0) lay.addWidget(self.sb_paramy, 2, 1) lay.addWidget(self.lb_paramy, 2, 2) lay.addWidget(self.lb_mon, 0, 3) lay.addWidget(self.lb_prmmonx, 1, 3) lay.addWidget(self.lb_prmmony, 2, 3) lay.addWidget(self.bt_apply, 3, 1) lay.setColumnStretch(0, 1) lay.setColumnStretch(1, 5) lay.setColumnStretch(2, 5) lay.setColumnStretch(3, 5) if self.acc == 'SI' and self.param == 'chrom': self._icon_absval = qta.icon( 'mdi.alpha-a', 'mdi.alpha-b', 'mdi.alpha-s', options=[ dict(scale_factor=1.5, offset=(-0.4, 0.0)), dict(scale_factor=1.5, offset=(0.0, 0.0)), dict(scale_factor=1.5, offset=(+0.4, 0.0))]) self._icon_delta = qta.icon('mdi.delta') self._is_setting = 'absolut' self.pb_change_sp = QPushButton(self._icon_absval, '', self) self.pb_change_sp.clicked.connect(self._change_chrom_sp) self.sb_paramx_delta = PyDMSpinbox( self, self.ioc_prefix.substitute(propty='DeltaChromX-SP')) self.sb_paramx_delta.showStepExponent = False self.sb_paramx_delta.setVisible(False) self.sb_paramy_delta = PyDMSpinbox( self, self.ioc_prefix.substitute(propty='DeltaChromY-SP')) self.sb_paramy_delta.showStepExponent = False self.sb_paramy_delta.setVisible(False) self.lb_paramx_delta = PyDMLabel( self, self.ioc_prefix.substitute(propty='DeltaChromX-RB')) self.lb_paramx_delta.setVisible(False) self.lb_paramy_delta = PyDMLabel( self, self.ioc_prefix.substitute(propty='DeltaChromY-RB')) self.lb_paramy_delta.setVisible(False) self.lb_mon.setText('Implem.\nEstimative') self.lb_mon.setStyleSheet('font-weight: bold;') self.lb_calcmon = QLabel( 'Calcd.\nEstimative', self, alignment=Qt.AlignCenter) self.lb_calcmon.setStyleSheet('font-weight: bold;') self.lb_prmcalcmonx = PyDMLabel( self, self.ioc_prefix.substitute(propty='CalcChromX-Mon')) self.lb_prmcalcmony = PyDMLabel( self, self.ioc_prefix.substitute(propty='CalcChromY-Mon')) lay.addWidget(self.pb_change_sp, 0, 0) lay.addWidget(self.sb_paramx_delta, 1, 1) lay.addWidget(self.sb_paramy_delta, 2, 1) lay.addWidget(self.lb_paramx_delta, 1, 2) lay.addWidget(self.lb_paramy_delta, 2, 2) lay.addWidget(self.lb_calcmon, 0, 4) lay.addWidget(self.lb_prmcalcmonx, 1, 4) lay.addWidget(self.lb_prmcalcmony, 2, 4) return lay
def _setupUi(self): self._ld_stthw = QLabel('Hardware state', self) self._led_stthw = PyDMLedMultiChannel( self, channels2values={ self.dev_pref.substitute(propty='StateHw-Mon'): { 'value': [0x4C, 0x3C], 'comp': 'in' } }) # in [Op, Ready] self._led_stthw.offColor = PyDMLed.Yellow self._led_stthw.onColor = PyDMLed.LightGreen self._led_stthw.setObjectName('led') self._led_stthw.setStyleSheet('#led{max-width: 1.29em;}') self._led_stthw.setSizePolicy(QSzPlcy.Maximum, QSzPlcy.Preferred) self._lb_stthw = PyDMLabel( self, self.dev_pref.substitute(propty='StateHw-Mon')) self._ld_sttsys = QLabel('System state', self) self._led_sttsys = PyDMLedMultiChannel( self, channels2values={ self.dev_pref.substitute(propty='State-Mon'): { 'value': [1, 4], 'comp': 'in' } }) # in [Op, Standby] self._led_sttsys.offColor = PyDMLed.Yellow self._led_sttsys.onColor = PyDMLed.LightGreen self._led_sttsys.setObjectName('led') self._led_sttsys.setStyleSheet('#led{max-width: 1.29em;}') self._led_sttsys.setSizePolicy(QSzPlcy.Maximum, QSzPlcy.Preferred) self._lb_sttsys = PyDMLabel( self, self.dev_pref.substitute(propty='State-Mon')) self._ld_isopr = QLabel('Is operational', self) self._led_isopr = PyDMLed( self, self.dev_pref.substitute(propty='IsOperational-Mon')) self._led_isopr.offColor = PyDMLed.Red self._led_isopr.onColor = PyDMLed.LightGreen self._led_isopr.setStyleSheet('max-width: 1.29em;') self._led_isopr.setSizePolicy(QSzPlcy.Maximum, QSzPlcy.Preferred) lay_hwsys = QGridLayout(self) lay_hwsys.addWidget( QLabel('<h4>Hardware&&LowLevel</h4>', self, alignment=Qt.AlignCenter), 0, 0, 1, 3) lay_hwsys.addWidget(self._ld_stthw, 2, 0) lay_hwsys.addWidget(self._led_stthw, 2, 1) lay_hwsys.addWidget(self._lb_stthw, 2, 2) lay_hwsys.addWidget(self._ld_sttsys, 3, 0) lay_hwsys.addWidget(self._led_sttsys, 3, 1) lay_hwsys.addWidget(self._lb_sttsys, 3, 2) lay_hwsys.addWidget(self._ld_isopr, 4, 0) lay_hwsys.addWidget(self._led_isopr, 4, 1)
def _setupUi(self): label = QLabel('<h3>'+self.title+'</h3>', self) label.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));""") self.gb_status = QGroupBox('Status', self) self.gb_status.setLayout(self._setupStatusLayout()) self.wid_optics = QWidget() lay_optics = QGridLayout(self.wid_optics) lay_optics.setContentsMargins(0, 0, 0, 0) self.gb_optprm = QGroupBox( 'ΔTune' if self.param == 'tune' else 'Chromaticity', self) self.gb_optprm.setLayout(self._setupOpticsParamLayout()) if self.param == 'tune': self.pb_updref = PyDMPushButton( self, label='Update Reference', pressValue=1, init_channel=self.ioc_prefix.substitute(propty='SetNewRefKL-Cmd')) self.pb_updref.setStyleSheet('min-height:2.4em; max-height:2.4em;') lay_optics.addWidget(self.pb_updref, 0, 0, 1, 2) lay_optics.addWidget(self.gb_optprm, 1, 0) if self.acc == 'SI': self.gb_digmon = QGroupBox('Tune Monitor', self) self.gb_digmon.setLayout(self._setupDigMonLayout()) lay_optics.addWidget(self.gb_digmon, 1, 1) lay_optics.setColumnStretch(0, 3) lay_optics.setColumnStretch(1, 1) else: lay_optics.addWidget(self.gb_optprm, 0, 0) self.gb_fams = QGroupBox('Families', self) self.gb_fams.setLayout(self._setupFamiliesLayout()) self.gb_fams.setSizePolicy(QSzPly.Preferred, QSzPly.Expanding) self.gb_iocctrl = QGroupBox('IOC Control', self) self.gb_iocctrl.setLayout(self._setupIOCControlLayout()) cwt = QWidget() self.setCentralWidget(cwt) if self.acc == 'SI': vlay1 = QVBoxLayout() vlay1.setAlignment(Qt.AlignTop) vlay1.addWidget(self.wid_optics) vlay1.addWidget(self.gb_fams) lay = QGridLayout(cwt) lay.addWidget(label, 0, 0, 1, 2) lay.addLayout(vlay1, 1, 0, alignment=Qt.AlignTop) lay.addWidget(self.gb_iocctrl, 1, 1) lay.addWidget(self.gb_status, 2, 0, 1, 2) lay.setColumnStretch(0, 1) lay.setColumnStretch(1, 1) lay.setRowStretch(0, 1) lay.setRowStretch(1, 15) lay.setRowStretch(2, 5) else: lay = QVBoxLayout(cwt) lay.addWidget(label) lay.addWidget(self.wid_optics) lay.addWidget(self.gb_fams) lay.addWidget(self.gb_iocctrl) lay.addWidget(self.gb_status) self.setStyleSheet(""" PyDMLabel{ qproperty-alignment: AlignCenter; }""")
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 _setupUi(self): self._ld_almaxctrl = QLabel('<h4>Axis Control</h4>', self) self._ld_almflag = QLabel('Flag', self) self._lb_almflag = PyDMLabel( self, self.dev_pref.substitute(propty='AlrmPhase-Mon')) self._ld_almeid = QLabel('Error ID Code', self) self._lb_almeid = PyDMLabel( self, self.dev_pref.substitute(propty='AlrmPhaseErrID-Mon')) self._ld_almsttdw = QLabel('State DWord', self) self._lb_almsttdw = PyDMLabel( self, self.dev_pref.substitute(propty='AlrmPhaseSttDW-Mon')) self._ld_almsttcode = QLabel('State Code', self) self._lb_almsttcode = PyDMLabel( self, self.dev_pref.substitute(propty='AlrmPhaseStt-Mon')) self._ld_almrack = QLabel('<h4>Rack</h4>', self) self._ld_almestop = QLabel('E-Stop button pressed', self) self._led_almestop = PyDMLed( self, self.dev_pref.substitute(propty='AlrmRackEStop-Mon')) self._led_almestop.offColor = PyDMLed.LightGreen self._led_almestop.onColor = PyDMLed.Red self._ld_almkillpres = QLabel('Kill switch pressed', self) self._led_almkillpres = PyDMLed( self, self.dev_pref.substitute(propty='AlrmRackKill-Mon')) self._led_almkillpres.offColor = PyDMLed.LightGreen self._led_almkillpres.onColor = PyDMLed.Red self._ld_almkilldsbl = QLabel('Kill switches disabled', self) self._led_almkilldsbl = PyDMLed( self, self.dev_pref.substitute(propty='AlrmRackKillDsbld-Mon')) self._led_almkilldsbl.offColor = PyDMLed.LightGreen self._led_almkilldsbl.onColor = PyDMLed.Red self._ld_almpwrdsbl = QLabel('Power disabled', self) self._led_almpwrdsbl = PyDMLed( self, self.dev_pref.substitute(propty='AlrmRackPwrDsbld-Mon')) self._led_almpwrdsbl.offColor = PyDMLed.LightGreen self._led_almpwrdsbl.onColor = PyDMLed.Red lay = QGridLayout(self) lay.addWidget( QLabel('<h4>Alarms</h4>', self, alignment=Qt.AlignCenter), 0, 0, 1, 2) lay.addWidget(self._ld_almaxctrl, 1, 0, 1, 2) lay.addWidget(self._ld_almflag, 2, 0) lay.addWidget(self._lb_almflag, 2, 1) lay.addWidget(self._ld_almeid, 3, 0) lay.addWidget(self._lb_almeid, 3, 1) lay.addWidget(self._ld_almsttdw, 4, 0) lay.addWidget(self._lb_almsttdw, 4, 1) lay.addWidget(self._ld_almsttcode, 5, 0) lay.addWidget(self._lb_almsttcode, 5, 1) lay.addItem(QSpacerItem(1, 10, QSzPlcy.Ignored, QSzPlcy.Fixed), 6, 0) lay.addWidget(self._ld_almrack, 7, 0, 1, 2) lay.addWidget(self._ld_almestop, 8, 0) lay.addWidget(self._led_almestop, 8, 1) lay.addWidget(self._ld_almkillpres, 9, 0) lay.addWidget(self._led_almkillpres, 9, 1) lay.addWidget(self._ld_almkilldsbl, 10, 0) lay.addWidget(self._led_almkilldsbl, 10, 1) lay.addWidget(self._ld_almpwrdsbl, 11, 0) lay.addWidget(self._led_almpwrdsbl, 11, 1)
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 create_layout(self): cancel_box = QHBoxLayout() cancel_box.addWidget(self.close_button) grid1 = QGridLayout() grid2 = QGridLayout() #----------------------------------------- # setup self.radio_rectangular = QRadioButton('Rectangular') self.radio_cylindrical = QRadioButton('Cylindrical') self.radio_spherical = QRadioButton('Spherical') coord_type_layout = QHBoxLayout() coord_type_layout.addWidget(self.radio_rectangular) coord_type_layout.addWidget(self.radio_cylindrical) coord_type_layout.addWidget(self.radio_spherical) location_layout = QHBoxLayout() location_layout.addWidget(self.location_x_edit) location_layout.addWidget(self.location_y_edit) location_layout.addWidget(self.location_z_edit) checkboxs = QButtonGroup(self) checkboxs.addButton(self.checkbox_show) checkboxs.addButton(self.checkbox_hide) vbox1 = QVBoxLayout() vbox1.addWidget(self.checkbox_show) vbox1.addWidget(self.checkbox_hide) #vbox1.addLayout(checkboxs) #----------------------------------------- irow = 0 grid1.addWidget(self.all_nodes_header, irow, 0) irow += 1 grid1.addWidget(self.color, irow, 0) grid1.addWidget(self.color_edit, irow, 1) irow += 1 grid1.addWidget(self.opacity, irow, 0) grid1.addWidget(self.opacity_edit, irow, 1) irow += 1 grid1.addWidget(self.point_size, irow, 0) grid1.addWidget(self.point_size_edit, irow, 1) irow += 1 #----------------------------------------- irow = 0 grid2.addWidget(self.nodes_header, irow, 0) irow += 1 grid2.addWidget(self.name, irow, 0) grid2.addWidget(self.name_edit, irow, 1) irow += 1 grid2.addWidget(self.description, irow, 0) grid2.addWidget(self.description_edit, irow, 1) irow += 1 #| All Nodes: | #| Color red | #| PointSize 3 | #| Opacity 0.3 | #| Show/Hide | #| | #| Name LEwingTip | #| Location X Y Z | #| Coord 0 | #| CoordType R, C, S | #| | #| Previous Next | grid2.addWidget(self.coord, irow, 0) grid2.addWidget(self.coord_edit, irow, 1) irow += 1 grid2.addWidget(self.coord_type, irow, 0) grid2.addLayout(coord_type_layout, irow, 1) irow += 1 grid2.addWidget(self.location, irow, 0) grid2.addLayout(location_layout, irow, 1) irow += 1 #------------------------------------ vbox = QVBoxLayout() vbox.addLayout(grid1) vbox.addLayout(vbox1) vbox.addStretch() vbox.addWidget(self.table) vbox.addLayout(grid2) vbox.addStretch() #vbox.addWidget(self.check_apply) vbox.addLayout(cancel_box) self.setLayout(vbox)