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 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
def refresh_table(self, job_list): for _row in range(self.ui.tableWidget.rowCount()): self.ui.tableWidget.removeRow(0) nbr_row = len(job_list) for _row in range(nbr_row): _row_job = job_list[_row] self.ui.tableWidget.insertRow(_row) # job name _item = QTableWidgetItem(_row_job['job_name']) self.ui.tableWidget.setItem(_row, 0, _item) # time _item = QTableWidgetItem(_row_job['time']) self.ui.tableWidget.setItem(_row, 1, _item) # action _pid = _row_job['pid'] process = psutil.Process(_pid) # TODO check status result if not process.is_running(): _item = QTableWidgetItem("Done!") self.ui.tableWidget.setItem(_row, 2, _item) else: if _row_job['status'] == 'processing': _widget = QPushButton() _widget.setText("Abort!") _widget.clicked.connect(lambda row=_row: self.parent.kill_job(row)) self.ui.tableWidget.setCellWidget(_row, 2, _widget) else: _item = QTableWidgetItem("Killed!") self.ui.tableWidget.setItem(_row, 2, _item)
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.search_bar = QLineEdit() search_bar_layout = QHBoxLayout() search_bar_layout.addWidget(QLabel('Custom Query:')) search_bar_layout.addWidget(self.search_bar) mongo_query_help_button = QPushButton() mongo_query_help_button.setText('?') search_bar_layout.addWidget(mongo_query_help_button) mongo_query_help_button.clicked.connect(self.show_mongo_query_help) self.since_widget = QDateTimeEdit() self.since_widget.setCalendarPopup(True) self.since_widget.setDisplayFormat('yyyy-MM-dd HH:mm') since_layout = QHBoxLayout() since_layout.addWidget(QLabel('Since:')) since_layout.addWidget(self.since_widget) self.until_widget = QDateTimeEdit() self.until_widget.setCalendarPopup(True) self.until_widget.setDisplayFormat('yyyy-MM-dd HH:mm') until_layout = QHBoxLayout() until_layout.addWidget(QLabel('Until:')) until_layout.addWidget(self.until_widget) layout = QVBoxLayout() layout.addLayout(since_layout) layout.addLayout(until_layout) layout.addLayout(search_bar_layout) self.setLayout(layout)
class PipOutput(QDialog): def __init__(self, parent=None): super(PipOutput, self).__init__(parent) self.create_controls() def sizeHint(self): def_sz = super(PipOutput, self).sizeHint() def_sz.setWidth(500) return def_sz def create_controls(self): self.setWindowTitle(tr("Updating via pip")) wFlags = self.windowFlags() if Qt.WindowCloseButtonHint == (wFlags & Qt.WindowCloseButtonHint): wFlags ^= Qt.WindowCloseButtonHint self.setWindowFlags(wFlags) vbox = QVBoxLayout() self.output = QTextEdit() if self.parent() and hasattr(self.parent(), 'console'): self.output.setFont(self.parent().console.font) vbox.addWidget(self.output) hbox = QHBoxLayout() hbox.addStretch() self.btn_close = QPushButton(tr("Close")) self.btn_close.clicked.connect(self.accept) self.btn_close.setEnabled(False) hbox.addWidget(self.btn_close) vbox.addLayout(hbox) self.setLayout(vbox)
def __init__(self, parent=None, filename=None): QPushButton.__init__(self, parent) PyDMPrimitiveWidget.__init__(self) self.mouseReleaseEvent = self.push_button_release_event self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.show_context_menu) self.iconFont = IconFont() self._icon = self.iconFont.icon("file") self.setIconSize(QSize(16, 16)) self.setIcon(self._icon) self._filenames = [] self._titles = [] self._macros = [] self.num_additional_items = 0 self._shift_key_was_down = False self.setCursor(QCursor(self._icon.pixmap(16, 16))) self._display_menu_items = None self._display_filename = filename if filename is not None else "" self._macro_string = None self._open_in_new_window = False self.open_in_new_window_action = QAction("Open in New Window", self) self.open_in_new_window_action.triggered.connect(partial(self.open_display, target=self.NEW_WINDOW)) self._show_icon = True self._menu_needs_rebuild = True
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.uid_label = QLabel() self.open_individually_button = QPushButton('Open individually') self.open_individually_button.hide() self.open_individually_button.clicked.connect(self._open_individually) self.open_overplotted_button = QPushButton('Open over-plotted') self.open_overplotted_button.hide() self.open_overplotted_button.clicked.connect(self._open_overplotted) self.open_overplotted_on_button = QPushButton('Add to tab...') self.open_overplotted_on_button.hide() self.open_overplotted_on_button.setEnabled(False) self.open_overplotted_on_button.clicked.connect(self._open_overplotted_on) self.copy_uid_button = QPushButton('Copy UID to Clipboard') self.copy_uid_button.hide() self.copy_uid_button.clicked.connect(self._copy_uid) self.streams = QLabel() self.entries = [] uid_layout = QHBoxLayout() uid_layout.addWidget(self.uid_label) uid_layout.addWidget(self.copy_uid_button) layout = QVBoxLayout() layout.addWidget(self.open_individually_button) layout.addWidget(self.open_overplotted_button) layout.addWidget(self.open_overplotted_on_button) layout.addLayout(uid_layout) layout.addWidget(self.streams) self.setLayout(layout) self._tab_titles = ()
def __init__(self, text, title='', font=None, parent=None, readonly=False, size=(400, 300)): 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.text = None self.btn_save_and_close = None # Display text as unicode if it comes as bytes, so users see # its right representation if is_binary_string(text): self.is_binary = True text = to_text_string(text, 'utf8') else: self.is_binary = False self.layout = QVBoxLayout() self.setLayout(self.layout) # Text edit self.edit = QTextEdit(parent) self.edit.setReadOnly(readonly) self.edit.textChanged.connect(self.text_changed) self.edit.setPlainText(text) if font is None: font = get_font() self.edit.setFont(font) self.layout.addWidget(self.edit) # Buttons configuration btn_layout = QHBoxLayout() 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) # Make the dialog act as a window self.setWindowFlags(Qt.Window) self.setWindowIcon(ima.icon('edit')) self.setWindowTitle(_("Text editor") + \ "%s" % (" - "+str(title) if str(title) else "")) self.resize(size[0], size[1])
def event(self, event): if event.type() == QEvent.KeyPress: key = event.key() if key in [Qt.Key_Tab]: self.sig_enter_first.emit() return True else: return QPushButton.event(self, event) else: return QPushButton.event(self, event)
def _make_export_button(self): """ Makes the export button menu, containing a list of export types :return: The export button menu """ export_button = QPushButton("Export") export_menu = QMenu() for text, extension in EXPORT_TYPES: export_menu.addAction(text, lambda ext=extension: self.presenter.export_plots_called(ext)) export_button.setMenu(export_menu) return export_button
def __init__(self, presenter, plot_number, parent=None): super(PlotNameWidget, self).__init__(parent) self.presenter = presenter self.plot_number = plot_number self.mutex = QMutex() self.line_edit = QLineEdit(self.presenter.get_plot_name_from_number(plot_number)) self.line_edit.setReadOnly(True) self.line_edit.setFrame(False) self.line_edit.setStyleSheet("* { background-color: rgba(0, 0, 0, 0); }") self.line_edit.setAttribute(Qt.WA_TransparentForMouseEvents, True) self.line_edit.editingFinished.connect(self.rename_plot) shown_icon = get_icon('mdi.eye') self.hide_button = QPushButton(shown_icon, "") self.hide_button.setToolTip('Hide') self.hide_button.setFlat(True) self.hide_button.setMaximumWidth(self.hide_button.iconSize().width() * 5 / 3) self.hide_button.clicked.connect(self.toggle_visibility) rename_icon = get_icon('mdi.square-edit-outline') self.rename_button = QPushButton(rename_icon, "") self.rename_button.setToolTip('Rename') self.rename_button.setFlat(True) self.rename_button.setMaximumWidth(self.rename_button.iconSize().width() * 5 / 3) self.rename_button.setCheckable(True) self.rename_button.toggled.connect(self.rename_button_toggled) close_icon = get_icon('mdi.close') self.close_button = QPushButton(close_icon, "") self.close_button.setToolTip('Delete') self.close_button.setFlat(True) self.close_button.setMaximumWidth(self.close_button.iconSize().width() * 5 / 3) self.close_button.clicked.connect(lambda: self.close_pressed(self.plot_number)) self.layout = QHBoxLayout() # Get rid of the top and bottom margins - the button provides # some natural margin anyway. Get rid of right margin and # reduce spacing to get buttons closer together. self.layout.setContentsMargins(5, 0, 0, 0) self.layout.setSpacing(0) self.layout.addWidget(self.line_edit) self.layout.addWidget(self.hide_button) self.layout.addWidget(self.rename_button) self.layout.addWidget(self.close_button) self.layout.sizeHint() self.setLayout(self.layout)
def __init__(self, parent=None, command=None): QPushButton.__init__(self, parent) PyDMPrimitiveWidget.__init__(self) self.iconFont = IconFont() self._icon = self.iconFont.icon("cog") self.setIconSize(QSize(16, 16)) self.setIcon(self._icon) self.setCursor(QCursor(self._icon.pixmap(16, 16))) self._command = command self._allow_multiple = False self.process = None self._show_icon = True
def paintEvent(self, event): QPushButton.paintEvent(self, event) color = self.color() padding = self.padding() rect = event.rect() painter = QPainter() painter.begin(self) painter.setBrush(QBrush(color)) painter.setPen(Qt.NoPen) rect.adjust(padding, padding, -1 - padding, -1 - padding) painter.drawRect(rect) painter.end()
def paintEvent(self, event): QPushButton.paintEvent(self, event) qp = QPainter() qp.begin(self) font = qp.font() font.setPixelSize(self.font().pixelSize() * 0.6) font.setWeight(QFont.Normal) qp.setFont(font) #qp.drawText(event.rect().translated(2, 2), str(self._atomic_number)) qp.end()
class ConnectionInspector(QWidget): def __init__(self, parent=None): super(ConnectionInspector, self).__init__(parent, Qt.Window) connections = self.fetch_data() self.table_view = ConnectionTableView(connections, self) self.setLayout(QVBoxLayout(self)) self.layout().addWidget(self.table_view) button_layout = QHBoxLayout() self.layout().addItem(button_layout) self.save_status_label = QLabel(self) button_layout.addWidget(self.save_status_label) button_layout.addStretch() self.save_button = QPushButton(self) self.save_button.setText("Save list to file...") self.save_button.clicked.connect(self.save_list_to_file) button_layout.addWidget(self.save_button) self.update_timer = QTimer(parent=self) self.update_timer.setInterval(1500) self.update_timer.timeout.connect(self.update_data) self.update_timer.start() def update_data(self): self.table_view.model().connections = self.fetch_data() def fetch_data(self): plugins = data_plugins.plugin_modules return [connection for p in plugins.values() for connection in p.connections.values() ] @Slot() def save_list_to_file(self): filename, filters = QFileDialog.getSaveFileName(self, "Save connection list", "", "Text Files (*.txt)") try: with open(filename, "w") as f: for conn in self.table_view.model().connections: f.write( "{p}://{a}\n".format(p=conn.protocol, a=conn.address)) self.save_status_label.setText("File saved to {}".format(filename)) except Exception as e: msgBox = QMessageBox() msgBox.setText("Couldn't save connection list to file.") msgBox.setInformativeText("Error: {}".format(str(e))) msgBox.setStandardButtons(QMessageBox.Ok) msgBox.exec_()
class LSPManagerConfigPage(PluginConfigPage): """Language Server Protocol client manager preferences.""" def get_name(self): return _('Language Server Protocol Manager') def get_icon(self): return ima.icon('lspserver') def setup_page(self): self.table = LSPServerTable(self, text_color=ima.MAIN_FG_COLOR) self.reset_btn = QPushButton(_("Reset to default values")) self.new_btn = QPushButton(_("Setup a new server")) self.delete_btn = QPushButton(_("Delete currently selected server")) self.delete_btn.setEnabled(False) server_group = QGroupBox(_('Available LSP Servers')) vlayout = QVBoxLayout() vlayout.addWidget(server_group) # vlayout.addWidget(server_settings_description) vlayout.addWidget(self.table) vlayout.addWidget(self.new_btn) vlayout.addWidget(self.delete_btn) vlayout.addWidget(self.reset_btn) self.setLayout(vlayout) 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) def reset_to_default(self): CONF.reset_to_defaults(section='lsp-server') self.table.load_servers() self.load_from_conf() self.set_modified(True) def create_new_server(self): self.table.show_editor(new_server=True) def delete_server(self): idx = self.table.currentIndex().row() self.table.delete_server(idx) self.set_modified(True) self.delete_btn.setEnabled(False) def apply_changes(self): self.table.save_servers() # TODO: Reset Manager self.plugin.update_server_list()
def setup_ui(self): self.vertical_layout = QVBoxLayout(self) self.table_view = QTableView(self) self.table_view.setEditTriggers(QAbstractItemView.DoubleClicked) self.table_view.setProperty("showDropIndicator", False) self.table_view.setDragDropOverwriteMode(False) self.table_view.setSelectionMode(QAbstractItemView.SingleSelection) self.table_view.setSelectionBehavior(QAbstractItemView.SelectRows) self.table_view.setSortingEnabled(False) self.table_view.horizontalHeader().setStretchLastSection(True) self.table_view.verticalHeader().setVisible(False) self.table_view.setColumnWidth(0, 160) self.table_view.setColumnWidth(1, 160) self.table_view.setColumnWidth(2, 160) self.vertical_layout.addWidget(self.table_view) self.add_remove_layout = QHBoxLayout() spacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.add_remove_layout.addItem(spacer) self.add_button = QPushButton("Add Curve", self) self.add_remove_layout.addWidget(self.add_button) self.remove_button = QPushButton("Remove Curve", self) self.add_remove_layout.addWidget(self.remove_button) self.vertical_layout.addLayout(self.add_remove_layout) self.button_box = QDialogButtonBox(self) self.button_box.setOrientation(Qt.Horizontal) self.button_box.addButton("Done", QDialogButtonBox.AcceptRole) self.vertical_layout.addWidget(self.button_box) self.button_box.accepted.connect(self.saveChanges) self.button_box.rejected.connect(self.reject) self.setWindowTitle("Waveform Curve Editor")
def create_controls(self): self.btn_start = QPushButton(tr("Start")) self.btn_stop = QPushButton(tr("Stop")) self.btn_stop.setEnabled(False) self.btn_start.clicked.connect(self.start_recording) self.btn_stop.clicked.connect(self.stop_recording) self.chk_actions = QCheckBox(tr("Actions")) self.chk_code = QCheckBox(tr("Code")) for c in [self.chk_actions, self.chk_code]: c.setChecked(True) c.toggled.connect(self.update_filter) hbox = QHBoxLayout() for w in [self.btn_start, self.btn_stop]: hbox.addWidget(w) hbox2 = QHBoxLayout() for w in [self.chk_actions, self.chk_code]: hbox2.addWidget(w) vbox = QVBoxLayout() vbox.addLayout(hbox) vbox.addLayout(hbox2) wrap = QWidget() wrap.setLayout(vbox) height = vbox.sizeHint().height() wrap.setFixedHeight(height) self.setWidget(wrap)
def __init__(self, dim_info, number=0, state=State.NONE, parent=None): super(Dimension, self).__init__(parent) self.minimum = dim_info['minimum'] self.nbins = dim_info['number_of_bins'] self.width = dim_info['width'] self.number = number self.layout = QHBoxLayout(self) self.name = QLabel(dim_info['name']) self.units = QLabel(dim_info['units']) self.x = QPushButton('X') self.x.setFixedSize(32,32) self.x.setCheckable(True) self.x.clicked.connect(self.x_clicked) self.y = QPushButton('Y') self.y.setFixedSize(32,32) self.y.setCheckable(True) self.y.clicked.connect(self.y_clicked) self.slider = QSlider(Qt.Horizontal) self.slider.setRange(0, self.nbins-1) self.slider.valueChanged.connect(self.slider_changed) self.spinbox = QDoubleSpinBox() self.spinbox.setDecimals(3) self.spinbox.setRange(self.get_bin_center(0), self.get_bin_center(self.nbins-1)) self.spinbox.setSingleStep(self.width) self.spinbox.valueChanged.connect(self.spinbox_changed) self.layout.addWidget(self.name) self.layout.addWidget(self.x) self.layout.addWidget(self.y) self.layout.addWidget(self.slider, stretch=1) self.layout.addStretch(0) self.layout.addWidget(self.spinbox) self.layout.addWidget(self.units) self.set_value(0) if self.nbins < 2: state = State.DISABLE self.set_state(state)
def _init_ui(self): # LINE 1: Data component drop down self.component_prompt = QLabel("Data Component:") self.component_prompt.setWordWrap(True) # Add the data component labels to the drop down, with the ComponentID # set as the userData: if self.parent is not None and hasattr(self.parent, 'data_components'): self.label_data = [(str(cid), cid) for cid in self.parent.data_components] else: self.label_data = [(str(cid), cid) for cid in self.data.visible_components] default_index = 0 self.component_combo = QComboBox() self.component_combo.setFixedWidth(200) update_combobox(self.component_combo, self.label_data, default_index=default_index) self.component_combo.currentIndexChanged.connect(self.update_unit_layout) # hbl is short for Horizontal Box Layout hbl1 = QHBoxLayout() hbl1.addWidget(self.component_prompt) hbl1.addWidget(self.component_combo) hbl1.addStretch(1) # LINE 2: Unit conversion layout # This layout is filled by CubeVizUnit self.unit_layout = QHBoxLayout() # this is hbl2 # LINE 3: Message box self.message_box = QLabel("") hbl3 = QHBoxLayout() hbl3.addWidget(self.message_box) hbl3.addStretch(1) # Line 4: Buttons ok_text = "Convert Data" if self.convert_data else "Convert Displayed Units" ok_function = self.convert_data_units if self.convert_data else self.convert_displayed_units self.okButton = QPushButton(ok_text) self.okButton.clicked.connect(ok_function) self.okButton.setDefault(True) self.cancelButton = QPushButton("Cancel") self.cancelButton.clicked.connect(self.cancel) hbl4 = QHBoxLayout() hbl4.addStretch(1) hbl4.addWidget(self.cancelButton) hbl4.addWidget(self.okButton) vbl = QVBoxLayout() vbl.addLayout(hbl1) vbl.addLayout(self.unit_layout) vbl.addLayout(hbl3) vbl.addLayout(hbl4) self.setLayout(vbl) self.vbl = vbl self.update_unit_layout(default_index) self.show()
def __init__(self, atomic_number, parent=None): QPushButton.__init__(self, parent) self._atomic_number = atomic_number self._symbol = get_symbol(atomic_number) self.setText(self._symbol) font = self.font() font.setWeight(QFont.Bold) self.setFont(font) self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) self.setDefault(False) self.setAutoDefault(False)
def create_controls(self, path): editor = api.CodeEdit() editor.backend.start(server.__file__) # editor.panels.append(panels.FoldingPanel()) editor.panels.append(panels.LineNumberPanel()) editor.panels.append(panels.CheckerPanel()) editor.modes.append(modes.CaretLineHighlighterMode()) editor.modes.append(modes.CodeCompletionMode()) editor.modes.append(modes.ExtendedSelectionMode()) editor.modes.append(modes.FileWatcherMode()) editor.modes.append(modes.RightMarginMode()) editor.modes.append(modes.SmartBackSpaceMode()) editor.modes.append(modes.OccurrencesHighlighterMode()) editor.modes.append(modes.SymbolMatcherMode()) # editor.modes.append(modes.WordClickMode()) editor.modes.append(modes.ZoomMode()) editor.modes.append(pymodes.PythonSH(editor.document())) editor.modes.append(pymodes.CommentsMode()) editor.modes.append(ConsoleCodeCalltipsMode(self)) editor.modes.append(ConsoleCodeCheckerMode(self)) editor.modes.append(pymodes.PEP8CheckerMode()) editor.modes.append(pymodes.PyAutoCompleteMode()) editor.modes.append(pymodes.PyAutoIndentMode()) editor.modes.append(pymodes.PyIndenterMode()) if path is not None: editor.file._path = path self.editor = editor self.tab = TabWidget(self) if path is not None and os.path.isfile(path): self.tab.add_code_edit(editor) else: self.tab.add_code_edit(editor, tr("untitled") + "%d.py") self.btn_save = QPushButton(tr("Save")) self.btn_run = QPushButton(tr("Run")) self.btn_make_plugin = QPushButton(tr("Make Plugin")) self.btn_reg_plugin = QPushButton(tr("Register Plugin")) self.btn_reg_plugin.setVisible(False) self.btn_save.clicked.connect(self.save) self.btn_run.clicked.connect(self.run) self.btn_make_plugin.clicked.connect(self.make_plugin) self.btn_reg_plugin.clicked.connect(self.register_plugin) self.hbox = QHBoxLayout() for w in [self.btn_save, self.btn_run, self.btn_make_plugin, self.btn_reg_plugin]: self.hbox.addWidget(w) vbox = QVBoxLayout(self) vbox.addWidget(self.tab) vbox.addLayout(self.hbox) self.setLayout(vbox)
def create_controls(self): """ Create UI controls. """ vbox = QVBoxLayout() form = QFormLayout() self.num_angle = QDoubleSpinBox() self.num_angle.setValue(0.0) self.num_angle.setMinimum(-360) self.num_angle.setMaximum(360) form.addRow(tr("Angle:"), self.num_angle) vbox.addLayout(form) self.gbo_preview = QGroupBox(tr("Preview")) self.gbo_preview.setCheckable(True) self.gbo_preview.setChecked(False) gbo_vbox = QVBoxLayout() self.chk_grid = QCheckBox(tr("Grid")) self.chk_grid.setChecked(False) self.num_grid = QSpinBox() self.num_grid.setValue(4) self.num_grid.setMinimum(1) self.num_grid.setEnabled(False) self.chk_grid.toggled[bool].connect(self.num_grid.setEnabled) gbo_vbox.addWidget(self.chk_grid) gbo_vbox.addWidget(self.num_grid) self.gbo_preview.setLayout(gbo_vbox) vbox.addWidget(self.gbo_preview) self.gbo_preview.toggled[bool].connect(self.set_preview) self.gbo_output = QGroupBox(tr("Output")) self.opt_new = QRadioButton(tr("New signal")) self.opt_replace = QRadioButton(tr("In place")) self.opt_new.setChecked(True) gbo_vbox2 = QVBoxLayout() gbo_vbox2.addWidget(self.opt_new) gbo_vbox2.addWidget(self.opt_replace) self.gbo_output.setLayout(gbo_vbox2) vbox.addWidget(self.gbo_output) self.chk_reshape = QCheckBox(tr("Resize to fit")) self.chk_reshape.setChecked(False) vbox.addWidget(self.chk_reshape) self.btn_ok = QPushButton(tr("&OK")) self.btn_ok.setDefault(True) self.btn_ok.clicked.connect(self.accept) self.btn_cancel = QPushButton(tr("&Cancel")) self.btn_cancel.clicked.connect(self.reject) hbox = QHBoxLayout() hbox.addWidget(self.btn_ok) hbox.addWidget(self.btn_cancel) vbox.addLayout(hbox) vbox.addStretch(1) self.setLayout(vbox)
class TabBarPlus(QTabBar): """Tab bar that has a plus button floating to the right of the tabs.""" plusClicked = Signal() def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # Plus Button self.plusButton = QPushButton("+") self.plusButton.setParent(self) self.plusButton.setFixedSize(20, 20) # Small Fixed size self.plusButton.clicked.connect(self.plusClicked.emit) self.movePlusButton() # Move to the correct location # end Constructor def sizeHint(self): """Return the size of the TabBar with increased width for the plus button.""" sizeHint = QTabBar.sizeHint(self) width = sizeHint.width() height = sizeHint.height() return QSize(width+25, height) # end tabSizeHint def resizeEvent(self, event): """Resize the widget and make sure the plus button is in the correct location.""" super().resizeEvent(event) self.movePlusButton() # end resizeEvent def tabLayoutChange(self): """This virtual handler is called whenever the tab layout changes. If anything changes make sure the plus button is in the correct location. """ super().tabLayoutChange() self.movePlusButton() # end tabLayoutChange def movePlusButton(self): """Move the plus button to the correct location.""" # Find the width of all of the tabs size = sum([self.tabRect(i).width() for i in range(self.count())]) # size = 0 # for i in range(self.count()): # size += self.tabRect(i).width() # Set the plus button location in a visible area h = self.geometry().top() w = self.width() if size > w: # Show just to the left of the scroll buttons self.plusButton.move(w-54, h) else: self.plusButton.move(size, h)
def create_browsedir(self, text, option, default=NoDefault, tip=None): widget = self.create_lineedit(text, option, default, alignment=Qt.Horizontal) for edit in self.lineedits: if widget.isAncestorOf(edit): break msg = _("Invalid directory path") self.validate_data[edit] = (osp.isdir, msg) browse_btn = QPushButton(ima.icon('DirOpenIcon'), '', self) browse_btn.setToolTip(_("Select directory")) browse_btn.clicked.connect(lambda: self.select_directory(edit)) layout = QHBoxLayout() layout.addWidget(widget) layout.addWidget(browse_btn) layout.setContentsMargins(0, 0, 0, 0) browsedir = QWidget(self) browsedir.setLayout(layout) return browsedir
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # Plus Button self.plusButton = QPushButton("+") self.plusButton.setParent(self) self.plusButton.setFixedSize(20, 20) # Small Fixed size self.plusButton.clicked.connect(self.plusClicked.emit) self.movePlusButton() # Move to the correct location
def _init_ui(self): self.slit_type_label = QLabel('Slit Type') self.slit_type_combo = QComboBox() self.slit_type_combo.currentIndexChanged.connect(self.update_info) hbl1 = QHBoxLayout() hbl1.addWidget(self.slit_type_label) hbl1.addWidget(self.slit_type_combo) self.slit_width_label = QLabel('Slit Width') self.slit_width_input = QLineEdit() self.slit_width_combo = QComboBox() self.slit_width_units = QLabel('arcsec') hbl2 = QHBoxLayout() hbl2.addWidget(self.slit_width_label) hbl2.addWidget(self.slit_width_input) hbl2.addWidget(self.slit_width_combo) hbl2.addWidget(self.slit_width_units) self.slit_length_label = QLabel('Slit Length') self.slit_length_input = QLineEdit() self.slit_length_combo = QComboBox() self.slit_length_units = QLabel('arcsec') hbl3 = QHBoxLayout() hbl3.addWidget(self.slit_length_label) hbl3.addWidget(self.slit_length_input) hbl3.addWidget(self.slit_length_combo) hbl3.addWidget(self.slit_length_units) self.okButton = QPushButton('Apply') self.okButton.clicked.connect(self.apply) self.okButton.setDefault(True) self.cancelButton = QPushButton('Cancel') self.cancelButton.clicked.connect(self.cancel) hbl4 = QHBoxLayout() hbl4.addWidget(self.cancelButton) hbl4.addWidget(self.okButton) vbl = QVBoxLayout() vbl.addLayout(hbl1) vbl.addLayout(hbl2) vbl.addLayout(hbl3) vbl.addLayout(hbl4) self.setLayout(vbl) self.vbl = vbl self._load_selections() self._populate_combo() self.update_info(0) self.show()
def _make_sort_button(self): """ Make the sort button, with separate groups for ascending and descending, sorting by name or last shown :return: The sort menu button """ sort_button = QPushButton("Sort") sort_menu = QMenu() ascending_action = QAction("Ascending", sort_menu, checkable=True) ascending_action.setChecked(True) ascending_action.toggled.connect(self.presenter.set_sort_order) descending_action = QAction("Descending", sort_menu, checkable=True) order_group = QActionGroup(sort_menu) order_group.addAction(ascending_action) order_group.addAction(descending_action) number_action = QAction("Number", sort_menu, checkable=True) number_action.setChecked(True) number_action.toggled.connect(lambda: self.presenter.set_sort_type(Column.Number)) name_action = QAction("Name", sort_menu, checkable=True) name_action.toggled.connect(lambda: self.presenter.set_sort_type(Column.Name)) last_active_action = QAction("Last Active", sort_menu, checkable=True) last_active_action.toggled.connect(lambda: self.presenter.set_sort_type(Column.LastActive)) sort_type_group = QActionGroup(sort_menu) sort_type_group.addAction(number_action) sort_type_group.addAction(name_action) sort_type_group.addAction(last_active_action) sort_menu.addAction(ascending_action) sort_menu.addAction(descending_action) sort_menu.addSeparator() sort_menu.addAction(number_action) sort_menu.addAction(name_action) sort_menu.addAction(last_active_action) sort_button.setMenu(sort_menu) return sort_button
def final_dialog(self, label): """ Final dialog that to show where the calculated collapsed cube was put. :param label: :return: """ final_dialog = QDialog() # Create data component label and input box widget_desc = QLabel('The collapsed cube was added as an overlay with label "{}". {}'.format( label, self._extra_message)) widget_desc.setWordWrap(True) widget_desc.setFixedWidth(350) widget_desc.setAlignment((Qt.AlignLeft | Qt.AlignTop)) hb_desc = QHBoxLayout() hb_desc.addWidget(widget_desc) # Create Ok button okButton = QPushButton("Ok") okButton.clicked.connect(lambda: final_dialog.close()) okButton.setDefault(True) hb_buttons = QHBoxLayout() hb_buttons.addStretch(1) hb_buttons.addWidget(okButton) # Add description and buttons to popup box vbl = QVBoxLayout() vbl.addLayout(hb_desc) vbl.addLayout(hb_buttons) final_dialog.setLayout(vbl) final_dialog.setMaximumWidth(400) final_dialog.show()
def __init__(self, parent, data, readonly=False, xlabels=None, ylabels=None): QWidget.__init__(self, parent) self.data = data self.old_data_shape = None if len(self.data.shape) == 1: self.old_data_shape = self.data.shape self.data.shape = (self.data.shape[0], 1) elif len(self.data.shape) == 0: self.old_data_shape = self.data.shape self.data.shape = (1, 1) format = SUPPORTED_FORMATS.get(data.dtype.name, '%s') self.model = ArrayModel(self.data, format=format, xlabels=xlabels, ylabels=ylabels, readonly=readonly, parent=self) self.view = ArrayView(self, self.model, data.dtype, data.shape) btn_layout = QHBoxLayout() btn_layout.setAlignment(Qt.AlignLeft) btn = QPushButton(_( "Format")) # disable format button for int type btn.setEnabled(is_float(data.dtype)) btn_layout.addWidget(btn) btn.clicked.connect(self.change_format) btn = QPushButton(_( "Resize")) btn_layout.addWidget(btn) btn.clicked.connect(self.view.resize_to_contents) bgcolor = QCheckBox(_( 'Background color')) bgcolor.setChecked(self.model.bgcolor_enabled) bgcolor.setEnabled(self.model.bgcolor_enabled) bgcolor.stateChanged.connect(self.model.bgcolor) btn_layout.addWidget(bgcolor) layout = QVBoxLayout() layout.addWidget(self.view) layout.addLayout(btn_layout) self.setLayout(layout)
class EditNodeProperties(QDialog): def __init__(self, data, win_parent=None): """ +-----------------+ | Edit Node Props | +-----------------+------+ | LEwingTip | | Node2 | | Node3 | | Node4 | | | | 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 | | | | Close | +------------------------+ """ QDialog.__init__(self, win_parent) self.setWindowTitle('Edit Node Properties') #default self.win_parent = win_parent self.out_data = data point_properties = data['point_properties'] print(point_properties) #name = point_properties.name point_size = point_properties.point_size opacity = point_properties.opacity color = point_properties.color show = point_properties.is_visible self.points = data['points'] self.keys = sorted(self.points.keys()) keys = self.keys #nrows = len(keys) active_point = data['active_point'] #self.active_key = keys[0] self.active_key = active_point name = self.active_key description = self.points[self.active_key][0] self._use_old_table = False items = ['Node %i' % val for val in keys] header_labels = ['Nodes'] table_model = Model(items, header_labels, self) view = SingleChoiceQTableView(self) #Call your custom QTableView here view.setModel(table_model) if qt_version == 4: view.horizontalHeader().setResizeMode(QHeaderView.Stretch) else: view.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) self.table = view #self.representation = actor_obj.representation #print('rep =', self.representation) table = self.table #headers = [QtCore.QString('Groups')] header = table.horizontalHeader() header.setStretchLastSection(True) #---------------------------------------------- #self._default_is_apply = False self.color = QLabel("Color:") self.color_edit = QPushButton() #self.color_edit.setFlat(True) color = self.out_data['point_properties'].color opacity = self.out_data['point_properties'].opacity show = self.out_data['point_properties'].is_visible #color = self.out_data[self.active_key].color qcolor = QColor() qcolor.setRgb(*color) #print('color =%s' % str(color)) palette = QPalette( self.color_edit.palette()) # make a copy of the palette #palette.setColor(QPalette.Active, QPalette.Base, \ #qcolor) palette.setColor(QPalette.Background, QColor('blue')) # ButtonText self.color_edit.setPalette(palette) self.color_edit.setStyleSheet("QPushButton {" "background-color: rgb(%s, %s, %s);" % tuple(color) + #"border:1px solid rgb(255, 170, 255); " "}") self.all_nodes_header = QLabel("All Nodes:") self.point_size = QLabel("Point Size:") self.point_size_edit = QSpinBox(self) self.point_size_edit.setRange(1, 10) self.point_size_edit.setSingleStep(1) self.point_size_edit.setValue(point_size) self.opacity = QLabel("Opacity:") self.opacity_edit = QDoubleSpinBox(self) self.opacity_edit.setRange(0.1, 1.0) self.opacity_edit.setDecimals(1) self.opacity_edit.setSingleStep(0.1) self.opacity_edit.setValue(opacity) # show/hide self.checkbox_show = QCheckBox("Show") self.checkbox_hide = QCheckBox("Hide") self.checkbox_show.setChecked(show) self.checkbox_hide.setChecked(not show) #---------------------------------------------- self.nodes_header = QLabel("Single Node:") self.name = QLabel("ID:") self.name_edit = QLineEdit('Node %i' % name) self.name_edit.setDisabled(True) self.description = QLabel("Description:") self.description_edit = QLineEdit(str(description)) #self.description_edit.setDisabled(True) location_x = 0.1 location_y = 0.1 location_z = 0.1 self.location = QLabel("Location:") self.location_x_edit = QDoubleSpinBox(self) self.location_y_edit = QDoubleSpinBox(self) self.location_z_edit = QDoubleSpinBox(self) #self.location_x_edit.setDecimals(1) delta_x = abs(location_x) / 100. if location_x != 0.0 else 0.1 delta_y = abs(location_y) / 100. if location_y != 0.0 else 0.1 delta_z = abs(location_z) / 100. if location_z != 0.0 else 0.1 self.location_x_edit.setSingleStep(delta_x) self.location_y_edit.setSingleStep(delta_y) self.location_z_edit.setSingleStep(delta_z) self.location_x_edit.setValue(location_x) self.location_y_edit.setValue(location_y) self.location_z_edit.setValue(location_z) self.coord = QLabel("Coord:") self.coord_edit = QSpinBox(self) self.coord_edit.setRange(0, 99999999) #self.coord_edit.setSingleStep(1) self.coord_edit.setValue(0) self.coord_type = QLabel("Coord Type:") #---------------------------------------------- # closing #if self._default_is_apply: #self.apply_button.setDisabled(True) self.close_button = QPushButton("Close") self.create_layout() self.set_connections() def update_active_key(self, index): name = self.active_key old_obj = self.out_data['points'][name] #self.active_key #self.points[self.active_key] old_obj[0] = str(self.description_edit.text()) #old_obj.coord = self.description_edit.value() #old_obj.description = self.description_edit.value() #old_obj.description = self.description_edit.value() str_name = str(index.data().toString()) name = int(str_name[5:]) #i = self.keys.index(self.active_key) self.active_key = name point = self.points[self.active_key] #1 : ['LERoot', 0, 'R', 1.0, 2.0, 3.0], self.name_edit.setText(str(self.active_key)) self.description_edit.setText(point[0]) self.coord_edit.setValue(point[1]) if point[2] == 'R': self.radio_rectangular.setChecked(True) elif point[2] == 'C': self.radio_cylindrical.setChecked(True) elif point[2] == 'S': self.radio_spherical.setChecked(True) self.location_x_edit.setValue(point[3]) self.location_y_edit.setValue(point[4]) self.location_z_edit.setValue(point[5]) #obj = self.out_data[name] #point_size = obj.point_size #opacity = obj.opacity #representation = obj.representation #is_visible = obj.is_visible #self.opacity_edit.setValue(opacity) #self.checkbox_show.setChecked(is_visible) #self.checkbox_hide.setChecked(not is_visible) #def on_name_select(self): #print('on_name_select') #return 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) def set_connections(self): if qt_version == 4: self.connect(self.opacity_edit, QtCore.SIGNAL('clicked()'), self.on_opacity) self.connect(self.point_size, QtCore.SIGNAL('clicked()'), self.on_point_size) self.connect(self.color_edit, QtCore.SIGNAL('clicked()'), self.on_color) self.connect(self.checkbox_show, QtCore.SIGNAL('clicked()'), self.on_show) self.connect(self.checkbox_hide, QtCore.SIGNAL('clicked()'), self.on_hide) self.connect(self.description_edit, QtCore.SIGNAL("valueChanged(int)"), self.on_description) self.connect(self.coord_edit, QtCore.SIGNAL("valueChanged(int)"), self.on_coord) self.connect(self.radio_rectangular, QtCore.SIGNAL('clicked()'), self.on_coord_type) self.connect(self.radio_cylindrical, QtCore.SIGNAL('clicked()'), self.on_coord_type) self.connect(self.radio_spherical, QtCore.SIGNAL('clicked()'), self.on_coord_type) self.connect(self.location_x_edit, QtCore.SIGNAL('clicked()'), self.on_location_x) self.connect(self.location_y_edit, QtCore.SIGNAL('clicked()'), self.on_location_y) self.connect(self.location_z_edit, QtCore.SIGNAL('clicked()'), self.on_location_z) self.connect(self.close_button, QtCore.SIGNAL('clicked()'), self.on_close) #self.connect(self.check_apply, QtCore.SIGNAL('clicked()'), self.on_check_apply) #self.connect(self.apply_button, QtCore.SIGNAL('clicked()'), self.on_apply) #self.connect(self.ok_button, QtCore.SIGNAL('clicked()'), self.on_ok) #self.connect(self.close_button, QtCore.SIGNAL('clicked()'), self.on_close) else: #self.opacity_edit.clicked.connect(self.on_opacity) #self.point_size.clicked.connect(self.on_point_size) #self.color_edit.clicked.connect(self.on_color) #self.checkbox_show.clicked.connect(self.on_show) #self.checkbox_hide.clicked.connect(self.on_hide) #self.description_edit.valueChanged.connect(self.on_description) #self.coord_edit.valueChanged.connect(self.on_coord) #self.radio_rectangular.clicked.connect(self.on_coord_type) #self.radio_cylindrical.clicked.connect(self.on_coord_type) #self.radio_spherical.clicked.connect(self.on_coord_type) #self.location_x_edit.clicked.connect(self.on_location_x) #self.location_y_edit.clicked.connect(self.on_location_y) #self.location_z_edit.clicked.connect(self.on_location_z) self.close_button.clicked.connect(self.on_close) def on_color(self): obj = self.out_data['point_properties'] rgb_color_ints = obj.color msg = 'Points' col = QColorDialog.getColor(QColor(*rgb_color_ints), self, "Choose a %s color" % msg) if col.isValid(): color = col.getRgbF()[:3] obj.color = color #print('new_color =', color) self.color_edit.setStyleSheet( "QPushButton {" "background-color: rgb(%s, %s, %s);" % tuple(obj.color) + #"border:1px solid rgb(255, 170, 255); " "}") def on_show(self): is_checked = self.checkbox_show.isChecked() self.out_data['point_properties'].is_visible = is_checked def on_hide(self): is_checked = self.checkbox_hide.isChecked() self.out_data['point_properties'].is_visible = not is_checked def on_point_size(self): point_size = self.point_size_edit.value() self.out_data['point_properties'].point_size = point_size def on_opacity(self): opacity = self.opacity_edit.value() self.out_data['point_properties'].opacity = opacity def on_description(self): #1 : ['LERoot', 0, 'R', 1.0, 2.0, 3.0], name = self.active_key description = self.description_edit.value() self.out_data['points'][name][0] = description def on_coord(self): #1 : ['LERoot', 0, 'R', 1.0, 2.0, 3.0], name = self.active_key coord_id = self.coord_edit.value() self.out_data['points'][name][1] = coord_id def on_coord_type(self): #1 : ['LERoot', 0, 'R', 1.0, 2.0, 3.0], name = self.active_key if self.radio_rectangular.isChecked(): coord_type = 'R' elif self.radio_cylindrical.isChecked(): coord_type = 'C' elif self.radio_spherical.isChecked(): coord_type = 'S' else: raise NotImplementedError() self.out_data['points'][name][2] = coord_type def on_location_x(self): #1 : ['LERoot', 0, 'R', 1.0, 2.0, 3.0], name = self.active_key value = self.coord_edit.value() self.out_data['points'][name][3] = value def on_location_y(self): #1 : ['LERoot', 0, 'R', 1.0, 2.0, 3.0], name = self.active_key value = self.coord_edit.value() self.out_data['points'][name][4] = value def on_location_z(self): #1 : ['LERoot', 0, 'R', 1.0, 2.0, 3.0], name = self.active_key value = self.coord_edit.value() self.out_data['points'][name][5] = value def closeEvent(self, event): event.accept() #def on_default_name(self): #self.name_edit.setText(str(self._default_name)) #self.name_edit.setStyleSheet("QLineEdit{background: white;}") #def check_name(self, cell): #text = str(cell.text()).strip() #if len(text): #cell.setStyleSheet("QLineEdit{background: white;}") #return text, True #else: #cell.setStyleSheet("QLineEdit{background: red;}") #return None, False def on_validate(self): self.out_data['clicked_ok'] = True self.out_data['clicked_cancel'] = False old_obj = self.out_data[self.active_key] old_obj.point_size = self.point_size_edit.value() old_obj.opacity = self.opacity_edit.value() old_obj.is_visible = self.checkbox_show.isChecked() return True #name_value, flag0 = self.check_name(self.name_edit) #ox_value, flag1 = check_float(self.transparency_edit) #if flag0 and flag1: #self.out_data['clicked_ok'] = True #return True #return False def on_apply(self): passed = self.on_validate() if passed: self.win_parent.on_update_gui_nodes(self.out_data) return passed def on_ok(self): passed = self.on_apply() if passed: self.close() #self.destroy() def on_close(self): self.out_data['clicked_close'] = True self.close()
class AboutViewWidget(QWidget): def __init__(self, parent, version_text, date_text): super(AboutViewWidget, self).__init__(parent) self.background_pixmap = QPixmap(':/images/First_use_Background.png') self.mantid_pixmap = QPixmap(':/images/mantid_smaller.png') self.lbl_version = QLabel() self.clb_release_notes = QCommandLinkButton() self.clb_sample_datasets = QCommandLinkButton() self.clb_mantid_introduction = QCommandLinkButton() self.clb_python_introduction = QCommandLinkButton() self.clb_python_in_mantid = QCommandLinkButton() self.clb_extending_mantid = QCommandLinkButton() self.cb_facility = QComboBox() self.cb_instrument = instrumentselector.InstrumentSelector() self.pb_manage_user_directories = QPushButton() self.chk_allow_usage_data = QCheckBox() self.lbl_privacy_policy = QLabel() self.chk_do_not_show_until_next_release = QCheckBox() self.pb_close = QPushButton() self.is_widget_too_big = False self.setupUI() self.customize_layout(version_text, date_text) def paintEvent(self, event): scaled_background = self.background_pixmap.scaled(self.rescale_w(self.background_pixmap.width()), self.rescale_h(self.background_pixmap.height()), Qt.KeepAspectRatio, Qt.SmoothTransformation) scaled_mantid = self.mantid_pixmap.scaled(self.rescale_w(self.mantid_pixmap.width()), self.rescale_h(self.mantid_pixmap.height()), Qt.KeepAspectRatio, Qt.SmoothTransformation) qp = QPainter() qp.begin(self) qp.drawPixmap(0, 0, scaled_background) qp.drawPixmap(self.width() - scaled_mantid.width(), self.height() - scaled_mantid.height(), scaled_mantid) qp.end() def determine_dialog_dimensions(self): width = REFERENCE_WIDTH height = REFERENCE_HEIGHT screen = None try: if hasattr(QGuiApplication, "screenAt"): screen = QGuiApplication.screenAt(self.parent().parent().geometry().center()) else: # get the screen from the last top level window windows = QGuiApplication.topLevelWindows() screen = windows[-1].screen() except Exception: # something failed just take the primary screen screen = QGuiApplication.primaryScreen() if screen is not None: screen_width = screen.availableSize().width() screen_height = screen.availableSize().height() # the proportion of the whole window size for the about screen window_scaling = 0.4 width = int(screen_width * window_scaling) # also calculate the intended width but using the hieght and a standard screen aspect ratio width_by_height = int(screen_height * WIDESCREEN_ASPECT_RATIO * window_scaling) # take the smaller of the width from the screen width and height if width_by_height < width: width = width_by_height # set a minimum size if width < REFERENCE_WIDTH: width = REFERENCE_WIDTH # calculate height from the width and aspect ratio height = int(width / REFERENCE_ASPECT_RATIO) if width > screen_width or height > screen_height: self.is_widget_too_big = True return width, height def rescale_w(self, value): return int(value * (self.width() / REFERENCE_WIDTH)) def rescale_h(self, value): return int(value * (self.height() / REFERENCE_HEIGHT)) def setupUI(self): width, height = self.determine_dialog_dimensions() self.setFixedSize(width, height) self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.setWindowTitle("About Mantid Workbench") self.setStyleSheet(f"""QDialog {{ background-color: rgb(190, 230, 190); }} QLabel{{ font: {self.rescale_w(14)}px; }} QPushButton{{ font: {self.rescale_w(14)}px; }} QCommandLinkButton{{ font: {self.rescale_w(22)}px; background-color: rgba(255, 255, 255, 0); border-radius: {self.rescale_w(15)}px; }} QCommandLinkButton:hover {{ background-color: rgba(45, 105, 45, 40); }}""") # version label section at th etop parent_layout = QVBoxLayout() parent_layout.addSpacerItem(QSpacerItem(self.rescale_w(20), self.rescale_h(70), vPolicy=QSizePolicy.Fixed)) self.lbl_version.setText("version ") self.lbl_version.setIndent(self.rescale_w(115)) self.lbl_version.setStyleSheet(f"""color: rgb(215, 215, 215); font: {self.rescale_w(28)}pt; font-weight: bold; font-size: {self.rescale_w(28)}px""") parent_layout.addWidget(self.lbl_version) parent_layout.addSpacerItem(QSpacerItem(self.rescale_w(20), self.rescale_h(40), vPolicy=QSizePolicy.MinimumExpanding)) # split into the two columns two_box_layout = QHBoxLayout() # left side Welcome and Tutorial left_layout = QVBoxLayout() left_layout.setContentsMargins(self.rescale_w(5), 0, self.rescale_w(10), 0) left_layout.setSpacing(0) # welcome label lbl_welcome = QLabel() lbl_welcome.setStyleSheet(f"color: rgb(45, 105, 45); font-size: {self.rescale_w(28)}px;") lbl_welcome.setText("Welcome") left_layout.addWidget(lbl_welcome) # release notes self.setup_command_link_button(self.clb_release_notes, "Release Notes", ':/images/Notepad-Bloc-notes-icon-48x48.png') left_layout.addWidget(self.clb_release_notes) # sample datasets self.setup_command_link_button(self.clb_sample_datasets, "Sample Datasets", ':/images/download-icon-48x48.png') left_layout.addWidget(self.clb_sample_datasets) # Tutorials Label lbl_tutorials = QLabel() lbl_tutorials.setStyleSheet(f"color: rgb(45, 105, 45); font-size: {self.rescale_w(28)}px;") lbl_tutorials.setText("Tutorials") left_layout.addWidget(lbl_tutorials) # Mantid Introduction self.setup_command_link_button(self.clb_mantid_introduction, "Mantid Introduction", ':/images/Misc-Tutorial-icon-48x48.png') left_layout.addWidget(self.clb_mantid_introduction) # Introduction to python self.setup_command_link_button(self.clb_python_introduction, "Introduction to Python", ':/images/Python-icon-48x48.png') left_layout.addWidget(self.clb_python_introduction) # Python in Mantid self.setup_command_link_button(self.clb_python_in_mantid, "Python In Mantid", ':/images/Circle_cog_48x48.png') left_layout.addWidget(self.clb_python_in_mantid) # Extending Mantid with python self.setup_command_link_button(self.clb_extending_mantid, "Extending Mantid with Python", ':/images/Plugin-Python-icon-48x48.png') left_layout.addWidget(self.clb_extending_mantid) # right hand side Setup and facility icons right_layout = QVBoxLayout() right_layout.setSpacing(0) # personal setup grp_personal_setup = QGroupBox() grp_personal_setup.setStyleSheet(f"""QGroupBox {{ border: {self.rescale_w(3)}px solid rgb(38, 128, 20);; border-radius: {self.rescale_w(10)}px; background-color: rgb(240, 240, 240); }} QGroupBox QLabel{{ font: {self.rescale_w(12)}px; color: rgb(121, 121, 121); }} QGroupBox QComboBox{{ font: {self.rescale_w(12)}px; }} font: {self.rescale_w(12)}px; """) grp_personal_setup_layout = QVBoxLayout() grp_personal_setup_layout.setContentsMargins(self.rescale_w(9), self.rescale_h(1), self.rescale_w(9), self.rescale_h(9)) grp_personal_setup_layout.setSpacing(0) grp_personal_setup.setLayout(grp_personal_setup_layout) lbl_personal_setup = QLabel() lbl_personal_setup.setStyleSheet(f"color: rgb(38, 128, 20);\nfont-size: {self.rescale_w(18)}px;") lbl_personal_setup.setText("Personal Setup") lbl_personal_setup.setAlignment(Qt.AlignHCenter) grp_personal_setup_layout.addWidget(lbl_personal_setup) personal_setup_form_layout = QFormLayout() personal_setup_form_layout.setFieldGrowthPolicy(QFormLayout.AllNonFixedFieldsGrow) personal_setup_form_layout.setHorizontalSpacing(self.rescale_w(5)) personal_setup_form_layout.setVerticalSpacing(self.rescale_h(5)) personal_setup_form_layout.setLabelAlignment(Qt.AlignRight) # default Facility lbl_default_facilty = QLabel() lbl_default_facilty.setText("Default Facility") personal_setup_form_layout.addRow(lbl_default_facilty, self.cb_facility) # default instrument lbl_default_instrument = QLabel() lbl_default_instrument.setText("Default Instrument") personal_setup_form_layout.addRow(lbl_default_instrument, self.cb_instrument) # Set Data Directories lbl_mud = QLabel() lbl_mud.setText("Set data directories") self.pb_manage_user_directories.setText("Manage User Directories") personal_setup_form_layout.addRow(lbl_mud, self.pb_manage_user_directories) # Usage data lbl_allow_usage_data = QLabel() lbl_allow_usage_data.setText("Report Usage Data") usagelayout = QHBoxLayout() usagelayout.setContentsMargins(0, 0, 0, 0) self.chk_allow_usage_data.setChecked(True) self.chk_allow_usage_data.setStyleSheet(f"padding: {self.rescale_w(4)}px;") usagelayout.addWidget(self.chk_allow_usage_data) usagelayout.addSpacerItem(QSpacerItem(self.rescale_w(40), self.rescale_h(20), hPolicy=QSizePolicy.Expanding)) self.lbl_privacy_policy.setText(r'<html><head/><body><p>' r'<a href="https://www.mantidproject.org/MantidProject:Privacy_policy' r'#Usage_Data_recorded_in_Mantid">' r'<span style=" text-decoration: underline; color:#0000ff;">' r'Privacy Policy</span></a></p></body></html>') self.lbl_privacy_policy.setOpenExternalLinks(False) usagelayout.addWidget(self.lbl_privacy_policy) personal_setup_form_layout.addRow(lbl_allow_usage_data, usagelayout) grp_personal_setup_layout.addLayout(personal_setup_form_layout) right_layout.addWidget(grp_personal_setup) right_layout.addSpacerItem(QSpacerItem(self.rescale_w(20), self.rescale_h(40), vPolicy=QSizePolicy.Expanding)) # facility icons # Row one icon_layout_top = QHBoxLayout() icon_layout_top.setContentsMargins(0, self.rescale_h(10), 0, 0) icon_layout_top.setSpacing(0) icon_layout_top.addWidget(self.create_label_with_image(112, 60, ':/images/ISIS_Logo_Transparent_UKRI.png')) icon_layout_top.addSpacerItem(QSpacerItem(self.rescale_w(10), self.rescale_h(20), hPolicy=QSizePolicy.Fixed)) icon_layout_top.addWidget(self.create_label_with_image(94, 50, ':/images/ess_logo_transparent_small.png')) icon_layout_top.addSpacerItem(QSpacerItem(self.rescale_w(40), 20, hPolicy=QSizePolicy.Expanding)) right_layout.addLayout(icon_layout_top) # Row two icon_layout_middle = QHBoxLayout() icon_layout_middle.setContentsMargins(0, self.rescale_h(10), 0, 0) icon_layout_middle.setSpacing(0) icon_layout_middle.addWidget(self.create_label_with_image(200, 30, ':/images/Ornl_hfir_sns_logo_small.png')) icon_layout_middle.addSpacerItem(QSpacerItem(self.rescale_w(40), self.rescale_h(20), hPolicy=QSizePolicy.Expanding)) right_layout.addLayout(icon_layout_middle) # Row three icon_layout_bottom = QHBoxLayout() icon_layout_bottom.setContentsMargins(0, self.rescale_h(10), 0, 0) icon_layout_bottom.setSpacing(0) icon_layout_bottom.addWidget(self.create_label_with_image(110, 40, ':/images/Tessella_Logo_Transparent.gif')) icon_layout_bottom.addSpacerItem(QSpacerItem(self.rescale_w(10), self.rescale_h(20), hPolicy=QSizePolicy.Fixed)) icon_layout_bottom.addWidget(self.create_label_with_image(50, 50, ':/images/ILL_logo.png')) icon_layout_bottom.addSpacerItem(QSpacerItem(self.rescale_w(10), self.rescale_h(20), hPolicy=QSizePolicy.Fixed)) icon_layout_bottom.addWidget(self.create_label_with_image(92, 50, ':/images/CSNS_Logo_Short.png')) icon_layout_bottom.addSpacerItem(QSpacerItem(self.rescale_w(40), self.rescale_h(20), hPolicy=QSizePolicy.Expanding)) right_layout.addLayout(icon_layout_bottom) # end the two box layout two_box_layout.addLayout(left_layout) two_box_layout.addLayout(right_layout) parent_layout.addLayout(two_box_layout) # footer footer_layout = QHBoxLayout() # do not show again do_not_show_layout = QVBoxLayout() do_not_show_layout.setContentsMargins(self.rescale_w(15), 0, 0, 0) do_not_show_layout.setSpacing(self.rescale_w(2)) do_not_show_layout.addSpacerItem(QSpacerItem(1, self.rescale_h(1), vPolicy=QSizePolicy.Expanding)) lbl_update = QLabel() lbl_update.setMinimumSize(self.rescale_w(400), 0) lbl_update.setStyleSheet("color: rgb(25,125,25);") lbl_update.setText('You can revisit this dialog by selecting "About" on the Help menu.') lbl_update.setAlignment(Qt.AlignBottom) do_not_show_layout.addWidget(lbl_update) do_not_show_checkbox_layout = QHBoxLayout() self.chk_do_not_show_until_next_release.setChecked(True) do_not_show_checkbox_layout.addWidget(self.chk_do_not_show_until_next_release) do_not_show_checkbox_layout.addSpacerItem(QSpacerItem(self.rescale_w(10), self.rescale_h(2), hPolicy=QSizePolicy.Fixed)) lbl_do_not_show = QLabel() lbl_do_not_show.setStyleSheet("color: rgb(25,125,25);") lbl_do_not_show.setText('Do not show again until next release') do_not_show_checkbox_layout.addWidget(lbl_do_not_show) do_not_show_checkbox_layout.addSpacerItem(QSpacerItem(self.rescale_w(40), 10, hPolicy=QSizePolicy.Expanding)) do_not_show_layout.addLayout(do_not_show_checkbox_layout) footer_layout.addLayout(do_not_show_layout) # Close button close_button_layout = QVBoxLayout() close_button_layout.addSpacerItem(QSpacerItem(20, self.rescale_h(15), vPolicy=QSizePolicy.Expanding)) self.pb_close.setText("Close") self.pb_close.setDefault(True) close_button_layout.addWidget(self.pb_close) footer_layout.addLayout(close_button_layout) footer_layout.addSpacerItem(QSpacerItem(self.rescale_w(100), self.rescale_h(20), hPolicy=QSizePolicy.Fixed)) parent_layout.addLayout(footer_layout) self.setLayout(parent_layout) self.setAttribute(Qt.WA_DeleteOnClose, True) def setup_command_link_button(self, link_button, text, image_location, width=40, height=40): link_button.setText(text) link_button.setIconSize(QSize(self.rescale_w(width), self.rescale_h(height))) link_button.setIcon(QIcon(QPixmap(image_location))) return link_button def create_label_with_image(self, width, height, image_location): label_with_image = QLabel() label_with_image.setMinimumSize(self.rescale_w(width), self.rescale_h(height)) label_with_image.setMaximumSize(self.rescale_w(width), self.rescale_h(height)) label_with_image.setPixmap(QPixmap(image_location)) label_with_image.setScaledContents(True) return label_with_image def customize_layout(self, version_text, date_text): self.setWindowTitle(self.windowTitle() + " " + version_text) version_label = version_text # add a date if it is an official release if date_text and len(version_text) < 10: # strip off the first few characters that will be "day, " version_label += " ({0})".format(date_text[5:]) self.lbl_version.setText(self.lbl_version.text() + version_label)
class ImportWizard(BaseDialog): """Text data import wizard""" def __init__(self, parent, text, title=None, icon=None, contents_title=None, varname=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) if title is None: title = _("Import wizard") self.setWindowTitle(title) if icon is None: self.setWindowIcon(ima.icon('fileimport')) if contents_title is None: contents_title = _("Raw text") if varname is None: varname = _("variable_name") self.var_name, self.clip_data = None, None # Setting GUI self.tab_widget = QTabWidget(self) self.text_widget = ContentsWidget(self, text) self.table_widget = PreviewWidget(self) self.tab_widget.addTab(self.text_widget, _("text")) self.tab_widget.setTabText(0, contents_title) self.tab_widget.addTab(self.table_widget, _("table")) self.tab_widget.setTabText(1, _("Preview")) self.tab_widget.setTabEnabled(1, False) name_layout = QHBoxLayout() name_label = QLabel(_("Variable Name")) name_layout.addWidget(name_label) self.name_edt = QLineEdit() self.name_edt.setText(varname) name_layout.addWidget(self.name_edt) btns_layout = QHBoxLayout() cancel_btn = QPushButton(_("Cancel")) btns_layout.addWidget(cancel_btn) cancel_btn.clicked.connect(self.reject) h_spacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) btns_layout.addItem(h_spacer) self.back_btn = QPushButton(_("Previous")) self.back_btn.setEnabled(False) btns_layout.addWidget(self.back_btn) self.back_btn.clicked.connect(ft_partial(self._set_step, step=-1)) self.fwd_btn = QPushButton(_("Next")) if not text: self.fwd_btn.setEnabled(False) btns_layout.addWidget(self.fwd_btn) self.fwd_btn.clicked.connect(ft_partial(self._set_step, step=1)) self.done_btn = QPushButton(_("Done")) self.done_btn.setEnabled(False) btns_layout.addWidget(self.done_btn) self.done_btn.clicked.connect(self.process) self.text_widget.asDataChanged.connect(self.fwd_btn.setEnabled) self.text_widget.asDataChanged.connect(self.done_btn.setDisabled) layout = QVBoxLayout() layout.addLayout(name_layout) layout.addWidget(self.tab_widget) layout.addLayout(btns_layout) self.setLayout(layout) def _focus_tab(self, tab_idx): """Change tab focus""" for i in range(self.tab_widget.count()): self.tab_widget.setTabEnabled(i, False) self.tab_widget.setTabEnabled(tab_idx, True) self.tab_widget.setCurrentIndex(tab_idx) def _set_step(self, step): """Proceed to a given step""" new_tab = self.tab_widget.currentIndex() + step assert new_tab < self.tab_widget.count() and new_tab >= 0 if new_tab == self.tab_widget.count() - 1: try: self.table_widget.open_data( self._get_plain_text(), self.text_widget.get_col_sep(), self.text_widget.get_row_sep(), self.text_widget.trnsp_box.isChecked(), self.text_widget.get_skiprows(), self.text_widget.get_comments()) self.done_btn.setEnabled(True) self.done_btn.setDefault(True) self.fwd_btn.setEnabled(False) self.back_btn.setEnabled(True) except (SyntaxError, AssertionError) as error: QMessageBox.critical( self, _("Import wizard"), _("<b>Unable to proceed to next step</b>" "<br><br>Please check your entries." "<br><br>Error message:<br>%s") % str(error)) return elif new_tab == 0: self.done_btn.setEnabled(False) self.fwd_btn.setEnabled(True) self.back_btn.setEnabled(False) self._focus_tab(new_tab) def get_data(self): """Return processed data""" # It is import to avoid accessing Qt C++ object as it has probably # already been destroyed, due to the Qt.WA_DeleteOnClose attribute return self.var_name, self.clip_data def _simplify_shape(self, alist, rec=0): """Reduce the alist dimension if needed""" if rec != 0: if len(alist) == 1: return alist[-1] return alist if len(alist) == 1: return self._simplify_shape(alist[-1], 1) return [self._simplify_shape(al, 1) for al in alist] def _get_table_data(self): """Return clipboard processed as data""" data = self._simplify_shape(self.table_widget.get_data()) if self.table_widget.array_btn.isChecked(): return array(data) elif pd and self.table_widget.df_btn.isChecked(): info = self.table_widget.pd_info buf = io.StringIO(self.table_widget.pd_text) return pd.read_csv(buf, **info) return data def _get_plain_text(self): """Return clipboard as text""" return self.text_widget.text_editor.toPlainText() @Slot() def process(self): """Process the data from clipboard""" var_name = self.name_edt.text() try: self.var_name = str(var_name) except UnicodeEncodeError: self.var_name = to_text_string(var_name) if self.text_widget.get_as_data(): self.clip_data = self._get_table_data() elif self.text_widget.get_as_code(): self.clip_data = try_to_eval(to_text_string( self._get_plain_text())) else: self.clip_data = to_text_string(self._get_plain_text()) self.accept()
def _init_ui(self): # Line 1: Color map self.colormap_label = QLabel("Color Scheme: ") self.colormap_combo = QColormapCombo() self.colormap_combo.addItem("", userData=cm.viridis) self.colormap_combo._update_icons() self.colormap_combo.setCurrentIndex(self._colormap_index) self.colormap_combo.setMaximumWidth(150) self.colormap_combo.currentIndexChanged.connect( self._on_colormap_change) # hbl is short for Horizontal Box Layout hbl1 = QHBoxLayout() hbl1.addWidget(self.colormap_label) hbl1.addWidget(self.colormap_combo) # Line 2: Display contour labels self.contour_label_checkBox = QCheckBox("Contour labels (font size):") if self.contour_settings.add_contour_label: self.contour_label_checkBox.setChecked(True) self.contour_label_checkBox.toggled.connect(self.toggle_labels) font_string = str(self.contour_settings.font_size) self.font_size_input = QLineEdit(font_string) self.font_size_input.setFixedWidth(150) self.font_size_input.setDisabled( not self.contour_settings.add_contour_label) hbl2 = QHBoxLayout() hbl2.addWidget(self.contour_label_checkBox) hbl2.addWidget(self.font_size_input) # Line 3: Contour Spacing self.custom_spacing_checkBox = QCheckBox("Contour spacing (interval):") if self.is_custom_spacing: self.custom_spacing_checkBox.setChecked(True) self.custom_spacing_checkBox.toggled.connect(self.custom_spacing) self.spacing_input = QLineEdit() self.spacing_input.setFixedWidth(150) self.spacing_input.setDisabled(not self.is_custom_spacing) spacing = "" if self.is_custom_spacing: spacing = str(self.contour_settings.spacing) elif self.contour_settings.data_spacing is not None: spacing = self.contour_settings.data_spacing spacing = "{0:1.4f}".format(spacing) self.spacing_default_text = spacing self.spacing_input.setText(spacing) hbl3 = QHBoxLayout() hbl3.addWidget(self.custom_spacing_checkBox) hbl3.addWidget(self.spacing_input) # Line 4: Vmax self.vmax_checkBox = QCheckBox("Set max:") self.vmax_input = QLineEdit() self.vmax_input.setFixedWidth(150) self.vmax_input.setDisabled(not self.is_vmax) vmax = "" if self.is_vmax: self.vmax_checkBox.setChecked(True) vmax = str(self.contour_settings.vmax) elif self.contour_settings.data_max is not None: vmax = self.contour_settings.data_max vmax = "{0:1.4f}".format(vmax) self.vmax_input.setText(vmax) self.vmax_default_text = vmax self.vmax_checkBox.toggled.connect(self.toggle_vmax) hbl4 = QHBoxLayout() hbl4.addWidget(self.vmax_checkBox) hbl4.addWidget(self.vmax_input) # Line 5: Vmin self.vmin_checkBox = QCheckBox("Set min:") self.vmin_input = QLineEdit() self.vmin_input.setFixedWidth(150) self.vmin_input.setDisabled(not self.is_vmin) vmin = "" if self.is_vmin: self.vmin_checkBox.setChecked(True) vmin = str(self.contour_settings.vmin) elif self.contour_settings.data_min is not None: vmin = self.contour_settings.data_min vmin = "{0:1.4f}".format(vmin) self.vmin_input.setText(vmin) self.vmin_default_text = vmin self.vmin_checkBox.toggled.connect(self.toggle_vmin) hbl5 = QHBoxLayout() hbl5.addWidget(self.vmin_checkBox) hbl5.addWidget(self.vmin_input) # Line f: self.previewButton = QPushButton("Preview") self.previewButton.clicked.connect(self.preview) self.defaultButton = QPushButton("Reset") self.defaultButton.clicked.connect(self.default) self.okButton = QPushButton("OK") self.okButton.clicked.connect(self.finish) self.okButton.setDefault(True) self.cancelButton = QPushButton("Cancel") self.cancelButton.clicked.connect(self.cancel) hblf = QHBoxLayout() hblf.addStretch(1) hblf.addWidget(self.previewButton) hblf.addWidget(self.defaultButton) hblf.addWidget(self.cancelButton) hblf.addWidget(self.okButton) vbl = QVBoxLayout() vbl.addLayout(hbl1) vbl.addLayout(hbl2) vbl.addLayout(hbl3) vbl.addLayout(hbl4) vbl.addLayout(hbl5) vbl.addLayout(hblf) self.setLayout(vbl) self.show()
class GcodeBackplot(QBackPlot): line_selected = Signal(int) gcode_error = Signal(str) def __init__(self, parent=None, standalone=False): super(GcodeBackplot, self).__init__(parent) # This prevents doing unneeded initialization # when QtDesginer loads the plugin. if parent is None and not standalone: return self.show_overlay = False # no DRO or DRO overlay self.program_alpha = True self.grid_size = 1 self._reload_filename = None # Add loading progress bar and abort button self.progressBar = QProgressBar(visible=False) self.progressBar.setFormat("Loading backplot: %p%") self.abortButton = QPushButton('Abort', visible=False) hBox = QHBoxLayout() hBox.addWidget(self.progressBar) hBox.addWidget(self.abortButton) vBox = QVBoxLayout(self) vBox.addStretch() vBox.addLayout(hBox) self.abortButton.clicked.connect(self.abort) STATUS.actual_position.onValueChanged(self.update) STATUS.joint_actual_position.onValueChanged(self.update) STATUS.homed.onValueChanged(self.update) STATUS.limit.onValueChanged(self.update) STATUS.tool_in_spindle.onValueChanged(self.update) STATUS.motion_mode.onValueChanged(self.update) STATUS.current_vel.onValueChanged(self.update) STATUS.g5x_offset.onValueChanged(self.reloadBackplot) STATUS.g92_offset.onValueChanged(self.reloadBackplot) # Connect status signals STATUS.file.notify(self.loadBackplot) # STATUS.reload_backplot.notify(self.reloadBackplot) STATUS.program_units.notify(lambda v: self.setMetricUnits(v == 2)) def loadBackplot(self, fname): LOG.debug('load the display: {}'.format(fname.encode('utf-8'))) self._reload_filename = fname self.load(fname) @Slot() def reloadBackplot(self): QTimer.singleShot(100, lambda: self._reloadBackplot()) def _reloadBackplot(self): LOG.debug('reload the display: {}'.format(self._reload_filename)) dist = self.get_zoom_distance() try: self.load(self._reload_filename) self.set_zoom_distance(dist) except: LOG.warning("Problem reloading backplot file: {}".format( self._reload_filename), exc_info=True) # ========================================================================== # Override QBackPlot methods # ========================================================================== def report_loading_started(self): self.progressBar.show() self.abortButton.show() self.start = time.time() def report_progress_percentage(self, percentage): QApplication.processEvents() self.progressBar.setValue(percentage) def report_loading_finished(self): print time.time() - self.start self.progressBar.hide() self.abortButton.hide() # overriding functions def report_gcode_error(self, result, seq, filename): error = gcode.strerror(result) file = os.path.basename(filename) line = seq - 1 msg = "G-code error in '{}' near line {}: {}".format(file, line, error) LOG.error(msg) STATUS.backplot_gcode_error.emit(msg) # Override gremlin's / glcannon.py function so we can emit a GObject signal def update_highlight_variable(self, line): self.highlight_line = line if line is None: line = -1 STATUS.backplot_line_selected.emit(line) # ============================================================================== # QtDesigner property setters/getters # ============================================================================== @Slot(str) def setView(self, view): view = view.lower() if self.is_lathe: if view not in ['p', 'y', 'y2']: return False elif view not in ['p', 'x', 'y', 'z', 'z2']: return False self.current_view = view if self.initialised: self.set_current_view() def getView(self): return self.current_view defaultView = Property(str, getView, setView) @Slot() def setViewP(self): self.setView('p') @Slot() def setViewX(self): self.setView('x') @Slot() def setViewY(self): self.setView('y') @Slot() def setViewZ(self): self.setView('z') @Slot() def setViewZ2(self): self.setView('z2') @Slot() def clearLivePlot(self): self.clear_live_plotter() @Slot() def zoomIn(self): self.zoomin() @Slot() def zoomOut(self): self.zoomout() @Slot(bool) def alphaBlend(self, alpha): self.program_alpha = alpha self.update() @Slot(bool) def showGrid(self, grid): self.grid_size = int(grid) # ugly hack for now self.update() # @Slot(str) Fixme check for the correct data type def setdro(self, state): self.enable_dro = state self.updateGL() def getdro(self): return self.enable_dro _dro = Property(bool, getdro, setdro) # DTG # @Slot(str) Fixme check for the correct data type def setdtg(self, state): self.show_dtg = state self.updateGL() def getdtg(self): return self.show_dtg _dtg = Property(bool, getdtg, setdtg) # METRIC # @Slot(str) Fixme check for the correct data type def setMetricUnits(self, metric): self.metric_units = metric self.updateGL() def getMetricUnits(self): return self.metric_units metricUnits = Property(bool, getMetricUnits, setMetricUnits) # @Slot(str) Fixme check for the correct data type def setProgramAlpha(self, alpha): self.program_alpha = alpha self.updateGL() def getProgramAlpha(self): return self.program_alpha renderProgramAlpha = Property(bool, getProgramAlpha, setProgramAlpha) # @Slot(str) Fixme check for the correct data type def setBackgroundColor(self, color): self.colors['back'] = color.getRgbF()[:3] self.updateGL() def getBackgroundColor(self): r, g, b = self.colors['back'] color = QColor() color.setRgbF(r, g, b, 1.0) return color backgroundColor = Property(QColor, getBackgroundColor, setBackgroundColor)
def __init__(self, data, win_parent=None): """ +-----------------+ | Break Surfaces | +-----------------+------+ | EngineInlet | | EngineOutlet | | | | Name EngineInlet | | RegionMode * RegionID | | * All | | | | AllowedRegions: | | Region ID 3 | | | | PickMode * All | | Pick Mode x On/Off | | Pick Angle 20 deg | | | | Revert | | RenumberRegions | | Close | +------------------------+ """ QDialog.__init__(self, win_parent) self.setWindowTitle('Break Surface') #default self.win_parent = win_parent self.out_data = data self.points = data['points'] self.keys = sorted(self.points.keys()) keys = self.keys nrows = len(keys) active_point = data['active_point'] #self.active_key = keys[0] self.active_key = active_point name = self.active_key description = self.points[self.active_key][0] self._use_old_table = False items = ['Node %i' % val for val in keys] header_labels = ['Nodes'] table_model = Model(items, header_labels, self) view = SingleChoiceQTableView(self) #Call your custom QTableView here view.setModel(table_model) header = view.horizontalHeader() header.setSectionResizeMode(0, QHeaderView.Stretch) #header.setResizeMode(QtGui.QHeaderView.Stretch) self.table = view #self.representation = actor_obj.representation #print('rep =', self.representation) table = self.table #headers = [QtCore.QString('Groups')] header = table.horizontalHeader() header.setStretchLastSection(True) #---------------------------------------------- #self._default_is_apply = False self.mode_header = QLabel("Mode:") nregions_max = 10 pick_angle = 20.0 region_id = 4 all_regions = True self.region_id = QLabel("Region ID:") self.region_id_edit = QSpinBox(self) self.region_id_edit.setRange(1, nregions_max) self.region_id_edit.setSingleStep(1) self.region_id_edit.setValue(region_id) self.pick_angle = QLabel("Pick Angle:") self.pick_angle_edit = QDoubleSpinBox(self) self.pick_angle_edit.setRange(0.0, 360.0) self.pick_angle_edit.setDecimals(3) self.pick_angle_edit.setSingleStep(0.5) self.pick_angle_edit.setValue(pick_angle) # region IDs/all self.checkbox_region_ids = QCheckBox("Region IDs") self.checkbox_region_all = QCheckBox("All Regions") self.checkbox_region_all.setChecked(all_regions) self.checkbox_region_ids.setChecked(not all_regions) # pick mode self.checkbox_pick_mode = QCheckBox("Pick Mode (Off=label)") self.checkbox_pick_mode.setChecked(False) #---------------------------------------------- self.nodes_header = QLabel("Single Node:") self.name = QLabel("ID:") self.name_edit = QLineEdit('Node %i' % name) self.name_edit.setDisabled(True) #---------------------------------------------- self.location_x = QLabel("X:") self.location_x_edit = QLineEdit('X') self.location_y = QLabel("Y:") self.location_y_edit = QLineEdit('Y') self.location_z = QLabel("Z:") self.location_z_edit = QLineEdit('Z') #---------------------------------------------- # remove these... self.description_edit = QLineEdit('Description') self.coord_edit = QSpinBox() #---------------------------------------------- # closing #if self._default_is_apply: #self.apply_button.setDisabled(True) self.close_button = QPushButton("Close") self.create_layout()
class PayloadWindow(FramelessWindow): get_build_options = Signal() start_build = Signal(str, str, list) stop_build = Signal() def __init__(self, parent): super(PayloadWindow, self).__init__(parent) self.logger = logging.getLogger(self.__class__.__name__) self.setContentsMargins(11, 11, 11, 11) self.progress_windows = [] self.content_widget = QWidget(self) self.addContentWidget(self.content_widget) self.widget_layout = QFormLayout(self.content_widget) self.content_widget.setLayout(self.widget_layout) self.spinner = WaitingSpinner(self, modality=Qt.WindowModal, roundness=70.0, fade=70.0, radius=15.0, lines=6, line_length=25.0, line_width=4.0, speed=1.0) self.build_name_label = QLabel("Name", self.content_widget) self.build_name_edit = QLineEdit(self.content_widget) self.widget_layout.addRow(self.build_name_label, self.build_name_edit) self.icon_label = QLabel("Icon", self.content_widget) self.icon_combobox = QComboBox(self.content_widget) self.widget_layout.addRow(self.icon_label, self.icon_combobox) self.generators_label = QLabel("Generators", self.content_widget) self.generators_list = QListWidget(self.content_widget) self.widget_layout.addRow(self.generators_label, self.generators_list) self.build_button = QPushButton("Build", self.content_widget) self.build_button.clicked.connect(self.on_build_button_clicked) self.widget_layout.addWidget(self.build_button) self.menu = QMenu(self) self.menu.setTitle("Payload") self.reload_action = QAction(self.menu) self.reload_action.setText("Reload options") self.reload_action.triggered.connect(self.setupUi) self.menu.addAction(self.reload_action) self.addMenu(self.menu) @Slot() def setupUi(self): self.spinner.start() self.get_build_options.emit() @Slot(dict) def process_build_message(self, message): if self.isVisible(): event = message.get("event") if event == "options": options = message.get("options") self.set_options(options.get("generators"), options.get("icons")) elif event == "started": self.set_started(message.get("generator_name")) elif event == "stopped": self.set_stopped() elif event == "progress": self.set_progress(message.get("generator_name"), message.get("progress")) elif event == "error": self.set_error(message.get("error")) elif event == "generator_finished": self.set_generator_finished(message.get("generator_name"), message.get("exit_code")) elif event == "build_finished": self.set_build_finished() @Slot(str, str) def set_progress(self, generator_name, progress): for win in self.progress_windows: if win.generator() == generator_name: win.appendProgress(progress) @Slot(str) def set_started(self, generator_name): win = ProgressWindow(self, generator_name) win.show() self.progress_windows.append(win) self.logger.info("Generator {} started!".format(generator_name)) self.reload_action.setEnabled(False) self.spinner.start() @Slot(str, int) def set_generator_finished(self, generator_name, exit_code): self.logger.info("Generator {} finished with exit code {}.".format( generator_name, exit_code)) @Slot(list, list) def set_options(self, generators, icons): self.build_name_edit.clear() self.generators_list.clear() self.icon_combobox.clear() for generator in generators: item = QListWidgetItem(generator, self.generators_list) item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable) item.setCheckState(Qt.Checked) self.generators_list.addItem(item) for icon in icons: name = icon.get("name") pix = QPixmap() pix.loadFromData(base64.b64decode(icon.get("ico"))) ico = QIcon() ico.addPixmap(pix) self.icon_combobox.addItem(ico, name) self.spinner.stop() @Slot() def set_stopped(self): self.on_build_finished() self.build_button.setText("Build") self.stopped_messagebox = FramelessInformationMessageBox(self) self.stopped_messagebox.setText( "Build process has been stopped successfully.") self.stopped_messagebox.setStandardButtons(QDialogButtonBox.Ok) self.stopped_messagebox.button(QDialogButtonBox.Ok).clicked.connect( self.stopped_messagebox.close) self.stopped_messagebox.show() @Slot(str) def set_error(self, error): self.on_build_finished() self.build_button.setText("Build") self.error_messagebox = FramelessCriticalMessageBox(self) self.error_messagebox.setText(error) self.error_messagebox.setStandardButtons(QDialogButtonBox.Ok) self.error_messagebox.button(QDialogButtonBox.Ok).clicked.connect( self.error_messagebox.close) self.error_messagebox.show() @Slot() def set_build_finished(self): self.on_build_finished() self.build_button.setText("Build") self.build_finished_messagebox = FramelessInformationMessageBox(self) self.build_finished_messagebox.setText( "Build process has been finished.") self.build_finished_messagebox.setStandardButtons(QDialogButtonBox.Ok) self.build_finished_messagebox.button( QDialogButtonBox.Ok).clicked.connect( self.build_finished_messagebox.close) self.build_finished_messagebox.show() @Slot() def on_build_button_clicked(self): if self.build_button.text() == "Build": generators = [] for i in range(self.generators_list.count()): item = self.generators_list.item(i) if item.checkState() == Qt.Checked: generators.append(item.text()) self.start_build.emit(self.build_name_edit.text(), self.icon_combobox.currentText(), generators) self.build_button.setText("Stop") else: self.stop_build_messagebox = FramelessQuestionMessageBox(self) self.stop_build_messagebox.setText( "Do you want to stop build process?") self.stop_build_messagebox.setStandardButtons( QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.stop_build_messagebox.button( QDialogButtonBox.Cancel).clicked.connect( self.stop_build_messagebox.close) self.stop_build_messagebox.button( QDialogButtonBox.Ok).clicked.connect(self.stop_build.emit) self.stop_build_messagebox.button( QDialogButtonBox.Ok).clicked.connect( self.stop_build_messagebox.close) self.stop_build_messagebox.show() @Slot() def on_build_finished(self): self.reload_action.setEnabled(True) self.spinner.stop() @Slot() def close(self) -> bool: for win in self.progress_windows: win.close() return super().close()
def create_widgets(self, show_animation_button=True): """creates the menu objects""" # title self.title_label = QLabel("Title:") self.title_edit = QLineEdit(str(self._default_title)) self.title_button = QPushButton("Default") # Min self.min_label = QLabel("Min:") self.min_edit = QLineEdit(str(self._default_min)) self.min_button = QPushButton("Default") # Max self.max_label = QLabel("Max:") self.max_edit = QLineEdit(str(self._default_max)) self.max_button = QPushButton("Default") #--------------------------------------- # Format self.format_label = QLabel("Format (e.g. %.3f, %g, %.6e):") self.format_edit = QLineEdit(str(self._format)) self.format_button = QPushButton("Default") #--------------------------------------- # Scale self.scale_label = QLabel("True Scale:") self.scale_edit = QLineEdit(str(self._scale)) self.scale_button = QPushButton("Default") if self._icase_disp is None: self.scale_label.setVisible(False) self.scale_edit.setVisible(False) self.scale_button.setVisible(False) # Phase self.phase_label = QLabel("Phase (deg):") self.phase_edit = QLineEdit(str(self._phase)) self.phase_button = QPushButton("Default") if self._icase_disp is None or self._default_phase is None: self.phase_label.setVisible(False) self.phase_edit.setVisible(False) self.phase_button.setVisible(False) self.phase_edit.setText('0.0') #--------------------------------------- self.arrow_scale_label = QLabel("Arrow Scale:") self.arrow_scale_edit = QLineEdit(str(self._arrow_scale)) self.arrow_scale_button = QPushButton("Default") if self._icase_vector is None: self.arrow_scale_label.setVisible(False) self.arrow_scale_edit.setVisible(False) self.arrow_scale_button.setVisible(False) #tip = QtGui.QToolTip() #tip.setTe #self.format_edit.toolTip(tip) #--------------------------------------- # nlabels self.nlabels_label = QLabel("Number of Labels:") self.nlabels_edit = QLineEdit(str(self._nlabels)) self.nlabels_button = QPushButton("Default") self.labelsize_label = QLabel("Label Size:") self.labelsize_edit = QLineEdit(str(self._labelsize)) self.labelsize_button = QPushButton("Default") self.ncolors_label = QLabel("Number of Colors:") self.ncolors_edit = QLineEdit(str(self._ncolors)) self.ncolors_button = QPushButton("Default") self.colormap_label = QLabel("Color Map:") self.colormap_edit = QComboBox(self) self.colormap_button = QPushButton("Default") for key in colormap_keys: self.colormap_edit.addItem(key) self.colormap_edit.setCurrentIndex(colormap_keys.index(self._colormap)) # -------------------------------------------------------------- # the header self.grid2_title = QLabel("Color Scale:") # red/blue or blue/red self.low_to_high_radio = QRadioButton('Low -> High') self.high_to_low_radio = QRadioButton('High -> Low') widget = QWidget(self) low_to_high_group = QButtonGroup(widget) low_to_high_group.addButton(self.low_to_high_radio) low_to_high_group.addButton(self.high_to_low_radio) self.low_to_high_radio.setChecked(self._default_is_low_to_high) self.high_to_low_radio.setChecked(not self._default_is_low_to_high) # horizontal / vertical self.horizontal_radio = QRadioButton("Horizontal") self.vertical_radio = QRadioButton("Vertical") widget = QWidget(self) horizontal_vertical_group = QButtonGroup(widget) horizontal_vertical_group.addButton(self.horizontal_radio) horizontal_vertical_group.addButton(self.vertical_radio) self.horizontal_radio.setChecked(self._default_is_horizontal) self.vertical_radio.setChecked(not self._default_is_horizontal) # on / off self.show_radio = QRadioButton("Show") self.hide_radio = QRadioButton("Hide") widget = QWidget(self) show_hide_group = QButtonGroup(widget) show_hide_group.addButton(self.show_radio) show_hide_group.addButton(self.hide_radio) self.show_radio.setChecked(self._default_is_shown) self.hide_radio.setChecked(not self._default_is_shown) # -------------------------------------------------------------- if self._icase_fringe is None: self.title_label.setVisible(False) self.title_edit.setVisible(False) self.title_button.setVisible(False) if not self._is_fringe: self.max_label.hide() self.min_label.hide() self.max_edit.hide() self.min_edit.hide() self.max_button.hide() self.min_button.hide() self.format_label.hide() self.format_edit.hide() self.format_button.hide() self.nlabels_label.hide() self.nlabels_edit.hide() self.nlabels_button.hide() self.ncolors_label.hide() self.ncolors_edit.hide() self.ncolors_button.hide() self.grid2_title.hide() self.vertical_radio.hide() self.horizontal_radio.hide() self.show_radio.hide() self.hide_radio.hide() self.low_to_high_radio.hide() self.high_to_low_radio.hide() self.colormap_label.hide() self.colormap_edit.hide() self.colormap_button.hide() self.animate_button = QPushButton('Create Animation') self.animate_button.setVisible(show_animation_button) #self.advanced_button = QPushButton('Advanced') if self._default_icase_disp is None: # or self._default_icase_vector is None: self.animate_button.setEnabled(False) self.animate_button.setToolTip(ANIMATE_TOOLTIP_OFF) else: self.animate_button.setEnabled(True) self.animate_button.setToolTip(ANIMATE_TOOLTIP_ON) # closing self.apply_button = QPushButton("Apply") self.ok_button = QPushButton("OK") self.cancel_button = QPushButton("Cancel")
class LegendPropertiesWindow(PyDialog): """ +-------------------+ | Legend Properties | +-----------------------+ | Title ______ Default | | Min ______ Default | | Max ______ Default | | Format ______ Default | | Scale ______ Default | | Phase ______ Default | | Number of Colors ____ | | Number of Labels ____ | | Label Size ____ | (TODO) | ColorMap ____ | (TODO) | | | x Min/Max (Blue->Red) | | o Max/Min (Red->Blue) | | | | x Vertical/Horizontal | | x Show/Hide | | | | Animate | | Apply OK Cancel | +-----------------------+ """ def __init__(self, data, win_parent=None, show_animation_button=True): PyDialog.__init__(self, data, win_parent) self.is_gui = win_parent is not None self._updated_legend = False self.external_call = True #if win_parent is None: self._icase_fringe = data['icase_fringe'] self._icase_disp = data['icase_disp'] self._icase_vector = data['icase_vector'] #else: #self._icase_fringe = data['icase'] #self._icase_disp = data['icase'] #self._icase_vector = data['icase'] self._default_icase_fringe = self._icase_fringe self._default_icase_disp = self._icase_disp self._default_icase_vector = self._icase_vector #print('*icase_fringe=%s icase_disp=%s icase_vector=%s' % ( #self._default_icase_fringe, self._default_icase_disp, self._default_icase_vector)) self._default_title = data['title'] self._default_min = data['min_value'] self._default_max = data['max_value'] self._default_scale = data['default_scale'] self._scale = data['scale'] #if win_parent is None: self._default_arrow_scale = data['default_arrow_scale'] self._arrow_scale = data['arrow_scale'] #else: #self._default_arrow_scale = data['default_scale'] #self._arrow_scale = data['scale'] self._default_phase = data['default_phase'] self._phase = data['phase'] self._default_format = data['default_format'] self._format = data['format'] self._default_labelsize = data['default_labelsize'] self._labelsize = data['labelsize'] self._default_nlabels = data['default_nlabels'] self._nlabels = data['nlabels'] self._default_ncolors = data['default_ncolors'] self._ncolors = data['ncolors'] self._default_colormap = data['default_colormap'] self._colormap = data['colormap'] self._default_is_low_to_high = data['is_low_to_high'] self._default_is_discrete = data['is_discrete'] self._default_is_horizontal = data['is_horizontal'] self._default_is_shown = data['is_shown'] self._is_fringe = data['is_fringe'] self._update_defaults_to_blank() self.setWindowTitle('Legend Properties') self.create_widgets(show_animation_button=show_animation_button) self.create_layout() self.set_connections() self.set_font_size(data['font_size']) def _update_defaults_to_blank(self): """Changes the default (None) to a blank string""" if self._default_colormap is None: self._default_colormap = 'jet' if self._default_labelsize is None: self._default_labelsize = '' if self._default_ncolors is None: self._default_ncolors = '' if self._default_nlabels is None: self._default_nlabels = '' if self._colormap is None: self._colormap = 'jet' if self._labelsize is None: self._labelsize = '' if self._ncolors is None: self._ncolors = '' if self._nlabels is None: self._nlabels = '' def update_legend(self, icase_fringe, icase_disp, icase_vector, title, min_value, max_value, data_format, nlabels, labelsize, ncolors, colormap, is_fringe, scale, phase, arrow_scale, default_title, default_min_value, default_max_value, default_data_format, default_nlabels, default_labelsize, default_ncolors, default_colormap, default_scale, default_phase, default_arrow_scale, font_size=8, external_call=False): """ We need to update the legend if there's been a result change request """ self.external_call = external_call self.set_font_size(font_size) update_fringe = False update_disp = False update_vector = False #print('update_legend; fringe=%s disp=%s vector=%s' % ( #icase_fringe, icase_disp, icase_vector)) #print('update_legend; default: fringe=%s disp=%s vector=%s' % ( # self._default_icase_fringe, self._default_icase_disp, self._default_icase_vector)) if icase_fringe != self._default_icase_fringe: self._icase_fringe = icase_fringe self._default_icase_fringe = icase_fringe update_fringe = True #is_fringe = icase_fringe is not None is_disp = icase_disp is not None is_vector = icase_vector is not None if icase_disp != self._default_icase_disp: assert isinstance( scale, float_types), 'scale=%r type=%s' % (scale, type(scale)) #assert isinstance(default_scale, float), 'default_scale=%r' % default_scale self._icase_disp = icase_disp self._default_icase_disp = icase_disp self._default_scale = default_scale self._default_phase = default_phase update_disp = True if icase_vector != self._default_icase_vector: assert isinstance( arrow_scale, float_types), 'arrow_scale=%r type=%s' % (arrow_scale, type(scale)) #assert isinstance(default_arrow_scale, float), 'default_arrow_scale=%r' % default_arrow_scale self._icase_vector = icase_vector self._default_icase_vector = icase_vector self._default_arrow_scale = default_arrow_scale update_vector = True #print('*update_legend; default: fringe=%s disp=%s vector=%s' % ( # self._default_icase_fringe, self._default_icase_disp, self._default_icase_vector)) #print('update_fringe=%s update_disp=%s update_vector=%s' % ( # update_fringe, update_disp, update_vector)) #print('is_fringe=%s is_disp=%s is_vector=%s' % ( # is_fringe, is_disp, is_vector)) if update_fringe: self._icase_fringe = icase_fringe self._default_icase_fringe = icase_fringe self._default_title = default_title self._default_min = default_min_value self._default_max = default_max_value self._default_format = default_data_format #self._default_is_low_to_high = is_low_to_high self._default_is_discrete = True #self._default_is_horizontal = is_horizontal_scalar_bar self._default_nlabels = default_nlabels self._default_labelsize = default_labelsize self._default_ncolors = default_ncolors self._default_colormap = default_colormap self._is_fringe = is_fringe if colormap is None: colormap = 'jet' if labelsize is None: labelsize = '' if ncolors is None: ncolors = '' if nlabels is None: nlabels = '' self._update_defaults_to_blank() #----------------------------------------------------------------------- update = update_fringe or update_disp or update_vector if update: #self.scale_label.setEnabled(is_disp) #self.scale_edit.setEnabled(is_disp) #self.scale_button.setEnabled(is_disp) self.scale_label.setVisible(is_disp) self.scale_edit.setVisible(is_disp) self.scale_button.setVisible(is_disp) is_complex_disp = self._default_phase is not None self.phase_label.setVisible(is_complex_disp) self.phase_edit.setVisible(is_complex_disp) self.phase_button.setVisible(is_complex_disp) self._scale = set_cell_to_blank_if_value_is_none( self.scale_edit, scale) self._phase = set_cell_to_blank_if_value_is_none( self.phase_edit, phase) if self._default_icase_disp is None: # or self._default_icase_vector is None: self.animate_button.setEnabled(False) self.animate_button.setToolTip(ANIMATE_TOOLTIP_OFF) else: self.animate_button.setEnabled(True) self.animate_button.setToolTip(ANIMATE_TOOLTIP_ON) #----------------------------------------------------------------------- if update: #self.arrow_scale_label.setEnabled(is_vector) #self.arrow_scale_edit.setEnabled(is_vector) #self.arrow_scale_button.setEnabled(is_vector) self.arrow_scale_label.setVisible(is_vector) self.arrow_scale_edit.setVisible(is_vector) self.arrow_scale_button.setVisible(is_vector) self._arrow_scale = set_cell_to_blank_if_value_is_none( self.arrow_scale_edit, arrow_scale) #----------------------------------------------------------------------- if update_fringe: #self.on_default_title() #self.on_default_min() #self.on_default_max() #self.on_default_format() #self.on_default_scale() # reset defaults self.title_edit.setText(title) self.title_edit.setStyleSheet("QLineEdit{background: white;}") self.min_edit.setText(str(min_value)) self.min_edit.setStyleSheet("QLineEdit{background: white;}") self.max_edit.setText(str(max_value)) self.max_edit.setStyleSheet("QLineEdit{background: white;}") self.format_edit.setText(str(data_format)) self.format_edit.setStyleSheet("QLineEdit{background: white;}") self.nlabels_edit.setText(str(nlabels)) self.nlabels_edit.setStyleSheet("QLineEdit{background: white;}") self.labelsize_edit.setText(str(labelsize)) self.labelsize_edit.setStyleSheet("QLineEdit{background: white;}") self.ncolors_edit.setText(str(ncolors)) self.ncolors_edit.setStyleSheet("QLineEdit{background: white;}") self.colormap_edit.setCurrentIndex( colormap_keys.index(str(colormap))) self._set_legend_fringe(self._is_fringe) if update: self.on_apply() self.external_call = True #print('---------------------------------') def clear_disp(self): """hides dispacement blocks""" self._icase_disp = None self._default_icase_disp = None self.scale_label.setVisible(False) self.scale_edit.setVisible(False) self.scale_button.setVisible(False) self.phase_label.setVisible(False) self.phase_edit.setVisible(False) self.phase_button.setVisible(False) def clear_vector(self): """hides vector blocks""" self._icase_vector = None self._default_icase_vector = None self.arrow_scale_label.setVisible(False) self.arrow_scale_edit.setVisible(False) self.arrow_scale_button.setVisible(False) def clear(self): """hides fringe, displacemnt, and vector blocks""" self._icase_fringe = None self._default_icase_fringe = None self._set_legend_fringe(False) self.clear_disp() self.clear_vector() def _set_legend_fringe(self, is_fringe): """ Show/hide buttons if we dont have a result. This is used for normals. A result can still exist (i.e., icase_fringe is not None). """ # lots of hacking for the Normal vectors self._is_fringe = is_fringe #self._default_icase_fringe = None enable = True if not is_fringe: enable = False show_title = self._icase_fringe is not None self.title_label.setVisible(show_title) self.title_edit.setVisible(show_title) self.title_button.setVisible(show_title) self.max_label.setVisible(enable) self.min_label.setVisible(enable) self.max_edit.setVisible(enable) self.min_edit.setVisible(enable) self.max_button.setVisible(enable) self.min_button.setVisible(enable) self.show_radio.setVisible(enable) self.hide_radio.setVisible(enable) self.low_to_high_radio.setVisible(enable) self.high_to_low_radio.setVisible(enable) self.format_label.setVisible(enable) self.format_edit.setVisible(enable) self.format_edit.setVisible(enable) self.format_button.setVisible(enable) self.nlabels_label.setVisible(enable) self.nlabels_edit.setVisible(enable) self.nlabels_button.setVisible(enable) self.ncolors_label.setVisible(enable) self.ncolors_edit.setVisible(enable) self.ncolors_button.setVisible(enable) self.grid2_title.setVisible(enable) self.vertical_radio.setVisible(enable) self.horizontal_radio.setVisible(enable) self.colormap_label.setVisible(enable) self.colormap_edit.setVisible(enable) self.colormap_button.setVisible(enable) def create_widgets(self, show_animation_button=True): """creates the menu objects""" # title self.title_label = QLabel("Title:") self.title_edit = QLineEdit(str(self._default_title)) self.title_button = QPushButton("Default") # Min self.min_label = QLabel("Min:") self.min_edit = QLineEdit(str(self._default_min)) self.min_button = QPushButton("Default") # Max self.max_label = QLabel("Max:") self.max_edit = QLineEdit(str(self._default_max)) self.max_button = QPushButton("Default") #--------------------------------------- # Format self.format_label = QLabel("Format (e.g. %.3f, %g, %.6e):") self.format_edit = QLineEdit(str(self._format)) self.format_button = QPushButton("Default") #--------------------------------------- # Scale self.scale_label = QLabel("True Scale:") self.scale_edit = QLineEdit(str(self._scale)) self.scale_button = QPushButton("Default") if self._icase_disp is None: self.scale_label.setVisible(False) self.scale_edit.setVisible(False) self.scale_button.setVisible(False) # Phase self.phase_label = QLabel("Phase (deg):") self.phase_edit = QLineEdit(str(self._phase)) self.phase_button = QPushButton("Default") if self._icase_disp is None or self._default_phase is None: self.phase_label.setVisible(False) self.phase_edit.setVisible(False) self.phase_button.setVisible(False) self.phase_edit.setText('0.0') #--------------------------------------- self.arrow_scale_label = QLabel("Arrow Scale:") self.arrow_scale_edit = QLineEdit(str(self._arrow_scale)) self.arrow_scale_button = QPushButton("Default") if self._icase_vector is None: self.arrow_scale_label.setVisible(False) self.arrow_scale_edit.setVisible(False) self.arrow_scale_button.setVisible(False) #tip = QtGui.QToolTip() #tip.setTe #self.format_edit.toolTip(tip) #--------------------------------------- # nlabels self.nlabels_label = QLabel("Number of Labels:") self.nlabels_edit = QLineEdit(str(self._nlabels)) self.nlabels_button = QPushButton("Default") self.labelsize_label = QLabel("Label Size:") self.labelsize_edit = QLineEdit(str(self._labelsize)) self.labelsize_button = QPushButton("Default") self.ncolors_label = QLabel("Number of Colors:") self.ncolors_edit = QLineEdit(str(self._ncolors)) self.ncolors_button = QPushButton("Default") self.colormap_label = QLabel("Color Map:") self.colormap_edit = QComboBox(self) self.colormap_button = QPushButton("Default") for key in colormap_keys: self.colormap_edit.addItem(key) self.colormap_edit.setCurrentIndex(colormap_keys.index(self._colormap)) # -------------------------------------------------------------- # the header self.grid2_title = QLabel("Color Scale:") # red/blue or blue/red self.low_to_high_radio = QRadioButton('Low -> High') self.high_to_low_radio = QRadioButton('High -> Low') widget = QWidget(self) low_to_high_group = QButtonGroup(widget) low_to_high_group.addButton(self.low_to_high_radio) low_to_high_group.addButton(self.high_to_low_radio) self.low_to_high_radio.setChecked(self._default_is_low_to_high) self.high_to_low_radio.setChecked(not self._default_is_low_to_high) # horizontal / vertical self.horizontal_radio = QRadioButton("Horizontal") self.vertical_radio = QRadioButton("Vertical") widget = QWidget(self) horizontal_vertical_group = QButtonGroup(widget) horizontal_vertical_group.addButton(self.horizontal_radio) horizontal_vertical_group.addButton(self.vertical_radio) self.horizontal_radio.setChecked(self._default_is_horizontal) self.vertical_radio.setChecked(not self._default_is_horizontal) # on / off self.show_radio = QRadioButton("Show") self.hide_radio = QRadioButton("Hide") widget = QWidget(self) show_hide_group = QButtonGroup(widget) show_hide_group.addButton(self.show_radio) show_hide_group.addButton(self.hide_radio) self.show_radio.setChecked(self._default_is_shown) self.hide_radio.setChecked(not self._default_is_shown) # -------------------------------------------------------------- if self._icase_fringe is None: self.title_label.setVisible(False) self.title_edit.setVisible(False) self.title_button.setVisible(False) if not self._is_fringe: self.max_label.hide() self.min_label.hide() self.max_edit.hide() self.min_edit.hide() self.max_button.hide() self.min_button.hide() self.format_label.hide() self.format_edit.hide() self.format_button.hide() self.nlabels_label.hide() self.nlabels_edit.hide() self.nlabels_button.hide() self.ncolors_label.hide() self.ncolors_edit.hide() self.ncolors_button.hide() self.grid2_title.hide() self.vertical_radio.hide() self.horizontal_radio.hide() self.show_radio.hide() self.hide_radio.hide() self.low_to_high_radio.hide() self.high_to_low_radio.hide() self.colormap_label.hide() self.colormap_edit.hide() self.colormap_button.hide() self.animate_button = QPushButton('Create Animation') self.animate_button.setVisible(show_animation_button) #self.advanced_button = QPushButton('Advanced') if self._default_icase_disp is None: # or self._default_icase_vector is None: self.animate_button.setEnabled(False) self.animate_button.setToolTip(ANIMATE_TOOLTIP_OFF) else: self.animate_button.setEnabled(True) self.animate_button.setToolTip(ANIMATE_TOOLTIP_ON) # closing self.apply_button = QPushButton("Apply") self.ok_button = QPushButton("OK") self.cancel_button = QPushButton("Cancel") def create_layout(self): """displays the menu objects""" grid = QGridLayout() grid.addWidget(self.title_label, 0, 0) grid.addWidget(self.title_edit, 0, 1) grid.addWidget(self.title_button, 0, 2) grid.addWidget(self.min_label, 1, 0) grid.addWidget(self.min_edit, 1, 1) grid.addWidget(self.min_button, 1, 2) grid.addWidget(self.max_label, 2, 0) grid.addWidget(self.max_edit, 2, 1) grid.addWidget(self.max_button, 2, 2) grid.addWidget(self.format_label, 3, 0) grid.addWidget(self.format_edit, 3, 1) grid.addWidget(self.format_button, 3, 2) grid.addWidget(self.scale_label, 4, 0) grid.addWidget(self.scale_edit, 4, 1) grid.addWidget(self.scale_button, 4, 2) grid.addWidget(self.phase_label, 6, 0) grid.addWidget(self.phase_edit, 6, 1) grid.addWidget(self.phase_button, 6, 2) grid.addWidget(self.arrow_scale_label, 5, 0) grid.addWidget(self.arrow_scale_edit, 5, 1) grid.addWidget(self.arrow_scale_button, 5, 2) grid.addWidget(self.nlabels_label, 7, 0) grid.addWidget(self.nlabels_edit, 7, 1) grid.addWidget(self.nlabels_button, 7, 2) #grid.addWidget(self.labelsize_label, 6, 0) #grid.addWidget(self.labelsize_edit, 6, 1) #grid.addWidget(self.labelsize_button, 6, 2) grid.addWidget(self.ncolors_label, 8, 0) grid.addWidget(self.ncolors_edit, 8, 1) grid.addWidget(self.ncolors_button, 8, 2) grid.addWidget(self.colormap_label, 9, 0) grid.addWidget(self.colormap_edit, 9, 1) grid.addWidget(self.colormap_button, 9, 2) ok_cancel_box = QHBoxLayout() ok_cancel_box.addWidget(self.apply_button) ok_cancel_box.addWidget(self.ok_button) ok_cancel_box.addWidget(self.cancel_button) grid2 = QGridLayout() grid2.addWidget(self.grid2_title, 0, 0) grid2.addWidget(self.low_to_high_radio, 1, 0) grid2.addWidget(self.high_to_low_radio, 2, 0) grid2.addWidget(self.vertical_radio, 1, 1) grid2.addWidget(self.horizontal_radio, 2, 1) grid2.addWidget(self.show_radio, 1, 2) grid2.addWidget(self.hide_radio, 2, 2) grid2.addWidget(self.animate_button, 3, 1) #grid2.setSpacing(0) vbox = QVBoxLayout() vbox.addLayout(grid) #vbox.addLayout(checkboxes) vbox.addLayout(grid2) vbox.addStretch() vbox.addLayout(ok_cancel_box) self.setLayout(vbox) def set_connections(self): """creates the actions for the menu""" self.title_button.clicked.connect(self.on_default_title) self.min_button.clicked.connect(self.on_default_min) self.max_button.clicked.connect(self.on_default_max) self.format_button.clicked.connect(self.on_default_format) self.scale_button.clicked.connect(self.on_default_scale) self.arrow_scale_button.clicked.connect(self.on_default_arrow_scale) self.phase_button.clicked.connect(self.on_default_phase) self.nlabels_button.clicked.connect(self.on_default_nlabels) self.labelsize_button.clicked.connect(self.on_default_labelsize) self.ncolors_button.clicked.connect(self.on_default_ncolors) self.colormap_button.clicked.connect(self.on_default_colormap) self.animate_button.clicked.connect(self.on_animate) self.show_radio.clicked.connect(self.on_show_hide) self.hide_radio.clicked.connect(self.on_show_hide) self.apply_button.clicked.connect(self.on_apply) self.ok_button.clicked.connect(self.on_ok) self.cancel_button.clicked.connect(self.on_cancel) if qt_version == 4: self.connect(self, QtCore.SIGNAL('triggered()'), self.closeEvent) #self.colormap_edit.activated[str].connect(self.onActivated) #else: # closeEvent??? def set_font_size(self, font_size): """ Updates the font size of the objects Parameters ---------- font_size : int the font size """ if self.font_size == font_size: return self.font_size = font_size font = QFont() font.setPointSize(font_size) self.setFont(font) self.title_edit.setFont(font) self.min_edit.setFont(font) self.max_edit.setFont(font) self.format_edit.setFont(font) self.scale_edit.setFont(font) self.phase_edit.setFont(font) self.nlabels_edit.setFont(font) self.labelsize_edit.setFont(font) self.ncolors_edit.setFont(font) def on_animate(self): """opens the animation window""" title, flag0 = check_name_str(self.title_edit) if not flag0: return scale, flag1 = check_float(self.scale_edit) if not flag1: scale = self._scale data = { 'font_size': self.out_data['font_size'], 'icase_fringe': self._icase_fringe, 'icase_disp': self._icase_disp, 'icase_vector': self._icase_vector, 'title': title, 'time': 2, 'frames/sec': 30, 'resolution': 1, 'iframe': 0, 'scale': scale, 'default_scale': self._default_scale, 'arrow_scale': scale, 'default_arrow_scale': self._default_arrow_scale, 'is_scale': self._default_phase is None, 'phase': self._phase, 'default_phase': self._default_phase, 'dirname': os.path.abspath(os.getcwd()), 'clicked_ok': False, 'close': False, } self.win_parent.legend_obj.set_animation_window(data) def on_default_title(self): """action when user clicks 'Default' for title""" title = str(self._default_title) self.title_edit.setText(title) self.title_edit.setStyleSheet("QLineEdit{background: white;}") def on_default_min(self): """action when user clicks 'Default' for min value""" self.min_edit.setText(str(self._default_min)) self.min_edit.setStyleSheet("QLineEdit{background: white;}") def on_default_max(self): """action when user clicks 'Default' for max value""" self.max_edit.setText(str(self._default_max)) self.max_edit.setStyleSheet("QLineEdit{background: white;}") def on_default_format(self): """action when user clicks 'Default' for the number format""" self.format_edit.setText(str(self._default_format)) self.format_edit.setStyleSheet("QLineEdit{background: white;}") def on_default_scale(self): """action when user clicks 'Default' for scale factor""" self.scale_edit.setText(str(self._default_scale)) self.scale_edit.setStyleSheet("QLineEdit{background: white;}") def on_default_arrow_scale(self): """action when user clicks 'Default' for arrow_scale factor""" self.arrow_scale_edit.setText(str(self._default_arrow_scale)) self.arrow_scale_edit.setStyleSheet("QLineEdit{background: white;}") def on_default_phase(self): """action when user clicks 'Default' for phase angle""" self.phase_edit.setText(str(self._default_phase)) self.phase_edit.setStyleSheet("QLineEdit{background: white;}") def on_default_ncolors(self): """action when user clicks 'Default' for number of colors""" self.ncolors_edit.setText(str(self._default_ncolors)) self.ncolors_edit.setStyleSheet("QLineEdit{background: white;}") def on_default_colormap(self): """action when user clicks 'Default' for the color map""" self.colormap_edit.setCurrentIndex( colormap_keys.index(self._default_colormap)) def on_default_nlabels(self): """action when user clicks 'Default' for number of labels""" self.nlabels_edit.setStyleSheet("QLineEdit{background: white;}") self.nlabels_edit.setText(str(self._default_nlabels)) def on_default_labelsize(self): """action when user clicks 'Default' for number of labelsize""" self.labelsize_edit.setText(str(self._default_labelsize)) self.labelsize_edit.setStyleSheet("QLineEdit{background: white;}") def on_show_hide(self): """action when user clicks the 'Show/Hide' radio button""" #self.colormap_edit.setCurrentIndex(colormap_keys.index(self._default_colormap)) is_shown = self.show_radio.isChecked() self.nlabels_edit.setEnabled(is_shown) self.nlabels_button.setEnabled(is_shown) self.ncolors_edit.setEnabled(is_shown) self.ncolors_button.setEnabled(is_shown) self.high_to_low_radio.setEnabled(is_shown) self.low_to_high_radio.setEnabled(is_shown) self.colormap_edit.setEnabled(is_shown) self.colormap_button.setEnabled(is_shown) self.vertical_radio.setEnabled(is_shown) self.horizontal_radio.setEnabled(is_shown) def show_legend(self): """shows the legend""" self._set_legend(True) def hide_legend(self): """hides the legend""" self._set_legend(False) def _set_legend(self, is_shown): """shows/hides the legend""" self.show_radio.setChecked(is_shown) self.hide_radio.setChecked(not is_shown) #if self.is_gui: #self.win_parent.scalar_bar_actor.SetVisibility(is_shown) def on_validate(self): """checks to see if the ``on_apply`` method can be called""" show_title = self._icase_fringe is not None flag_title = True title_value = '' if show_title: title_value, flag_title = check_name_str(self.title_edit) flag_fringe = True min_value = max_value = format_value = nlabels = ncolors = labelsize = colormap = None if self._icase_fringe is not None: min_value, flag1 = check_float(self.min_edit) max_value, flag2 = check_float(self.max_edit) format_value, flag3 = check_format(self.format_edit) nlabels, flag4 = check_positive_int_or_blank(self.nlabels_edit) ncolors, flag5 = check_positive_int_or_blank(self.ncolors_edit) labelsize, flag6 = check_positive_int_or_blank(self.labelsize_edit) colormap = str(self.colormap_edit.currentText()) if flag3 and 'i' in format_value: format_value = '%i' flag_fringe = all([flag1, flag2, flag3, flag4, flag5, flag6]) flag_disp = True scale = phase = None if self._icase_disp is not None: scale, flag1 = check_float(self.scale_edit) phase, flag2 = check_float(self.phase_edit) assert isinstance(scale, float), scale flag_disp = all([flag1, flag2]) flag_vector = True arrow_scale = None if self._icase_vector is not None: arrow_scale, flag_vector = check_float(self.arrow_scale_edit) if all([flag_title, flag_fringe, flag_disp, flag_vector]): self.out_data['title'] = title_value self.out_data['min_value'] = min_value self.out_data['max_value'] = max_value self.out_data['format'] = format_value self.out_data['scale'] = scale self.out_data['phase'] = phase self.out_data['arrow_scale'] = arrow_scale self.out_data['nlabels'] = nlabels self.out_data['ncolors'] = ncolors self.out_data['labelsize'] = labelsize self.out_data['colormap'] = colormap self.out_data['is_low_to_high'] = self.low_to_high_radio.isChecked( ) self.out_data['is_horizontal'] = self.horizontal_radio.isChecked() self.out_data['is_shown'] = self.show_radio.isChecked() self.out_data['clicked_ok'] = True self.out_data['close'] = True #print('self.out_data = ', self.out_data) #print("title = %r" % self.title_edit.text()) #print("min = %r" % self.min_edit.text()) #print("max = %r" % self.max_edit.text()) #print("format = %r" % self.format_edit.text()) return True return False def on_apply(self): """applies the current values""" passed = self.on_validate() if passed and self.external_call: self.win_parent.legend_obj._apply_legend(self.out_data) self.external_call = True return passed def on_ok(self): """applies the current values and closes the window""" passed = self.on_apply() if passed: self.close() #self.destroy() def on_cancel(self): """closes the windows and reverts the legend""" self.out_data['close'] = True self.close()
def _setupControlsWidget(self): ld_growenbl = QLabel('Grow/Damp Enable', self) cb_growenbl = PyDMEnumComboBox(self, self.dev_pref+':GDEN') ld_down = QLabel('Rec. Downsample ', self) sb_down = PyDMSpinbox(self, self.dev_pref+':'+self.TYPE+'_REC_DS') sb_down.showStepExponent = False ld_rawdata = QLabel('Raw Data', self) cb_rawdata = PyDMStateButton(self, self.dev_pref+':'+self.TYPE+'_DUMP') ld_acqtime = QLabel('Acquisition Time', self) sb_acqtime = PyDMSpinbox(self, self.dev_pref+':'+self.TYPE+'_ACQTIME') sb_acqtime.showStepExponent = False sb_acqtime.showUnits = True ld_holdoff = QLabel('Hold-Off Time', self) sb_holdoff = PyDMSpinbox(self, self.dev_pref+':'+self.TYPE+'_HOLDTIME') sb_holdoff.showStepExponent = False sb_holdoff.showUnits = True ld_posttrg = QLabel('Post Trigger', self) sb_posttrg = PyDMSpinbox(self, self.dev_pref+':'+self.TYPE+'_POSTTIME') sb_posttrg.showStepExponent = False sb_posttrg.showUnits = True fr_posttrg = SiriusFrame( self, self.dev_pref+':'+self.TYPE+'_POSTREG_SUBWR') fr_posttrg.add_widget(sb_posttrg) ld_growtime = QLabel('Growth Time', self) sb_growtime = PyDMSpinbox(self, self.dev_pref+':'+self.TYPE+'_GDTIME') sb_growtime.showStepExponent = False sb_growtime.showUnits = True fr_growtime = SiriusFrame( self, self.dev_pref+':'+self.TYPE+'_GDREG_SUBWR') fr_growtime.add_widget(sb_growtime) ld_acqlen = QLabel('Acquisition Length', self) lb_acqlen = PyDMLabel(self, self.dev_pref+':'+self.TYPE+'_ACQ_TURNS') lb_acqlen.showUnits = True ld_psttrglen = QLabel('Post Trigger Length', self) lb_psttrglen = PyDMLabel( self, self.dev_pref+':'+self.TYPE+'_POST_TURNS') lb_psttrglen.showUnits = True bt_modal = QPushButton('Modal Analysis', self) window = create_window_from_widget( _BbBModalAnalysis, title='SRAM Modal Analysis', icon=get_bbb_icon(), is_main=True) connect_window( bt_modal, window, self, prefix=self._prefix, device=self._device, acq_type=self.TYPE) gbox_dtacq = QGroupBox('Data Acquisition', self) lay_dtacq = QGridLayout(gbox_dtacq) lay_dtacq.addWidget(ld_growenbl, 0, 0) lay_dtacq.addWidget(cb_growenbl, 0, 1) lay_dtacq.addWidget(ld_down, 1, 0) lay_dtacq.addWidget(sb_down, 1, 1) lay_dtacq.addWidget(ld_rawdata, 2, 0) lay_dtacq.addWidget(cb_rawdata, 2, 1) lay_dtacq.addWidget(ld_acqtime, 3, 0) lay_dtacq.addWidget(sb_acqtime, 3, 1) lay_dtacq.addWidget(ld_holdoff, 4, 0) lay_dtacq.addWidget(sb_holdoff, 4, 1) lay_dtacq.addWidget(ld_posttrg, 5, 0) lay_dtacq.addWidget(fr_posttrg, 5, 1) lay_dtacq.addWidget(ld_growtime, 6, 0) lay_dtacq.addWidget(fr_growtime, 6, 1) lay_dtacq.addWidget(ld_acqlen, 7, 0) lay_dtacq.addWidget(lb_acqlen, 7, 1) lay_dtacq.addWidget(ld_psttrglen, 8, 0) lay_dtacq.addWidget(lb_psttrglen, 8, 1) lay_dtacq.addWidget(bt_modal, 9, 0, 1, 2) ld_acqtyp = QLabel( '<h4>Acq Type</h4>', self, alignment=Qt.AlignCenter) cb_acqtyp = PyDMEnumComboBox( self, self.dev_pref+':'+self.TYPE+'_POSTSEL') gbox_acqtyp = QGroupBox(self) lay_acqtyp = QVBoxLayout(gbox_acqtyp) lay_acqtyp.addWidget(ld_acqtyp) lay_acqtyp.addWidget(cb_acqtyp) ld_trgexten = QLabel('Internal/External', self) cb_trgexten = PyDMEnumComboBox( self, self.dev_pref+':'+self.TYPE+'_HWTEN') ld_trginsel = QLabel('Selection', self) cb_trginsel = PyDMEnumComboBox( self, self.dev_pref+':'+self.TYPE+'_TRIG_IN_SEL') ld_trgarm = QLabel('Arm', self) cb_trgarm = PyDMStateButton(self, self.dev_pref+':'+self.TYPE+'_ARM') lb_armmon = SiriusLedState( self, self.dev_pref+':'+self.TYPE+'_ARM_MON') ld_trgbrarm = QLabel('Auto re-arm', self) cb_trgbrarm = PyDMStateButton( self, self.dev_pref+':'+self.TYPE+'_BR_ARM') ld_rst = QLabel('Trigger 1/2 Cap.:', self) lb_rst1 = PyDMLabel(self, self.dev_pref+':'+self.TYPE+'_CAP_TRIG1') lb_rst2 = PyDMLabel(self, self.dev_pref+':'+self.TYPE+'_CAP_TRIG2') gbox_trig = QGroupBox('Trigger', self) lay_trig = QGridLayout(gbox_trig) lay_trig.setAlignment(Qt.AlignTop) lay_trig.addWidget(ld_trgexten, 0, 0) lay_trig.addWidget(cb_trgexten, 0, 1, 1, 2) lay_trig.addWidget(ld_trginsel, 1, 0) lay_trig.addWidget(cb_trginsel, 1, 1, 1, 2) lay_trig.addWidget(ld_trgarm, 2, 0) lay_trig.addWidget(cb_trgarm, 2, 1) lay_trig.addWidget(lb_armmon, 2, 2) lay_trig.addWidget(ld_trgbrarm, 3, 0) lay_trig.addWidget(cb_trgbrarm, 3, 1) lay_trig.addWidget(ld_rst, 4, 0) lay_trig.addWidget(lb_rst1, 4, 1) lay_trig.addWidget(lb_rst2, 4, 2) lay_trig.setRowStretch(5, 2) pixmap = QPixmap(_os.path.join( _os.path.abspath(_os.path.dirname(__file__)), 'grow_damp.png')) img_wid = QLabel(self) img_wid.setPixmap(pixmap) img_wid.setScaledContents(True) wid = QWidget() lay = QGridLayout(wid) lay.setContentsMargins(0, 0, 0, 0) lay.addWidget(gbox_acqtyp, 0, 0) lay.addWidget(gbox_dtacq, 1, 0) lay.addWidget(gbox_trig, 2, 0) lay.addWidget(img_wid, 4, 0) lay.setRowStretch(3, 5) lay.setRowStretch(5, 5) wid.setStyleSheet("SiriusFrame{max-height: 1.8em;}") return wid
def create_clim_reset_buttons(layer): """Create contrast limits reset and full range buttons. Important: consumers of this function should check whether range_btn is not None before adding the widget to a layout. Adding None to a layout can cause a segmentation fault. Parameters ---------- layer : napari.layers.Layer Image or Surface Layer Returns ------- 2-tuple If layer data type is integer type, returns (reset_btn, range_btn). Else, returns (reset_btn, None) """ def reset(): layer.reset_contrast_limits() layer.contrast_limits_range = layer.contrast_limits def reset_range(): layer.reset_contrast_limits_range() reset_btn = QPushButton("reset") reset_btn.setObjectName("reset_clims_button") reset_btn.setToolTip("autoscale contrast to data range") reset_btn.setFixedWidth(40) reset_btn.clicked.connect(reset) range_btn = None # the "full range" button doesn't do anything if it's not an # unsigned integer type (it's unclear what range should be set) # so we don't show create it at all. if np.issubdtype(layer.dtype, np.integer): range_btn = QPushButton("full range") range_btn.setObjectName("full_clim_range_button") range_btn.setToolTip("set contrast range to full bit-depth") range_btn.setFixedWidth(65) range_btn.clicked.connect(reset_range) return reset_btn, range_btn
class ColorSelector(QWidget): def __init__(self, initial_color=MPL_DEFAULT, parent=None): super(ColorSelector, self).__init__(parent=parent) self.initial_color = QColor(initial_color) # Create line edit and push button and add to a horizontal layout self.line_edit = QLineEdit(self) self.button = QPushButton(self) self.h_layout = QHBoxLayout(self) self.h_layout.addWidget(self.line_edit) self.h_layout.addWidget(self.button) self.h_layout.setContentsMargins(0, 0, 0, 0) self.line_edit.setText(self.initial_color.name()) self.prev_color = self.initial_color.name() # Color input only allows valid hex codes. re = QRegExp('^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$') validator = ColorValidator(re, self.line_edit, self) self.line_edit.setValidator(validator) self.button.setAutoFillBackground(True) self.button.setFlat(True) self.update_color_button() # Signals self.button.clicked.connect(self.launch_qcolor_dialog) self.line_edit.textChanged.connect(self.update_color_button) self.line_edit.editingFinished.connect(self.convert_three_digit_hex_to_six) def get_color(self): return self.line_edit.text() def launch_qcolor_dialog(self): color_dialog = QColorDialog(self) color_dialog.setCurrentColor(QColor(self.get_color())) color_dialog.colorSelected.connect( lambda: self.set_line_edit(color_dialog.selectedColor().name()) ) color_dialog.accepted.connect( lambda: self.set_prev_color(color_dialog.selectedColor().name()) ) color_dialog.setModal(True) color_dialog.show() def set_prev_color(self, color): self.prev_color = color def set_color(self, color_hex): self.line_edit.setText(convert_color_to_hex(color_hex)) def set_line_edit(self, color_hex): self.line_edit.setText(color_hex) def update_color_button(self): color = self.get_color() self.button.setStyleSheet("border:1px solid #000000;" f"background-color: {color}") self.button.update() def convert_three_digit_hex_to_six(self): color = self.get_color() # If a 3-digit hex code is inputted, it is converted to 6 digits # by duplicating each digit. if len(color) == 4: new = '#{}'.format(''.join(2 * c for c in color.lstrip('#'))) self.set_color(new) color = new self.prev_color = color
def __init__(self, viewer, metadata_levels, initial_classes, *args, **kwargs): super(Classifier,self).__init__(*args,**kwargs) self.viewer = viewer # open image if not already open if len(self.viewer.layers)<1: msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setText("No image open, please select an image in the following dialog.") msg.exec() self.viewer.window.qt_viewer._open_files_dialog() if len(self.viewer.layers)<1: # still no image open raise ValueError("Could not find image layers.") # get image shape self.shape = self.viewer.layers[0].shape # check metadata levels if not metadata_levels: self.metadata_levels = [f'dim_{dim}' for dim in range(len(self.shape[:-2]))] elif len(metadata_levels)!=len(self.shape[:-2]): metadata_levels_warning = NapariNotification((f'Number of metadata_levels ({len(metadata_levels)}) does not match ' f'number of leading image dimensions ({len(self.shape[:-2])}); will use default metadata_levels.'), severity='warning') metadata_levels_warning.show() self.metadata_levels = [f'dim_{dim}' for dim in range(len(self.shape[:-2]))] else: self.metadata_levels = metadata_levels # load metadata self.load_metadata() # initialize widget layout = QHBoxLayout() ## io panel save_button = QPushButton('Save...',self) save_button.clicked.connect(self.save_results) io_panel = QWidget() io_layout = QVBoxLayout() io_layout.addWidget(save_button) io_panel.setLayout(io_layout) layout.addWidget(io_panel) ## class panel classes_panel = QGroupBox('classes') classes_panel.setMinimumWidth(CLASS_PANEL_MINIMUM_WIDTH) ### layout for adding classes add_classes_layout = QHBoxLayout() add_class_button = QPushButton('Add class',self) add_class_button.clicked.connect(self.click_add_class) self.new_class_text = QLineEdit(self) self.new_class_text.setAlignment(Qt.AlignLeft) add_classes_layout.addWidget(add_class_button) add_classes_layout.addWidget(self.new_class_text) ### layout for class buttons self.class_button_layout = QGridLayout() ### add sub layouts to class panel classes_layout = QVBoxLayout() classes_layout.addLayout(add_classes_layout) classes_layout.addLayout(self.class_button_layout) classes_panel.setLayout(classes_layout) layout.addWidget(classes_panel) ## set widget layout layout.setAlignment(Qt.AlignTop) layout.setSpacing(4) self.setLayout(layout) self.setMaximumHeight(GUI_MAXIMUM_HEIGHT) self.setMaximumWidth(GUI_MAXIMUM_WIDTH) # initialize classes self.classes = [] if initial_classes is not None: for initial_class in initial_classes: self.add_class(initial_class)
class ShortcutEditor(QDialog): """A dialog for entering key sequences.""" def __init__(self, parent, context, name, sequence, shortcuts): super(ShortcutEditor, self).__init__(parent) self._parent = parent self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint) self.context = context self.name = name self.shortcuts = shortcuts self.current_sequence = sequence or _('<None>') self._qsequences = list() self.setup() self.update_warning() @property def new_sequence(self): """Return a string representation of the new key sequence.""" return ', '.join(self._qsequences) @property def new_qsequence(self): """Return the QKeySequence object of the new key sequence.""" return QKeySequence(self.new_sequence) def setup(self): """Setup the ShortcutEditor with the provided arguments.""" # Widgets icon_info = HelperToolButton() icon_info.setIcon(get_std_icon('MessageBoxInformation')) layout_icon_info = QVBoxLayout() layout_icon_info.setContentsMargins(0, 0, 0, 0) layout_icon_info.setSpacing(0) layout_icon_info.addWidget(icon_info) layout_icon_info.addStretch(100) self.label_info = QLabel() self.label_info.setText( _("Press the new shortcut and select 'Ok' to confirm, " "click 'Cancel' to revert to the previous state, " "or use 'Clear' to unbind the command from a shortcut.")) self.label_info.setAlignment(Qt.AlignTop | Qt.AlignLeft) self.label_info.setWordWrap(True) layout_info = QHBoxLayout() layout_info.setContentsMargins(0, 0, 0, 0) layout_info.addLayout(layout_icon_info) layout_info.addWidget(self.label_info) layout_info.setStretch(1, 100) self.label_current_sequence = QLabel(_("Current shortcut:")) self.text_current_sequence = QLabel(self.current_sequence) self.label_new_sequence = QLabel(_("New shortcut:")) self.text_new_sequence = ShortcutLineEdit(self) self.text_new_sequence.setPlaceholderText(_("Press shortcut.")) self.helper_button = HelperToolButton() self.helper_button.setIcon(QIcon()) self.label_warning = QLabel() self.label_warning.setWordWrap(True) self.label_warning.setAlignment(Qt.AlignTop | Qt.AlignLeft) self.button_default = QPushButton(_('Default')) self.button_ok = QPushButton(_('Ok')) self.button_ok.setEnabled(False) self.button_clear = QPushButton(_('Clear')) self.button_cancel = QPushButton(_('Cancel')) button_box = QHBoxLayout() button_box.addWidget(self.button_default) button_box.addStretch(100) button_box.addWidget(self.button_ok) button_box.addWidget(self.button_clear) button_box.addWidget(self.button_cancel) # New Sequence button box self.btn_clear_sequence = create_toolbutton( self, icon=ima.icon('editclear'), tip=_("Clear all entered key sequences"), triggered=self.clear_new_sequence) self.button_back_sequence = create_toolbutton( self, icon=ima.icon('ArrowBack'), tip=_("Remove last key sequence entered"), triggered=self.back_new_sequence) newseq_btnbar = QHBoxLayout() newseq_btnbar.setSpacing(0) newseq_btnbar.setContentsMargins(0, 0, 0, 0) newseq_btnbar.addWidget(self.button_back_sequence) newseq_btnbar.addWidget(self.btn_clear_sequence) # Setup widgets self.setWindowTitle(_('Shortcut: {0}').format(self.name)) self.helper_button.setToolTip('') style = """ QToolButton { margin:1px; border: 0px solid grey; padding:0px; border-radius: 0px; }""" self.helper_button.setStyleSheet(style) icon_info.setToolTip('') icon_info.setStyleSheet(style) # Layout layout_sequence = QGridLayout() layout_sequence.setContentsMargins(0, 0, 0, 0) layout_sequence.addLayout(layout_info, 0, 0, 1, 4) layout_sequence.addItem(QSpacerItem(15, 15), 1, 0, 1, 4) layout_sequence.addWidget(self.label_current_sequence, 2, 0) layout_sequence.addWidget(self.text_current_sequence, 2, 2) layout_sequence.addWidget(self.label_new_sequence, 3, 0) layout_sequence.addWidget(self.helper_button, 3, 1) layout_sequence.addWidget(self.text_new_sequence, 3, 2) layout_sequence.addLayout(newseq_btnbar, 3, 3) layout_sequence.addWidget(self.label_warning, 4, 2, 1, 2) layout_sequence.setColumnStretch(2, 100) layout_sequence.setRowStretch(4, 100) layout = QVBoxLayout(self) layout.addLayout(layout_sequence) layout.addSpacing(10) layout.addLayout(button_box) layout.setSizeConstraint(layout.SetFixedSize) # Signals self.button_ok.clicked.connect(self.accept_override) self.button_clear.clicked.connect(self.unbind_shortcut) self.button_cancel.clicked.connect(self.reject) self.button_default.clicked.connect(self.set_sequence_to_default) # Set all widget to no focus so that we can register <Tab> key # press event. widgets = (self.label_warning, self.helper_button, self.text_new_sequence, self.button_clear, self.button_default, self.button_cancel, self.button_ok, self.btn_clear_sequence, self.button_back_sequence) for w in widgets: w.setFocusPolicy(Qt.NoFocus) w.clearFocus() @Slot() def reject(self): """Slot for rejected signal.""" # Added for spyder-ide/spyder#5426. Due to the focusPolicy of # Qt.NoFocus for the buttons, if the cancel button was clicked without # first setting focus to the button, it would cause a seg fault crash. self.button_cancel.setFocus() super(ShortcutEditor, self).reject() @Slot() def accept(self): """Slot for accepted signal.""" # Added for spyder-ide/spyder#5426. Due to the focusPolicy of # Qt.NoFocus for the buttons, if the cancel button was clicked without # first setting focus to the button, it would cause a seg fault crash. self.button_ok.setFocus() super(ShortcutEditor, self).accept() def event(self, event): """Qt method override.""" # We reroute all ShortcutOverride events to our keyPressEvent and block # any KeyPress and Shortcut event. This allows to register default # Qt shortcuts for which no key press event are emitted. # See spyder-ide/spyder/issues/10786. if event.type() == QEvent.ShortcutOverride: self.keyPressEvent(event) return True elif event.type() in [QEvent.KeyPress, QEvent.Shortcut]: return True else: return super(ShortcutEditor, self).event(event) def keyPressEvent(self, event): """Qt method override.""" event_key = event.key() if not event_key or event_key == Qt.Key_unknown: return if len(self._qsequences) == 4: # QKeySequence accepts a maximum of 4 different sequences. return if event_key in [ Qt.Key_Control, Qt.Key_Shift, Qt.Key_Alt, Qt.Key_Meta ]: # The event corresponds to just and only a special key. return translator = ShortcutTranslator() event_keyseq = translator.keyevent_to_keyseq(event) event_keystr = event_keyseq.toString(QKeySequence.PortableText) self._qsequences.append(event_keystr) self.update_warning() def check_conflicts(self): """Check shortcuts for conflicts.""" conflicts = [] if len(self._qsequences) == 0: return conflicts new_qsequence = self.new_qsequence for shortcut in self.shortcuts: shortcut_qsequence = QKeySequence.fromString(str(shortcut.key)) if shortcut_qsequence.isEmpty(): continue if (shortcut.context, shortcut.name) == (self.context, self.name): continue if shortcut.context in [self.context, '_'] or self.context == '_': if (shortcut_qsequence.matches(new_qsequence) or new_qsequence.matches(shortcut_qsequence)): conflicts.append(shortcut) return conflicts def check_ascii(self): """ Check that all characters in the new sequence are ascii or else the shortcut will not work. """ try: self.new_sequence.encode('ascii') except UnicodeEncodeError: return False else: return True def check_singlekey(self): """Check if the first sub-sequence of the new key sequence is valid.""" if len(self._qsequences) == 0: return True else: keystr = self._qsequences[0] valid_single_keys = (EDITOR_SINGLE_KEYS if self.context == 'editor' else SINGLE_KEYS) if any((m in keystr for m in ('Ctrl', 'Alt', 'Shift', 'Meta'))): return True else: # This means that the the first subsequence is composed of # a single key with no modifier. valid_single_keys = (EDITOR_SINGLE_KEYS if self.context == 'editor' else SINGLE_KEYS) if any((k == keystr for k in valid_single_keys)): return True else: return False def update_warning(self): """Update the warning label, buttons state and sequence text.""" new_qsequence = self.new_qsequence new_sequence = self.new_sequence self.text_new_sequence.setText( new_qsequence.toString(QKeySequence.NativeText)) conflicts = self.check_conflicts() if len(self._qsequences) == 0: warning = SEQUENCE_EMPTY tip = '' icon = QIcon() elif conflicts: warning = SEQUENCE_CONFLICT template = '<p style="margin-bottom: 0.3em">{0}</p>{1}{2}' tip_title = _('This key sequence conflicts with:') tip_body = '' for s in conflicts: tip_body += ' ' * 2 tip_body += ' - {0}: <b>{1}</b><br>'.format(s.context, s.name) tip_body += '<br>' if len(conflicts) == 1: tip_override = _("Press 'Ok' to unbind it and assign it to") else: tip_override = _("Press 'Ok' to unbind them and assign it to") tip_override += ' <b>{}</b>.'.format(self.name) tip = template.format(tip_title, tip_body, tip_override) icon = get_std_icon('MessageBoxWarning') elif new_sequence in BLACKLIST: warning = IN_BLACKLIST tip = _('This key sequence is forbidden.') icon = get_std_icon('MessageBoxWarning') elif self.check_singlekey() is False or self.check_ascii() is False: warning = INVALID_KEY tip = _('This key sequence is invalid.') icon = get_std_icon('MessageBoxWarning') else: warning = NO_WARNING tip = _('This key sequence is valid.') icon = get_std_icon('DialogApplyButton') self.warning = warning self.conflicts = conflicts self.helper_button.setIcon(icon) self.button_ok.setEnabled( self.warning in [NO_WARNING, SEQUENCE_CONFLICT]) self.label_warning.setText(tip) def set_sequence_from_str(self, sequence): """ This is a convenience method to set the new QKeySequence of the shortcut editor from a string. """ self._qsequences = [QKeySequence(s) for s in sequence.split(', ')] self.update_warning() def set_sequence_to_default(self): """Set the new sequence to the default value defined in the config.""" sequence = CONF.get_default('shortcuts', "{}/{}".format(self.context, self.name)) if sequence: self._qsequences = sequence.split(', ') self.update_warning() else: self.unbind_shortcut() def back_new_sequence(self): """Remove the last subsequence from the sequence compound.""" self._qsequences = self._qsequences[:-1] self.update_warning() def clear_new_sequence(self): """Clear the new sequence.""" self._qsequences = [] self.update_warning() def unbind_shortcut(self): """Unbind the shortcut.""" self._qsequences = [] self.accept() def accept_override(self): """Unbind all conflicted shortcuts, and accept the new one""" conflicts = self.check_conflicts() if conflicts: for shortcut in conflicts: shortcut.key = '' self.accept()
class MainMenu(BaseMainMenu): def __init__(self, settings: PartSettings, main_window): super().__init__(settings, main_window) self.settings = settings self.open_btn = QPushButton("Open") self.save_btn = QPushButton("Save") self.advanced_btn = QPushButton("Settings and Measurement") self.mask_manager_btn = QPushButton("Mask manager") self.batch_processing_btn = QPushButton("Batch Processing") layout = QHBoxLayout() # layout.setSpacing(0) layout.setContentsMargins(0, 0, 4, 4) layout.addWidget(self.open_btn) layout.addWidget(self.save_btn) layout.addWidget(self.advanced_btn) layout.addWidget(self.mask_manager_btn) layout.addWidget(self.batch_processing_btn) self.setLayout(layout) self.open_btn.clicked.connect(self.load_data) self.save_btn.clicked.connect(self.save_file) self.advanced_btn.clicked.connect(self.advanced_window_show) self.mask_manager_btn.clicked.connect(self.mask_manager) self.batch_processing_btn.clicked.connect(self.batch_window) self.setFocusPolicy(Qt.StrongFocus) # self.test_btn.clicked.connect(self.test_fun) def resizeEvent(self, event: QResizeEvent): if event.size().width() < 800: self.batch_processing_btn.hide() else: self.batch_processing_btn.show() def keyPressEvent(self, event: QKeyEvent): if event.matches(QKeySequence.Save): self.save_file() elif event.matches(QKeySequence.Open): self.load_data() super().keyPressEvent(event) def save_file(self): base_values = self.settings.get("save_parameters", {}) dial = PSaveDialog( save_dict, system_widget=False, base_values=base_values, settings=self.settings, path=IO_SAVE_DIRECTORY, filter_path="io.save_filter", ) dial.selectFile( os.path.splitext(os.path.basename(self.settings.image_path))[0]) if dial.exec_(): save_location, selected_filter, save_class, values = dial.get_result( ) project_info = self.settings.get_project_info() base_values[selected_filter] = values def exception_hook(exception): if isinstance(exception, ValueError): show_warning("Save error", f"Error during saving\n{exception}") else: raise exception dial2 = ExecuteFunctionDialog( save_class.save, [save_location, project_info, values], exception_hook=exception_hook) dial2.exec_() def mask_manager(self): if self.settings.roi is None: QMessageBox.information(self, "No segmentation", "Cannot create mask without segmentation") return dial = MaskDialog(self.settings) dial.exec_() def load_data(self): def exception_hook(exception): if isinstance(exception, WrongFileTypeException): show_warning( OPEN_ERROR, "No needed files inside archive. Most probably you choose file from segmentation mask", ) else: load_data_exception_hook(exception) try: dial = PLoadDialog(load_functions.load_dict, settings=self.settings, path=OPEN_DIRECTORY, filter_path=OPEN_FILE_FILTER) file_path = self.settings.get(OPEN_FILE, "") if os.path.isfile(file_path): dial.selectFile(file_path) if dial.exec_(): result = dial.get_result() self.settings.set(OPEN_FILE, result.load_location[0]) self.settings.add_last_files(result.load_location, result.load_class.get_name()) dial2 = ExecuteFunctionDialog( result.load_class.load, [result.load_location], { "metadata": { "default_spacing": self.settings.image_spacing } }, exception_hook=exception_hook, ) if dial2.exec_(): result = dial2.get_result() self.set_data(result) except ValueError as e: show_warning("Open error", f"{e}") def batch_window(self): if self.main_window.batch_window is None: self.main_window.batch_window = BatchWindow(self.settings) self.main_window.batch_window.show() elif self.main_window.batch_window.isVisible(): self.main_window.batch_window.activateWindow() else: self.main_window.batch_window.show() def advanced_window_show(self): if self.main_window.advanced_window.isVisible(): self.main_window.advanced_window.activateWindow() else: self.main_window.advanced_window.show()
def setup_page(self): 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 = SimpleCodeEditor(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 self.plain_text_font = self.create_fontgroup( option='font', title=_("Plain text"), fontfilters=QFontComboBox.MonospacedFonts, without_group=True) self.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(self.plain_text_font.fontlabel, 0, 0) fonts_layout.addWidget(self.plain_text_font.fontbox, 0, 1) fonts_layout.addWidget(self.plain_text_font.sizelabel, 0, 2) fonts_layout.addWidget(self.plain_text_font.sizebox, 0, 3) fonts_layout.addWidget(self.rich_text_font.fontlabel, 1, 0) fonts_layout.addWidget(self.rich_text_font.fontbox, 1, 1) fonts_layout.addWidget(self.rich_text_font.sizelabel, 1, 2) fonts_layout.addWidget(self.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()
def __init__(self, *args, **kwargs): super(Arboretum, self).__init__(*args, **kwargs) layout = QVBoxLayout() # add some buttons self.load_button = QPushButton('Load...', self) self.config_button = QPushButton('Configure...', self) self.localize_button = QPushButton('Localize', self) self.track_button = QPushButton('Track', self) self.save_button = QPushButton('Save...', self) # checkboxes self.optimize_checkbox = QCheckBox() self.optimize_checkbox.setChecked(True) # self.use_states_checkbox = QCheckBox() # self.use_states_checkbox.setChecked(True) # combo boxes self.tracking_mode_combobox = QComboBox() for mode in BayesianUpdates: self.tracking_mode_combobox.addItem(mode.name.lower()) default_mode = BayesianUpdates.EXACT self.tracking_mode_combobox.setCurrentIndex(default_mode.value) # # sliders self.search_radius_slider = QSlider(Qt.Horizontal) self.search_radius_slider.setFocusPolicy(Qt.NoFocus) self.search_radius_slider.setMinimum(1) self.search_radius_slider.setMaximum(300) self.search_radius_slider.setSingleStep(1) # self.search_radius_slider.setEnabled(False) # dynamic labels self.config_filename_label = QLabel() self.localizations_label = QLabel() self.tracks_label = QLabel() self.status_label = QLabel() self.search_radius_label = QLabel() self.search_radius_label.setAlignment(Qt.AlignRight) # load/save buttons io_panel = QWidget() io_layout = QHBoxLayout() io_layout.addWidget(self.load_button) io_layout.addWidget(self.save_button) io_panel.setLayout(io_layout) io_panel.setMaximumWidth(GUI_MAXIMUM_WIDTH) layout.addWidget(io_panel) # tracking panel tracking_panel = QGroupBox('tracking') tracking_layout = QGridLayout() tracking_layout.addWidget(QLabel('method: '), 0, 0) tracking_layout.addWidget(self.tracking_mode_combobox, 0, 1) tracking_layout.addWidget(self.search_radius_label, 1, 0) tracking_layout.addWidget(self.search_radius_slider, 1, 1) tracking_layout.addWidget(QLabel('optimize: '), 2, 0) tracking_layout.addWidget(self.optimize_checkbox, 2, 1) tracking_layout.addWidget(self.config_button, 3, 0) tracking_layout.addWidget(self.config_filename_label, 3, 1) tracking_layout.addWidget(self.localize_button, 4, 0) tracking_layout.addWidget(self.localizations_label, 4, 1) tracking_layout.addWidget(self.track_button, 5, 0) tracking_layout.addWidget(self.tracks_label, 5, 1) tracking_layout.setColumnMinimumWidth(1, 150) tracking_layout.setSpacing(4) tracking_panel.setMaximumWidth(GUI_MAXIMUM_WIDTH) tracking_panel.setLayout(tracking_layout) layout.addWidget(tracking_panel) # status panel status_panel = QGroupBox('status') status_layout = QHBoxLayout() status_layout.addWidget(self.status_label) status_panel.setMaximumWidth(GUI_MAXIMUM_WIDTH) status_panel.setLayout(status_layout) layout.addWidget(status_panel) # set the layout layout.setAlignment(Qt.AlignTop) layout.setSpacing(4) self.setLayout(layout) self.setMaximumHeight(GUI_MAXIMUM_HEIGHT) self.setMaximumWidth(GUI_MAXIMUM_WIDTH) # callbacks self.load_button.clicked.connect(self.load_data) self.save_button.clicked.connect(self.export_data) self.config_button.clicked.connect(self.load_config) self.tracking_mode_combobox.currentTextChanged.connect( self._on_mode_change) self.search_radius_slider.valueChanged.connect(self._on_radius_change) self._tracker_state = None self._segmentation = None self._localizations = None self._tracks = None self._btrack_cfg = None self._active_layer = None # TODO(arl): this is the working filename for the dataset self.filename = None self._search_radius = None self._on_mode_change() self.search_radius_slider.setValue(100)
class AppearanceConfigPage(PluginConfigPage): APPLY_CONF_PAGE_SETTINGS = True def setup_page(self): 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 = SimpleCodeEditor(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 self.plain_text_font = self.create_fontgroup( option='font', title=_("Plain text"), fontfilters=QFontComboBox.MonospacedFonts, without_group=True) self.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(self.plain_text_font.fontlabel, 0, 0) fonts_layout.addWidget(self.plain_text_font.fontbox, 0, 1) fonts_layout.addWidget(self.plain_text_font.sizelabel, 0, 2) fonts_layout.addWidget(self.plain_text_font.sizebox, 0, 3) fonts_layout.addWidget(self.rich_text_font.fontlabel, 1, 0) fonts_layout.addWidget(self.rich_text_font.fontbox, 1, 1) fonts_layout.addWidget(self.rich_text_font.sizelabel, 1, 2) fonts_layout.addWidget(self.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() def get_font(self, option): """Return global font used in Spyder.""" return get_font(option=option) def set_font(self, font, option): """Set global font used in Spyder.""" # Update fonts in all plugins set_font(font, option=option) plugins = self.main.widgetlist + self.main.thirdparty_plugins for plugin in plugins: plugin.update_font() def apply_settings(self, options): self.set_option('selected', self.current_scheme) color_scheme = self.get_option('selected') ui_theme = self.get_option('ui_theme') style_sheet = self.main.styleSheet() if ui_theme == 'automatic': if ((not is_dark_font_color(color_scheme) and not style_sheet) or (is_dark_font_color(color_scheme) and style_sheet)): self.changed_options.add('ui_theme') elif 'ui_theme' in self.changed_options: self.changed_options.remove('ui_theme') if 'ui_theme' not in self.changed_options: self.main.editor.apply_plugin_settings(['color_scheme_name']) if self.main.ipyconsole is not None: self.main.ipyconsole.apply_plugin_settings( ['color_scheme_name']) for plugin in self.main.thirdparty_plugins: try: # New API plugin.apply_conf(['color_scheme_name']) except AttributeError: # Old API plugin.apply_plugin_settings(['color_scheme_name']) self.update_combobox() self.update_preview() else: if 'ui_theme' in self.changed_options: if (style_sheet and ui_theme == 'dark' or not style_sheet and ui_theme == 'light'): self.changed_options.remove('ui_theme') if 'ui_theme' not in self.changed_options: self.main.editor.apply_plugin_settings(['color_scheme_name']) if self.main.ipyconsole is not None: self.main.ipyconsole.apply_plugin_settings( ['color_scheme_name']) for plugin in self.main.thirdparty_plugins: try: # New API plugin.apply_conf(['color_scheme_name']) except AttributeError: # Old API plugin.apply_plugin_settings(['color_scheme_name']) self.update_combobox() self.update_preview() qapp = QApplication.instance() if 'windows_style' in options: style_name = self.get_option('windows_style') style = QStyleFactory.create(style_name) if style is not None: style.setProperty('name', style_name) qapp.setStyle(style) if self.main.historylog is not None: self.main.historylog.apply_conf(['color_scheme_name']) # Helpers # ------------------------------------------------------------------------- @property def current_scheme_name(self): return self.schemes_combobox.currentText() @property def current_scheme(self): return self.scheme_choices_dict[self.current_scheme_name] @property def current_scheme_index(self): return self.schemes_combobox.currentIndex() def update_qt_style_combobox(self): """Enable/disable the Qt style combobox.""" if is_dark_interface(): self.style_combobox.setEnabled(False) else: self.style_combobox.setEnabled(True) def update_combobox(self): """Recreates the combobox contents.""" index = self.current_scheme_index self.schemes_combobox.blockSignals(True) names = self.get_option("names") try: names.pop(names.index(u'Custom')) except ValueError: pass custom_names = self.get_option("custom_names", []) # Useful for retrieving the actual data for n in names + custom_names: self.scheme_choices_dict[self.get_option('{0}/name'.format(n))] = n if custom_names: choices = names + [None] + custom_names else: choices = names combobox = self.schemes_combobox combobox.clear() for name in choices: if name is None: continue combobox.addItem(self.get_option('{0}/name'.format(name)), name) if custom_names: combobox.insertSeparator(len(names)) self.schemes_combobox.blockSignals(False) self.schemes_combobox.setCurrentIndex(index) def update_buttons(self): """Updates the enable status of delete and reset buttons.""" current_scheme = self.current_scheme names = self.get_option("names") try: names.pop(names.index(u'Custom')) except ValueError: pass delete_enabled = current_scheme not in names self.delete_button.setEnabled(delete_enabled) self.reset_button.setEnabled(not delete_enabled) def update_preview(self, index=None, scheme_name=None): """ Update the color scheme of the preview editor and adds text. Note ---- 'index' is needed, because this is triggered by a signal that sends the selected index. """ text = ('"""A string"""\n\n' '# A comment\n\n' 'class Foo(object):\n' ' def __init__(self):\n' ' bar = 42\n' ' print(bar)\n') if scheme_name is None: scheme_name = self.current_scheme self.preview_editor.setup_editor( font=get_font(), color_scheme=scheme_name, show_blanks=False, scroll_past_end=False, ) self.preview_editor.set_language('Python') self.preview_editor.set_text(text) # Actions # ------------------------------------------------------------------------- def create_new_scheme(self): """Creates a new color scheme with a custom name.""" names = self.get_option('names') custom_names = self.get_option('custom_names', []) # Get the available number this new color scheme counter = len(custom_names) - 1 custom_index = [int(n.split('-')[-1]) for n in custom_names] for i in range(len(custom_names)): if custom_index[i] != i: counter = i - 1 break custom_name = "custom-{0}".format(counter + 1) # Add the config settings, based on the current one. custom_names.append(custom_name) self.set_option('custom_names', custom_names) for key in syntaxhighlighters.COLOR_SCHEME_KEYS: name = "{0}/{1}".format(custom_name, key) default_name = "{0}/{1}".format(self.current_scheme, key) option = self.get_option(default_name) self.set_option(name, option) self.set_option('{0}/name'.format(custom_name), custom_name) # Now they need to be loaded! how to make a partial load_from_conf? dlg = self.scheme_editor_dialog dlg.add_color_scheme_stack(custom_name, custom=True) dlg.set_scheme(custom_name) self.load_from_conf() if dlg.exec_(): # This is needed to have the custom name updated on the combobox name = dlg.get_scheme_name() self.set_option('{0}/name'.format(custom_name), name) # The +1 is needed because of the separator in the combobox index = (names + custom_names).index(custom_name) + 1 self.update_combobox() self.schemes_combobox.setCurrentIndex(index) else: # Delete the config .... custom_names.remove(custom_name) self.set_option('custom_names', custom_names) dlg.delete_color_scheme_stack(custom_name) def edit_scheme(self): """Edit current scheme.""" dlg = self.scheme_editor_dialog dlg.set_scheme(self.current_scheme) if dlg.exec_(): # Update temp scheme to reflect instant edits on the preview temporal_color_scheme = dlg.get_edited_color_scheme() for key in temporal_color_scheme: option = "temp/{0}".format(key) value = temporal_color_scheme[key] self.set_option(option, value) self.update_preview(scheme_name='temp') def delete_scheme(self): """Deletes the currently selected custom color scheme.""" scheme_name = self.current_scheme answer = QMessageBox.warning( self, _("Warning"), _("Are you sure you want to delete " "this scheme?"), QMessageBox.Yes | QMessageBox.No) if answer == QMessageBox.Yes: # Put the combobox in Spyder by default, when deleting a scheme names = self.get_option('names') self.set_scheme('spyder') self.schemes_combobox.setCurrentIndex(names.index('spyder')) self.set_option('selected', 'spyder') # Delete from custom_names custom_names = self.get_option('custom_names', []) if scheme_name in custom_names: custom_names.remove(scheme_name) self.set_option('custom_names', custom_names) # Delete config options for key in syntaxhighlighters.COLOR_SCHEME_KEYS: option = "{0}/{1}".format(scheme_name, key) CONF.remove_option(self.CONF_SECTION, option) CONF.remove_option(self.CONF_SECTION, "{0}/name".format(scheme_name)) self.update_combobox() self.update_preview() def set_scheme(self, scheme_name): """ Set the current stack in the dialog to the scheme with 'scheme_name'. """ dlg = self.scheme_editor_dialog dlg.set_scheme(scheme_name) @Slot() def reset_to_default(self): """Restore initial values for default color schemes.""" # Checks that this is indeed a default scheme scheme = self.current_scheme names = self.get_option('names') if scheme in names: for key in syntaxhighlighters.COLOR_SCHEME_KEYS: option = "{0}/{1}".format(scheme, key) value = CONF.get_default(self.CONF_SECTION, option) self.set_option(option, value) self.load_from_conf()
class ShearMomentTorqueWindow(PyDialog): """ +-------------------------+ | ShearMomentTorqueWindow | +-------------------------+ | Origin cid x y z | | P2 cid x y z | | z-axis cid x y z | | tol cid x y z | | | | Apply OK Cancel | +-------------------------+ """ def __init__(self, data, win_parent=None): """ Saves the data members from data and performs type checks """ PyDialog.__init__(self, data, win_parent) self._updated_preference = False self._default_font_size = data['font_size'] #self.dim_max = data['dim_max'] self.model_name = data['model_name'] self.cids = data['cids'] self.gpforce = data['gpforce'] #self._origin = data['origin'] #self._p1 = data['origin'] #self._p2 = data['origin'] #self.out_data = data self.plane_color_float, self.plane_color_int = _check_color( data['plane_color']) self.plane_opacity = data['plane_opacity'] self.methods = ['Z-Axis Projection', 'CORD2R'] self.zaxis_methods = ['Global Z', 'Camera Normal', 'Manual'] self._zaxis_method = 0 # Global Z self.setWindowTitle('Shear, Moment, Torque') self.create_widgets() self.create_layout() self.set_connections() self.on_font(self._default_font_size) #self.on_gradient_scale() #self.show() def on_font(self, value=None): """update the font for the current window""" if value is None: value = self.font_size_edit.value() font = QtGui.QFont() font.setPointSize(value) self.setFont(font) def set_font_size(self, font_size): """ Updates the font size of all objects in the PyDialog Parameters ---------- font_size : int the font size """ if self.font_size == font_size: return self.font_size = font_size font = make_font(font_size, is_bold=False) self.setFont(font) self.set_bold_font(font_size) def set_bold_font(self, font_size): """ Updates the font size of all bolded objects in the dialog Parameters ---------- font_size : int the font size """ bold_font = make_font(font_size, is_bold=True) self.additional_params_label.setFont(bold_font) self.case_info_label.setFont(bold_font) self.plane_label.setFont(bold_font) self.location_label.setFont(bold_font) self.cid_label.setFont(bold_font) self.x_label.setFont(bold_font) self.y_label.setFont(bold_font) self.z_label.setFont(bold_font) def create_widgets(self): """creates the display window""" # CORD2R #self.origin_label = QLabel("Origin:") #self.zaxis_label = QLabel("Z Axis:") #self.xz_plane_label = QLabel("XZ Plane:") # Z-Axis Projection self.p1_label = QLabel("Origin:") self.p3_label = QLabel("End:") self.p2_label = QLabel("XZ Plane:") self.p1_label.setToolTip( 'Defines the starting point for the shear, moment, torque plot') self.p3_label.setToolTip( 'Defines the end point for the shear, moment, torque plot') self.p2_label.setToolTip('Defines the XZ plane for the shears/moments') self.zaxis_label = QLabel("Z Axis:") self.method_pulldown = QComboBox() for method in self.methods: self.method_pulldown.addItem(method) self.zaxis_method_pulldown = QComboBox() for method in self.zaxis_methods: self.zaxis_method_pulldown.addItem(method) self.cid_label = QLabel("Coordinate System:") self.p1_cid_pulldown = QComboBox() self.p2_cid_pulldown = QComboBox() self.p3_cid_pulldown = QComboBox() self.zaxis_cid_pulldown = QComboBox() cid_global_str = '0/Global' for cid in sorted(self.cids): if cid == 0: cid_str = cid_global_str else: cid_str = str(cid) #print('cid_str = %r' % cid_str) self.p1_cid_pulldown.addItem(cid_str) self.p2_cid_pulldown.addItem(cid_str) self.p3_cid_pulldown.addItem(cid_str) self.zaxis_cid_pulldown.addItem(cid_str) self.p1_cid_pulldown.setCurrentIndex(0) self.p2_cid_pulldown.setCurrentIndex(0) self.p3_cid_pulldown.setCurrentIndex(0) self.zaxis_cid_pulldown.setCurrentIndex(0) if len(self.cids) == 1: self.p1_cid_pulldown.setEnabled(False) self.p2_cid_pulldown.setEnabled(False) self.p3_cid_pulldown.setEnabled(False) self.zaxis_cid_pulldown.setEnabled(False) #self.p1_cid_pulldown.setItemText(0, cid_str) #self.p2_cid_pulldown.setItemText(0, cid_str) #self.zaxis_cid_pulldown.setItemText(0, cid_str) self.p1_cid_pulldown.setToolTip( 'Defines the coordinate system for Point P1') self.p2_cid_pulldown.setToolTip( 'Defines the coordinate system for Point P2') self.p3_cid_pulldown.setToolTip( 'Defines the coordinate system for Point P3') self.zaxis_cid_pulldown.setToolTip( 'Defines the coordinate system for the Z Axis') self.p1_x_edit = QLineEdit('') self.p1_y_edit = QLineEdit('') self.p1_z_edit = QLineEdit('') self.p2_x_edit = QLineEdit('') self.p2_y_edit = QLineEdit('') self.p2_z_edit = QLineEdit('') self.p3_x_edit = QLineEdit('') self.p3_y_edit = QLineEdit('') self.p3_z_edit = QLineEdit('') self.zaxis_x_edit = QLineEdit('') self.zaxis_y_edit = QLineEdit('') self.zaxis_z_edit = QLineEdit('') self.additional_params_label = QLabel('Plane Parameters:') self.case_info_label = QLabel('Case Info:') self.p2_label = QLabel("XZ Plane:") # Plane Color self.plane_color_label = QLabel("Plane Color:") self.plane_color_edit = QPushButtonColor(self.plane_color_int) self.plane_opacity_label = QLabel("Plane Opacity:") self.plane_opacity_edit = QDoubleSpinBox() self.plane_opacity_edit.setRange(0.1, 1.0) self.plane_opacity_edit.setDecimals(1) self.plane_opacity_edit.setSingleStep(0.1) self.plane_opacity_edit.setValue(self.plane_opacity) self.flip_coord_label = QLabel("Flip Coordinate System:") self.flip_coord_checkbox = QCheckBox() #----------------------------------------------------------------------- self.time_label = QLabel('Time:') if self.gpforce is None: times = ['0.', '0.5', '1.', '1.5', '2.'] time = '0.' else: times = [str(time) for time in self.gpforce._times] time = times[0] self.times_pulldown = make_combo_box(times, time) self.time_label.setEnabled(False) self.times_pulldown.setEnabled(False) #self.node_label = QLabel('Nodes:') #self.node_edit = QNodeEdit(self.win_parent, self.model_name, parent=self.gui, #pick_style='area', tab_to_next=False) #self.element_label = QLabel('Elements:') #self.element_edit = QElementEdit(self.win_parent, self.model_name, parent=self.gui, #pick_style='area', tab_to_next=False) #self.node_element_label = QLabel('Nodes/Elements:') #self.node_element_edit = QLineEdit() #self.node_element_edit.setReadOnly(True) self.nplanes_label = QLabel('Num Planes:') self.nplanes_spinner = QSpinBox() self.nplanes_spinner.setMinimum(2) self.nplanes_spinner.setMaximum(500) self.nplanes_spinner.setValue(20) #----------------------------------------------------------------------- self.method_label = QLabel('Method:') self.plane_label = QLabel('Plane:') self.location_label = QLabel('Location:') self.zaxis_method_label = QLabel('Z-Axis Method:') self.cid_label = QLabel('Coordinate System:') self.x_label = QLabel('X') self.y_label = QLabel('Y') self.z_label = QLabel('Z') #self.location_label.setAlignment(Qt.AlignCenter) self.cid_label.setAlignment(Qt.AlignCenter) self.x_label.setAlignment(Qt.AlignCenter) self.y_label.setAlignment(Qt.AlignCenter) self.z_label.setAlignment(Qt.AlignCenter) self.export_checkbox = QCheckBox() self.csv_label = QLabel('CSV Filename:') self.csv_edit = QLineEdit() self.csv_button = QPushButton('Browse...') self.csv_label.setEnabled(False) self.csv_edit.setEnabled(False) self.csv_button.setEnabled(False) #----------------------------------------------------------------------- # nodes self.add_button = QPushButton('Add') self.remove_button = QPushButton('Remove') # elements self.add2_button = QPushButton('Add') self.remove2_button = QPushButton('Remove') #----------------------------------------------------------------------- # closing self.apply_button = QPushButton('Apply') self.cancel_button = QPushButton('Cancel') self.set_bold_font(self._default_font_size) @property def gui(self): if self.win_parent is None: return None return self.win_parent.parent.gui def create_layout(self): """sets up the window""" grid = self._make_grid_layout() #hbox_csv = QHBoxLayout() grid2 = QGridLayout() #irow = 0 #grid2.addWidget(self.node_label, irow, 0) #grid2.addWidget(self.node_edit, irow, 1) #grid2.addWidget(self.add_button, irow, 2) #grid2.addWidget(self.remove_button, irow, 3) #irow += 1 #grid2.addWidget(self.element_label, irow, 0) #grid2.addWidget(self.element_edit, irow, 1) #grid2.addWidget(self.add2_button, irow, 2) #grid2.addWidget(self.remove2_button, irow, 3) #irow += 1 #grid2.addWidget(self.node_element_label, irow, 0) #grid2.addWidget(self.node_element_edit, irow, 1) #irow += 1 hbox_csv = QHBoxLayout() hbox_csv.addWidget(self.export_checkbox) hbox_csv.addWidget(self.csv_label) hbox_csv.addWidget(self.csv_edit) hbox_csv.addWidget(self.csv_button) #---------------------------------------------- ok_cancel_box = QHBoxLayout() ok_cancel_box.addWidget(self.apply_button) ok_cancel_box.addWidget(self.cancel_button) vbox = QVBoxLayout() vbox.addLayout(grid) vbox.addLayout(grid2) #vbox.addStretch() vbox.addLayout(hbox_csv) vbox.addStretch() #----------------------- #vbox.addLayout(add_remove_box) vbox.addLayout(ok_cancel_box) self.on_method(0) self.on_zaxis_method(0) self.setLayout(vbox) def on_export_checkbox(self): """this is called when the checkbox is clicked""" is_checked = self.export_checkbox.isChecked() self.csv_label.setEnabled(is_checked) self.csv_edit.setEnabled(is_checked) self.csv_button.setEnabled(is_checked) def on_browse_csv(self): """opens a file dialog""" default_dirname = os.getcwd() csv_filename, wildcard = save_file_dialog( self, 'Select the file name for export', default_dirname, wildcard_csv) if not csv_filename: return self.csv_edit.setText(csv_filename) def _make_grid_layout(self): """builds the QGridLayout""" grid = QGridLayout() irow = 0 #------------------------- grid.addWidget(self.location_label, irow, 0) grid.addWidget(self.cid_label, irow, 1) grid.addWidget(self.x_label, irow, 2) grid.addWidget(self.y_label, irow, 3) grid.addWidget(self.z_label, irow, 4) irow += 1 add_row(irow, grid, self.p1_label, self.p1_cid_pulldown, self.p1_x_edit, self.p1_y_edit, self.p1_z_edit) irow += 1 add_row(irow, grid, self.p3_label, self.p3_cid_pulldown, self.p3_x_edit, self.p3_y_edit, self.p3_z_edit) irow += 1 grid.addWidget(self.plane_label, irow, 0) irow += 1 grid.addWidget(self.method_label, irow, 0) grid.addWidget(self.method_pulldown, irow, 1) irow += 1 grid.addWidget(self.zaxis_method_label, irow, 0) grid.addWidget(self.zaxis_method_pulldown, irow, 1) irow += 1 add_row(irow, grid, self.zaxis_label, self.zaxis_cid_pulldown, self.zaxis_x_edit, self.zaxis_y_edit, self.zaxis_z_edit) irow += 1 add_row(irow, grid, self.p2_label, self.p2_cid_pulldown, self.p2_x_edit, self.p2_y_edit, self.p2_z_edit) irow += 1 #----------------------------------------- grid.addWidget(self.case_info_label, irow, 0) irow += 1 grid.addWidget(self.time_label, irow, 0) grid.addWidget(self.times_pulldown, irow, 1) irow += 1 grid.addWidget(self.nplanes_label, irow, 0) grid.addWidget(self.nplanes_spinner, irow, 1) irow += 1 #----------------------------------------- grid.addWidget(self.additional_params_label, irow, 0) irow += 1 grid.addWidget(self.plane_color_label, irow, 0) grid.addWidget(self.plane_color_edit, irow, 1) irow += 1 grid.addWidget(self.plane_opacity_label, irow, 0) grid.addWidget(self.plane_opacity_edit, irow, 1) irow += 1 #---------------------------------------------- return grid def set_connections(self): """creates the actions for the menu""" self.method_pulldown.currentIndexChanged.connect(self.on_method) self.zaxis_method_pulldown.currentIndexChanged.connect( self.on_zaxis_method) self.plane_color_edit.clicked.connect(self.on_plane_color) self.export_checkbox.clicked.connect(self.on_export_checkbox) self.csv_button.clicked.connect(self.on_browse_csv) self.apply_button.clicked.connect(self.on_apply) self.cancel_button.clicked.connect(self.on_cancel) def on_method(self, method_int=None): method = get_pulldown_text(method_int, self.methods, self.method_pulldown) if method == 'Z-Axis Projection': is_cord2r = False elif method == 'CORD2R': is_cord2r = True else: raise NotImplementedError(method) if is_cord2r: self._zaxis_method = self.zaxis_method_pulldown.currentIndex() # set to manual #self.on_zaxis_method(method_int=2) # manual self.zaxis_method_pulldown.setCurrentIndex(2) self.on_zaxis_method() # update else: self.zaxis_method_pulldown.setCurrentIndex(self._zaxis_method) self.on_zaxis_method() # update # works self.zaxis_method_pulldown.setEnabled(not is_cord2r) self.zaxis_method_pulldown.setVisible(not is_cord2r) self.zaxis_method_label.setEnabled(not is_cord2r) def on_zaxis_method(self, method_int=None): method = get_pulldown_text(method_int, self.zaxis_methods, self.zaxis_method_pulldown) if method == 'Global Z': is_visible = False elif method == 'Camera Normal': is_visible = False elif method == 'Manual': is_visible = True else: raise NotImplementedError(method) self.zaxis_cid_pulldown.setVisible(is_visible) self.zaxis_x_edit.setVisible(is_visible) self.zaxis_y_edit.setVisible(is_visible) self.zaxis_z_edit.setVisible(is_visible) def on_plane_color(self): """ Choose a plane color""" title = "Choose a cutting plane color" rgb_color_ints = self.plane_color_int color_edit = self.plane_color_edit func_name = 'set_plane_color' passed, rgb_color_ints, rgb_color_floats = self._background_color( title, color_edit, rgb_color_ints, func_name) if passed: self.plane_color_int = rgb_color_ints self.plane_color_float = rgb_color_floats def _background_color(self, title, color_edit, rgb_color_ints, func_name): """helper method for ``on_background_color`` and ``on_background_color2``""" passed, rgb_color_ints, rgb_color_floats = self.on_color( color_edit, rgb_color_ints, title) if passed and 0: if self.win_parent is not None: settings = self.win_parent.settings func_background_color = getattr(settings, func_name) func_background_color(rgb_color_floats) return passed, rgb_color_ints, rgb_color_floats def on_color(self, color_edit, rgb_color_ints, title): """pops a color dialog""" col = QColorDialog.getColor(QtGui.QColor(*rgb_color_ints), self, title) if not col.isValid(): return False, rgb_color_ints, None color_float = col.getRgbF()[:3] # floats color_int = [int(colori * 255) for colori in color_float] assert isinstance(color_float[0], float), color_float assert isinstance(color_int[0], int), color_int color_edit.setStyleSheet("QPushButton {" "background-color: rgb(%s, %s, %s);" % tuple(color_int) + #"border:1px solid rgb(255, 170, 255); " "}") return True, color_int, color_float #--------------------------------------------------------------------------- def on_validate(self): p1_cidi = self.p1_cid_pulldown.currentText() p2_cidi = self.p2_cid_pulldown.currentText() p3_cidi = self.p3_cid_pulldown.currentText() zaxis_cidi = self.zaxis_cid_pulldown.currentText() p1_cid = int(p1_cidi) if 'Global' not in p1_cidi else 0 p2_cid = int(p2_cidi) if 'Global' not in p2_cidi else 0 p3_cid = int(p3_cidi) if 'Global' not in p3_cidi else 0 zaxis_cid = int(zaxis_cidi) if 'Global' not in zaxis_cidi else 0 #print('p1_cidi=%r p2_cidi=%r p3_cidi=%r' % (p1_cidi, p2_cidi, zaxis_cidi)) #print('p2_cid=%r p2_cid=%r p3_cidi=%r' % (p2_cid, p2_cid, zaxis_cid)) p1_x, flag1 = check_float(self.p1_x_edit) p1_y, flag2 = check_float(self.p1_y_edit) p1_z, flag3 = check_float(self.p1_z_edit) p2_x, flag4 = check_float(self.p2_x_edit) p2_y, flag5 = check_float(self.p2_y_edit) p2_z, flag6 = check_float(self.p2_z_edit) p3_x, flag7 = check_float(self.p3_x_edit) p3_y, flag8 = check_float(self.p3_y_edit) p3_z, flag9 = check_float(self.p3_z_edit) p1 = [p1_x, p1_y, p1_z] p2 = [p2_x, p2_y, p2_z] p3 = [p3_x, p3_y, p3_z] flag10, flag11, flag12, zaxis_cid, zaxis = get_zaxis( self.win_parent, # for camera self.zaxis_method_pulldown, self.zaxis_x_edit, self.zaxis_y_edit, self.zaxis_z_edit) method = self.method_pulldown.currentText() assert method in self.methods, 'method=%r' % method flag13 = True plane_opacity = self.plane_opacity_edit.value() nplanes = self.nplanes_spinner.value() csv_filename = None flag14 = True if self.export_checkbox.isChecked(): csv_filename, flag14 = check_save_path(self.csv_edit) flags = [ flag1, flag2, flag3, flag4, flag5, flag6, flag7, flag8, flag9, flag10, flag11, flag12, flag13, flag14 ] if all(flags): self.out_data['method'] = method self.out_data['p1'] = [p1_cid, p1] self.out_data['p2'] = [p2_cid, p2] self.out_data['p3'] = [p3_cid, p3] self.out_data['zaxis'] = [zaxis_cid, zaxis] self.out_data['plane_color'] = self.plane_color_float self.out_data['plane_opacity'] = plane_opacity self.out_data['nplanes'] = nplanes self.out_data['csv_filename'] = csv_filename self.out_data['clicked_ok'] = True return True return False def on_apply(self): passed = self.on_validate() if passed and self.win_parent is not None: self.win_parent.shear_moment_torque_obj.make_smt_from_data( self.out_data, show=True) #self.win_parent.make_smt_from_data(self.out_data) return passed def on_cancel(self): self.out_data['close'] = True self.close()
def create_widgets(self): """creates the display window""" # CORD2R #self.origin_label = QLabel("Origin:") #self.zaxis_label = QLabel("Z Axis:") #self.xz_plane_label = QLabel("XZ Plane:") # Z-Axis Projection self.p1_label = QLabel("Origin:") self.p3_label = QLabel("End:") self.p2_label = QLabel("XZ Plane:") self.p1_label.setToolTip( 'Defines the starting point for the shear, moment, torque plot') self.p3_label.setToolTip( 'Defines the end point for the shear, moment, torque plot') self.p2_label.setToolTip('Defines the XZ plane for the shears/moments') self.zaxis_label = QLabel("Z Axis:") self.method_pulldown = QComboBox() for method in self.methods: self.method_pulldown.addItem(method) self.zaxis_method_pulldown = QComboBox() for method in self.zaxis_methods: self.zaxis_method_pulldown.addItem(method) self.cid_label = QLabel("Coordinate System:") self.p1_cid_pulldown = QComboBox() self.p2_cid_pulldown = QComboBox() self.p3_cid_pulldown = QComboBox() self.zaxis_cid_pulldown = QComboBox() cid_global_str = '0/Global' for cid in sorted(self.cids): if cid == 0: cid_str = cid_global_str else: cid_str = str(cid) #print('cid_str = %r' % cid_str) self.p1_cid_pulldown.addItem(cid_str) self.p2_cid_pulldown.addItem(cid_str) self.p3_cid_pulldown.addItem(cid_str) self.zaxis_cid_pulldown.addItem(cid_str) self.p1_cid_pulldown.setCurrentIndex(0) self.p2_cid_pulldown.setCurrentIndex(0) self.p3_cid_pulldown.setCurrentIndex(0) self.zaxis_cid_pulldown.setCurrentIndex(0) if len(self.cids) == 1: self.p1_cid_pulldown.setEnabled(False) self.p2_cid_pulldown.setEnabled(False) self.p3_cid_pulldown.setEnabled(False) self.zaxis_cid_pulldown.setEnabled(False) #self.p1_cid_pulldown.setItemText(0, cid_str) #self.p2_cid_pulldown.setItemText(0, cid_str) #self.zaxis_cid_pulldown.setItemText(0, cid_str) self.p1_cid_pulldown.setToolTip( 'Defines the coordinate system for Point P1') self.p2_cid_pulldown.setToolTip( 'Defines the coordinate system for Point P2') self.p3_cid_pulldown.setToolTip( 'Defines the coordinate system for Point P3') self.zaxis_cid_pulldown.setToolTip( 'Defines the coordinate system for the Z Axis') self.p1_x_edit = QLineEdit('') self.p1_y_edit = QLineEdit('') self.p1_z_edit = QLineEdit('') self.p2_x_edit = QLineEdit('') self.p2_y_edit = QLineEdit('') self.p2_z_edit = QLineEdit('') self.p3_x_edit = QLineEdit('') self.p3_y_edit = QLineEdit('') self.p3_z_edit = QLineEdit('') self.zaxis_x_edit = QLineEdit('') self.zaxis_y_edit = QLineEdit('') self.zaxis_z_edit = QLineEdit('') self.additional_params_label = QLabel('Plane Parameters:') self.case_info_label = QLabel('Case Info:') self.p2_label = QLabel("XZ Plane:") # Plane Color self.plane_color_label = QLabel("Plane Color:") self.plane_color_edit = QPushButtonColor(self.plane_color_int) self.plane_opacity_label = QLabel("Plane Opacity:") self.plane_opacity_edit = QDoubleSpinBox() self.plane_opacity_edit.setRange(0.1, 1.0) self.plane_opacity_edit.setDecimals(1) self.plane_opacity_edit.setSingleStep(0.1) self.plane_opacity_edit.setValue(self.plane_opacity) self.flip_coord_label = QLabel("Flip Coordinate System:") self.flip_coord_checkbox = QCheckBox() #----------------------------------------------------------------------- self.time_label = QLabel('Time:') if self.gpforce is None: times = ['0.', '0.5', '1.', '1.5', '2.'] time = '0.' else: times = [str(time) for time in self.gpforce._times] time = times[0] self.times_pulldown = make_combo_box(times, time) self.time_label.setEnabled(False) self.times_pulldown.setEnabled(False) #self.node_label = QLabel('Nodes:') #self.node_edit = QNodeEdit(self.win_parent, self.model_name, parent=self.gui, #pick_style='area', tab_to_next=False) #self.element_label = QLabel('Elements:') #self.element_edit = QElementEdit(self.win_parent, self.model_name, parent=self.gui, #pick_style='area', tab_to_next=False) #self.node_element_label = QLabel('Nodes/Elements:') #self.node_element_edit = QLineEdit() #self.node_element_edit.setReadOnly(True) self.nplanes_label = QLabel('Num Planes:') self.nplanes_spinner = QSpinBox() self.nplanes_spinner.setMinimum(2) self.nplanes_spinner.setMaximum(500) self.nplanes_spinner.setValue(20) #----------------------------------------------------------------------- self.method_label = QLabel('Method:') self.plane_label = QLabel('Plane:') self.location_label = QLabel('Location:') self.zaxis_method_label = QLabel('Z-Axis Method:') self.cid_label = QLabel('Coordinate System:') self.x_label = QLabel('X') self.y_label = QLabel('Y') self.z_label = QLabel('Z') #self.location_label.setAlignment(Qt.AlignCenter) self.cid_label.setAlignment(Qt.AlignCenter) self.x_label.setAlignment(Qt.AlignCenter) self.y_label.setAlignment(Qt.AlignCenter) self.z_label.setAlignment(Qt.AlignCenter) self.export_checkbox = QCheckBox() self.csv_label = QLabel('CSV Filename:') self.csv_edit = QLineEdit() self.csv_button = QPushButton('Browse...') self.csv_label.setEnabled(False) self.csv_edit.setEnabled(False) self.csv_button.setEnabled(False) #----------------------------------------------------------------------- # nodes self.add_button = QPushButton('Add') self.remove_button = QPushButton('Remove') # elements self.add2_button = QPushButton('Add') self.remove2_button = QPushButton('Remove') #----------------------------------------------------------------------- # closing self.apply_button = QPushButton('Apply') self.cancel_button = QPushButton('Cancel') self.set_bold_font(self._default_font_size)
class ContourOptionsDialog(QDialog): """ Dialog box for selecting contour options """ def __init__(self, contour_settings): super(ContourOptionsDialog, self).__init__(contour_settings.cubeviz_layout) self.setWindowFlags(self.windowFlags() | Qt.Tool) self.setWindowTitle("Contour Options") self.is_preview_active = False # preview mode? self.contour_settings = contour_settings # ref to caller ContourSettings self.image_viewer = self.contour_settings.image_viewer # ref to image viewer self.options = self.contour_settings.options # ref to ContourSettings options self._colormap_members = self.contour_settings.colormap_members # Colormap options self._colormap_index = DEFAULT_GLUE_COLORMAP_INDEX # Currently selected colormap if "cmap" in self.options: if self.options["cmap"] in self._colormap_members: self._colormap_index = self._colormap_members.index( self.options["cmap"]) # Is there a user spacing? if self.contour_settings.spacing is None: self.is_custom_spacing = False else: self.is_custom_spacing = True # Is there a user min? if self.contour_settings.vmin is None: self.is_vmin = False else: self.is_vmin = True # Is there a user max? if self.contour_settings.vmax is None: self.is_vmax = False else: self.is_vmax = True self.add_contour_label = self.contour_settings.add_contour_label # bool self._init_ui() def _init_ui(self): # Line 1: Color map self.colormap_label = QLabel("Color Scheme: ") self.colormap_combo = QColormapCombo() self.colormap_combo.addItem("", userData=cm.viridis) self.colormap_combo._update_icons() self.colormap_combo.setCurrentIndex(self._colormap_index) self.colormap_combo.setMaximumWidth(150) self.colormap_combo.currentIndexChanged.connect( self._on_colormap_change) # hbl is short for Horizontal Box Layout hbl1 = QHBoxLayout() hbl1.addWidget(self.colormap_label) hbl1.addWidget(self.colormap_combo) # Line 2: Display contour labels self.contour_label_checkBox = QCheckBox("Contour labels (font size):") if self.contour_settings.add_contour_label: self.contour_label_checkBox.setChecked(True) self.contour_label_checkBox.toggled.connect(self.toggle_labels) font_string = str(self.contour_settings.font_size) self.font_size_input = QLineEdit(font_string) self.font_size_input.setFixedWidth(150) self.font_size_input.setDisabled( not self.contour_settings.add_contour_label) hbl2 = QHBoxLayout() hbl2.addWidget(self.contour_label_checkBox) hbl2.addWidget(self.font_size_input) # Line 3: Contour Spacing self.custom_spacing_checkBox = QCheckBox("Contour spacing (interval):") if self.is_custom_spacing: self.custom_spacing_checkBox.setChecked(True) self.custom_spacing_checkBox.toggled.connect(self.custom_spacing) self.spacing_input = QLineEdit() self.spacing_input.setFixedWidth(150) self.spacing_input.setDisabled(not self.is_custom_spacing) spacing = "" if self.is_custom_spacing: spacing = str(self.contour_settings.spacing) elif self.contour_settings.data_spacing is not None: spacing = self.contour_settings.data_spacing spacing = "{0:1.4f}".format(spacing) self.spacing_default_text = spacing self.spacing_input.setText(spacing) hbl3 = QHBoxLayout() hbl3.addWidget(self.custom_spacing_checkBox) hbl3.addWidget(self.spacing_input) # Line 4: Vmax self.vmax_checkBox = QCheckBox("Set max:") self.vmax_input = QLineEdit() self.vmax_input.setFixedWidth(150) self.vmax_input.setDisabled(not self.is_vmax) vmax = "" if self.is_vmax: self.vmax_checkBox.setChecked(True) vmax = str(self.contour_settings.vmax) elif self.contour_settings.data_max is not None: vmax = self.contour_settings.data_max vmax = "{0:1.4f}".format(vmax) self.vmax_input.setText(vmax) self.vmax_default_text = vmax self.vmax_checkBox.toggled.connect(self.toggle_vmax) hbl4 = QHBoxLayout() hbl4.addWidget(self.vmax_checkBox) hbl4.addWidget(self.vmax_input) # Line 5: Vmin self.vmin_checkBox = QCheckBox("Set min:") self.vmin_input = QLineEdit() self.vmin_input.setFixedWidth(150) self.vmin_input.setDisabled(not self.is_vmin) vmin = "" if self.is_vmin: self.vmin_checkBox.setChecked(True) vmin = str(self.contour_settings.vmin) elif self.contour_settings.data_min is not None: vmin = self.contour_settings.data_min vmin = "{0:1.4f}".format(vmin) self.vmin_input.setText(vmin) self.vmin_default_text = vmin self.vmin_checkBox.toggled.connect(self.toggle_vmin) hbl5 = QHBoxLayout() hbl5.addWidget(self.vmin_checkBox) hbl5.addWidget(self.vmin_input) # Line f: self.previewButton = QPushButton("Preview") self.previewButton.clicked.connect(self.preview) self.defaultButton = QPushButton("Reset") self.defaultButton.clicked.connect(self.default) self.okButton = QPushButton("OK") self.okButton.clicked.connect(self.finish) self.okButton.setDefault(True) self.cancelButton = QPushButton("Cancel") self.cancelButton.clicked.connect(self.cancel) hblf = QHBoxLayout() hblf.addStretch(1) hblf.addWidget(self.previewButton) hblf.addWidget(self.defaultButton) hblf.addWidget(self.cancelButton) hblf.addWidget(self.okButton) vbl = QVBoxLayout() vbl.addLayout(hbl1) vbl.addLayout(hbl2) vbl.addLayout(hbl3) vbl.addLayout(hbl4) vbl.addLayout(hbl5) vbl.addLayout(hblf) self.setLayout(vbl) self.show() def update_data_vals(self, vmin="", vmax="", spacing="1"): self.vmin_default_text = vmin if not self.is_vmin: self.vmin_input.setText(vmin) self.vmax_default_text = vmax if not self.is_vmax: self.vmax_input.setText(vmax) self.spacing_default_text = spacing if not self.is_custom_spacing: self.spacing_input.setText(spacing) def _on_colormap_change(self, index): """Combo index changed handler""" self._colormap_index = index def custom_spacing(self): """Checkbox toggled handler""" if self.is_custom_spacing: self.is_custom_spacing = False self.spacing_input.setDisabled(True) spacing = "" if self.contour_settings.data_spacing: spacing = self.contour_settings.data_spacing spacing = "{0:1.4f}".format(spacing) self.spacing_input.setText(spacing) self.spacing_input.setStyleSheet("") else: self.is_custom_spacing = True self.spacing_input.setDisabled(False) def toggle_labels(self): """Checkbox toggled handler""" if self.add_contour_label: self.add_contour_label = False self.font_size_input.setDisabled(True) font_string = str(self.contour_settings.font_size) self.font_size_input.setText(font_string) self.font_size_input.setStyleSheet("") else: self.add_contour_label = True self.font_size_input.setDisabled(False) def toggle_vmax(self): """Checkbox toggled handler""" if self.is_vmax: self.is_vmax = False self.vmax_input.setDisabled(True) vmax = "" if self.contour_settings.data_max: vmax = self.contour_settings.data_max vmax = "{0:1.4f}".format(vmax) self.vmax_input.setText(vmax) self.vmax_input.setStyleSheet("") else: self.is_vmax = True self.vmax_input.setDisabled(False) def toggle_vmin(self): """Checkbox toggled handler""" if self.is_vmin: self.is_vmin = False self.vmin_input.setDisabled(True) vmin = "" if self.contour_settings.data_min: vmin = self.contour_settings.data_min vmin = "{0:1.4f}".format(vmin) self.vmin_input.setText(vmin) self.vmin_input.setStyleSheet("") else: self.is_vmin = True self.vmin_input.setDisabled(False) def input_validation(self): red = "background-color: rgba(255, 0, 0, 128);" def float_check(min_val=None): if user_input.text() == "": user_input.setStyleSheet(red) return False else: try: value = float(user_input.text()) if min_val is not None: if value <= min_val: user_input.setStyleSheet(red) return False else: user_input.setStyleSheet("") except ValueError: user_input.setStyleSheet(red) return False return True def int_check(min_val=None): if user_input.text() == "": user_input.setStyleSheet(red) return False else: try: value = int(user_input.text()) if min_val is not None: if value <= min_val: user_input.setStyleSheet(red) return False else: user_input.setStyleSheet("") except ValueError: user_input.setStyleSheet(red) return False return True success = True # Check 1: spacing_input if self.is_custom_spacing: user_input = self.spacing_input float_check(0) success = success and float_check() # Check 2: font_size_input if self.add_contour_label: user_input = self.font_size_input int_check(0) success = success and int_check() # Check 3: vmax if self.is_vmax: user_input = self.vmax_input float_check() success = success and float_check() # Check 4: vmax if self.is_vmin: user_input = self.vmin_input float_check() success = success and float_check() # Check 5: vmax and vmin if self.is_vmax and self.is_vmin and success: vmax = float(self.vmax_input.text()) vmin = float(self.vmin_input.text()) if vmax <= vmin: self.vmax_input.setStyleSheet(red) self.vmin_input.setStyleSheet(red) success = False return success def finish(self): """ Ok button pressed. Finalize options and send to image viewer """ success = self.input_validation() if not success: return # Change Color Map self._colormap_index = self.colormap_combo.currentIndex() colormap = self._colormap_members[self._colormap_index] self.contour_settings.options["cmap"] = colormap # labels self.contour_settings.add_contour_label = self.add_contour_label # font size if self.add_contour_label: font_size = int(self.font_size_input.text()) self.contour_settings.font_size = font_size else: self.contour_settings.font_size = DEFAULT_CONTOUR_FONT_SIZE # Spacing if self.is_custom_spacing: self.contour_settings.spacing = float(self.spacing_input.text()) else: self.contour_settings.spacing = None # vmax if self.is_vmax: vmax = float(self.vmax_input.text()) self.contour_settings.vmax = vmax self.contour_settings.options["vmax"] = vmax else: self.contour_settings.vmax = None self.contour_settings.options["vmax"] = None # vmin if self.is_vmin: vmin = float(self.vmin_input.text()) self.contour_settings.vmin = vmin self.contour_settings.options["vmin"] = vmin else: self.contour_settings.vmin = None self.contour_settings.options["vmin"] = None # Redraw contour if self.contour_settings.image_viewer.is_contour_active: self.contour_settings.draw_function() self.close() def preview(self): """ Prepare preview contour settings and send to image viewer """ success = self.input_validation() if not success: return image_viewer = self.contour_settings.image_viewer preview_settings = ContourSettings(image_viewer) preview_settings.dialog = self preview_settings.options = self.contour_settings.options.copy() preview_settings.spacing = self.contour_settings.spacing # Change Color Map self._colormap_index = self.colormap_combo.currentIndex() colormap = self._colormap_members[self._colormap_index] preview_settings.options["cmap"] = colormap # labels add_contour_label = self.contour_label_checkBox.isChecked() preview_settings.add_contour_label = add_contour_label # font size if add_contour_label: font_size = int(self.font_size_input.text()) preview_settings.font_size = font_size # Spacing if self.is_custom_spacing: preview_settings.spacing = float(self.spacing_input.text()) else: preview_settings.spacing = None # vmax if self.is_vmax: vmax = float(self.vmax_input.text()) preview_settings.vmax = vmax preview_settings.options["vmax"] = vmax else: preview_settings.vmax = None preview_settings.options["vmax"] = None # vmin if self.is_vmin: vmin = float(self.vmin_input.text()) preview_settings.vmin = vmin preview_settings.options["vmin"] = vmin else: preview_settings.vmin = None preview_settings.options["vmin"] = None # Redraw contour if image_viewer.is_contour_active: self.is_preview_active = True image_viewer.set_contour_preview(preview_settings) else: message = "Contour map is currently switched off. " \ "Please turn on the contour map by selecting " \ "a component from the contour map drop-down menu." info = QMessageBox.critical(self, "Error", message) def default(self): """ Set options back to default and send to image viewer """ self.contour_settings.options = self.contour_settings.default_options() self.contour_settings.spacing = None self.contour_settings.font_size = DEFAULT_CONTOUR_FONT_SIZE self.contour_settings.vmax = None self.contour_settings.vmin = None self.contour_settings.add_contour_label = False if self.contour_settings.image_viewer.is_contour_active: self.contour_settings.draw_function() self.contour_settings.options_dialog() def cancel(self): if self.contour_settings.image_viewer.is_contour_active: self.contour_settings.draw_function() self.close() def closeEvent(self, event): """closeEvent handler""" if self.is_preview_active: self.contour_settings.image_viewer.end_contour_preview() def keyPressEvent(self, e): if e.key() == Qt.Key_Escape: self.cancel()
def __init__(self, parent=None, is_report=False): QDialog.__init__(self, parent) self.is_report = is_report self.setWindowTitle(_("Issue reporter")) self.setModal(True) # To save the traceback sent to the internal console self.error_traceback = "" # Dialog main label if self.is_report: title = _("Please fill the following information") else: title = _("Spyder has encountered an internal problem!") main_label = QLabel( _("<h3>{title}</h3>" "Before reporting this problem, <i>please</i> consult our " "comprehensive " "<b><a href=\"{trouble_url}\">Troubleshooting Guide</a></b> " "which should help solve most issues, and search for " "<b><a href=\"{project_url}\">known bugs</a></b> " "matching your error message or problem description for a " "quicker solution.").format(title=title, trouble_url=__trouble_url__, project_url=__project_url__)) main_label.setOpenExternalLinks(True) main_label.setWordWrap(True) main_label.setAlignment(Qt.AlignJustify) main_label.setStyleSheet('font-size: 12px;') # Issue title self.title = QLineEdit() self.title.textChanged.connect(self._contents_changed) self.title_chars_label = QLabel( _("{} more characters " "to go...").format(TITLE_MIN_CHARS)) form_layout = QFormLayout() red_asterisk = '<font color="Red">*</font>' title_label = QLabel(_("<b>Title</b>: {}").format(red_asterisk)) form_layout.setWidget(0, QFormLayout.LabelRole, title_label) form_layout.setWidget(0, QFormLayout.FieldRole, self.title) # Description steps_header = QLabel( _("<b>Steps to reproduce:</b> {}").format(red_asterisk)) steps_text = QLabel( _("Please enter a detailed step-by-step " "description (in English) of what led up to " "the problem below. Issue reports without a " "clear way to reproduce them will be closed.")) steps_text.setWordWrap(True) steps_text.setAlignment(Qt.AlignJustify) steps_text.setStyleSheet('font-size: 12px;') # Field to input the description of the problem self.input_description = DescriptionWidget(self) # Only allow to submit to Github if we have a long enough description self.input_description.textChanged.connect(self._contents_changed) # Widget to show errors self.details = ShowErrorWidget(self) self.details.set_pythonshell_font(get_font()) self.details.hide() # Label to show missing chars self.initial_chars = len(self.input_description.toPlainText()) self.desc_chars_label = QLabel( _("{} more characters " "to go...").format(DESC_MIN_CHARS)) # Checkbox to dismiss future errors self.dismiss_box = QCheckBox( _("Hide all future errors during this " "session")) if self.is_report: self.dismiss_box.hide() # Dialog buttons gh_icon = ima.icon('github') self.submit_btn = QPushButton(gh_icon, _('Submit to Github')) self.submit_btn.setEnabled(False) self.submit_btn.clicked.connect(self._submit_to_github) self.details_btn = QPushButton(_('Show details')) self.details_btn.clicked.connect(self._show_details) if self.is_report: self.details_btn.hide() self.close_btn = QPushButton(_('Close')) if self.is_report: self.close_btn.clicked.connect(self.reject) # Buttons layout buttons_layout = QHBoxLayout() buttons_layout.addWidget(self.submit_btn) buttons_layout.addWidget(self.details_btn) buttons_layout.addWidget(self.close_btn) # Main layout layout = QVBoxLayout() layout.addWidget(main_label) layout.addSpacing(20) layout.addLayout(form_layout) layout.addWidget(self.title_chars_label) layout.addSpacing(12) layout.addWidget(steps_header) layout.addSpacing(-1) layout.addWidget(steps_text) layout.addSpacing(1) layout.addWidget(self.input_description) layout.addWidget(self.details) layout.addWidget(self.desc_chars_label) layout.addSpacing(15) layout.addWidget(self.dismiss_box) layout.addSpacing(15) layout.addLayout(buttons_layout) layout.setContentsMargins(25, 20, 25, 10) self.setLayout(layout) self.resize(570, 600) self.title.setFocus() # Set Tab key focus order self.setTabOrder(self.title, self.input_description)
def __init__(self, parent, text, title=None, icon=None, contents_title=None, varname=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) if title is None: title = _("Import wizard") self.setWindowTitle(title) if icon is None: self.setWindowIcon(ima.icon('fileimport')) if contents_title is None: contents_title = _("Raw text") if varname is None: varname = _("variable_name") self.var_name, self.clip_data = None, None # Setting GUI self.tab_widget = QTabWidget(self) self.text_widget = ContentsWidget(self, text) self.table_widget = PreviewWidget(self) self.tab_widget.addTab(self.text_widget, _("text")) self.tab_widget.setTabText(0, contents_title) self.tab_widget.addTab(self.table_widget, _("table")) self.tab_widget.setTabText(1, _("Preview")) self.tab_widget.setTabEnabled(1, False) name_layout = QHBoxLayout() name_label = QLabel(_("Variable Name")) name_layout.addWidget(name_label) self.name_edt = QLineEdit() self.name_edt.setText(varname) name_layout.addWidget(self.name_edt) btns_layout = QHBoxLayout() cancel_btn = QPushButton(_("Cancel")) btns_layout.addWidget(cancel_btn) cancel_btn.clicked.connect(self.reject) h_spacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) btns_layout.addItem(h_spacer) self.back_btn = QPushButton(_("Previous")) self.back_btn.setEnabled(False) btns_layout.addWidget(self.back_btn) self.back_btn.clicked.connect(ft_partial(self._set_step, step=-1)) self.fwd_btn = QPushButton(_("Next")) if not text: self.fwd_btn.setEnabled(False) btns_layout.addWidget(self.fwd_btn) self.fwd_btn.clicked.connect(ft_partial(self._set_step, step=1)) self.done_btn = QPushButton(_("Done")) self.done_btn.setEnabled(False) btns_layout.addWidget(self.done_btn) self.done_btn.clicked.connect(self.process) self.text_widget.asDataChanged.connect(self.fwd_btn.setEnabled) self.text_widget.asDataChanged.connect(self.done_btn.setDisabled) layout = QVBoxLayout() layout.addLayout(name_layout) layout.addWidget(self.tab_widget) layout.addLayout(btns_layout) self.setLayout(layout)
class SpyderErrorDialog(QDialog): """Custom error dialog for error reporting.""" def __init__(self, parent=None, is_report=False): QDialog.__init__(self, parent) self.is_report = is_report self.setWindowTitle(_("Issue reporter")) self.setModal(True) # To save the traceback sent to the internal console self.error_traceback = "" # Dialog main label if self.is_report: title = _("Please fill the following information") else: title = _("Spyder has encountered an internal problem!") main_label = QLabel( _("<h3>{title}</h3>" "Before reporting this problem, <i>please</i> consult our " "comprehensive " "<b><a href=\"{trouble_url}\">Troubleshooting Guide</a></b> " "which should help solve most issues, and search for " "<b><a href=\"{project_url}\">known bugs</a></b> " "matching your error message or problem description for a " "quicker solution.").format(title=title, trouble_url=__trouble_url__, project_url=__project_url__)) main_label.setOpenExternalLinks(True) main_label.setWordWrap(True) main_label.setAlignment(Qt.AlignJustify) main_label.setStyleSheet('font-size: 12px;') # Issue title self.title = QLineEdit() self.title.textChanged.connect(self._contents_changed) self.title_chars_label = QLabel( _("{} more characters " "to go...").format(TITLE_MIN_CHARS)) form_layout = QFormLayout() red_asterisk = '<font color="Red">*</font>' title_label = QLabel(_("<b>Title</b>: {}").format(red_asterisk)) form_layout.setWidget(0, QFormLayout.LabelRole, title_label) form_layout.setWidget(0, QFormLayout.FieldRole, self.title) # Description steps_header = QLabel( _("<b>Steps to reproduce:</b> {}").format(red_asterisk)) steps_text = QLabel( _("Please enter a detailed step-by-step " "description (in English) of what led up to " "the problem below. Issue reports without a " "clear way to reproduce them will be closed.")) steps_text.setWordWrap(True) steps_text.setAlignment(Qt.AlignJustify) steps_text.setStyleSheet('font-size: 12px;') # Field to input the description of the problem self.input_description = DescriptionWidget(self) # Only allow to submit to Github if we have a long enough description self.input_description.textChanged.connect(self._contents_changed) # Widget to show errors self.details = ShowErrorWidget(self) self.details.set_pythonshell_font(get_font()) self.details.hide() # Label to show missing chars self.initial_chars = len(self.input_description.toPlainText()) self.desc_chars_label = QLabel( _("{} more characters " "to go...").format(DESC_MIN_CHARS)) # Checkbox to dismiss future errors self.dismiss_box = QCheckBox( _("Hide all future errors during this " "session")) if self.is_report: self.dismiss_box.hide() # Dialog buttons gh_icon = ima.icon('github') self.submit_btn = QPushButton(gh_icon, _('Submit to Github')) self.submit_btn.setEnabled(False) self.submit_btn.clicked.connect(self._submit_to_github) self.details_btn = QPushButton(_('Show details')) self.details_btn.clicked.connect(self._show_details) if self.is_report: self.details_btn.hide() self.close_btn = QPushButton(_('Close')) if self.is_report: self.close_btn.clicked.connect(self.reject) # Buttons layout buttons_layout = QHBoxLayout() buttons_layout.addWidget(self.submit_btn) buttons_layout.addWidget(self.details_btn) buttons_layout.addWidget(self.close_btn) # Main layout layout = QVBoxLayout() layout.addWidget(main_label) layout.addSpacing(20) layout.addLayout(form_layout) layout.addWidget(self.title_chars_label) layout.addSpacing(12) layout.addWidget(steps_header) layout.addSpacing(-1) layout.addWidget(steps_text) layout.addSpacing(1) layout.addWidget(self.input_description) layout.addWidget(self.details) layout.addWidget(self.desc_chars_label) layout.addSpacing(15) layout.addWidget(self.dismiss_box) layout.addSpacing(15) layout.addLayout(buttons_layout) layout.setContentsMargins(25, 20, 25, 10) self.setLayout(layout) self.resize(570, 600) self.title.setFocus() # Set Tab key focus order self.setTabOrder(self.title, self.input_description) def _submit_to_github(self): """Action to take when pressing the submit button.""" # Get reference to the main window if self.parent() is not None: if getattr(self.parent(), 'main', False): # This covers the case when the dialog is attached # to the internal console main = self.parent().main else: # Else the dialog is attached to the main window # directly main = self.parent() else: main = None # Getting description and traceback title = self.title.text() description = self.input_description.toPlainText() traceback = self.error_traceback[:-1] # Remove last EOL # Render issue if main is not None: issue_text = main.render_issue(description=description, traceback=traceback) else: issue_text = description try: if main is None: org = 'ccordoba12' else: org = 'spyder-ide' github_backend = GithubBackend(org, 'spyder') github_report = github_backend.send_report(title, issue_text) if github_report: self.close() except Exception: ret = QMessageBox.question( self, _('Error'), _("An error occurred while trying to send the issue to " "Github automatically. Would you like to open it " "manually?<br><br>" "If so, please make sure to paste your clipboard " "into the issue report box that will appear in a new " "browser tab before clicking <i>Submit</i> on that " "page.")) if ret in [QMessageBox.Yes, QMessageBox.Ok]: QApplication.clipboard().setText(issue_text) issue_body = ( " \n<!--- *** BEFORE SUBMITTING: PASTE CLIPBOARD HERE " "TO COMPLETE YOUR REPORT *** ---!>\n") if main is not None: main.report_issue(body=issue_body, title=title, open_webpage=True) else: pass def append_traceback(self, text): """Append text to the traceback, to be displayed in details.""" self.error_traceback += text def _show_details(self): """Show traceback on its own dialog""" if self.details.isVisible(): self.details.hide() self.details_btn.setText(_('Show details')) else: self.resize(570, 700) self.details.document().setPlainText('') self.details.append_text_to_shell(self.error_traceback, error=True, prompt=False) self.details.show() self.details_btn.setText(_('Hide details')) def _contents_changed(self): """Activate submit_btn.""" desc_chars = (len(self.input_description.toPlainText()) - self.initial_chars) if desc_chars < DESC_MIN_CHARS: self.desc_chars_label.setText(u"{} {}".format( DESC_MIN_CHARS - desc_chars, _("more characters to go..."))) else: self.desc_chars_label.setText(_("Description complete; thanks!")) title_chars = len(self.title.text()) if title_chars < TITLE_MIN_CHARS: self.title_chars_label.setText(u"{} {}".format( TITLE_MIN_CHARS - title_chars, _("more characters to go..."))) else: self.title_chars_label.setText(_("Title complete; thanks!")) submission_enabled = (desc_chars >= DESC_MIN_CHARS and title_chars >= TITLE_MIN_CHARS) self.submit_btn.setEnabled(submission_enabled)
class QtCustomTitleBar(QLabel): """A widget to be used as the titleBar in the QtViewerDockWidget. Keeps vertical size minimal, has a hand cursor and styles (in stylesheet) for hover. Close and float buttons. Parameters ---------- parent : QDockWidget The QtViewerDockWidget to which this titlebar belongs vertical : bool Whether this titlebar is oriented vertically or not. """ def __init__(self, parent, vertical=False): super().__init__(parent) self.setObjectName("QtCustomTitleBar") self.setProperty('vertical', str(vertical)) self.vertical = vertical self.setToolTip('drag to move. double-click to float') line = QFrame(self) line.setObjectName("QtCustomTitleBarLine") self.close_button = QPushButton(self) self.close_button.setToolTip('hide this panel') self.close_button.setObjectName("QTitleBarCloseButton") self.close_button.setCursor(Qt.ArrowCursor) self.close_button.clicked.connect( lambda: self.parent().toggleViewAction().trigger()) self.float_button = QPushButton(self) self.float_button.setToolTip('float this panel') self.float_button.setObjectName("QTitleBarFloatButton") self.float_button.setCursor(Qt.ArrowCursor) self.float_button.clicked.connect( lambda: self.parent().setFloating(not self.parent().isFloating())) if vertical: layout = QVBoxLayout() layout.setSpacing(4) layout.setContentsMargins(0, 8, 0, 8) line.setFixedWidth(1) layout.addWidget(self.close_button, 0, Qt.AlignHCenter) layout.addWidget(self.float_button, 0, Qt.AlignHCenter) layout.addWidget(line, 0, Qt.AlignHCenter) else: layout = QHBoxLayout() layout.setSpacing(4) layout.setContentsMargins(8, 1, 8, 0) line.setFixedHeight(1) layout.addWidget(self.close_button) layout.addWidget(self.float_button) layout.addWidget(line) self.setLayout(layout) self.setCursor(Qt.OpenHandCursor) def sizeHint(self): # this seems to be the correct way to set the height of the titlebar szh = super().sizeHint() if self.vertical: szh.setWidth(20) else: szh.setHeight(20) return szh
def __init__( self, settings: PartSettings, channel_control2: ChannelProperty, left_image: ResultImageView, synchronize: SynchronizeView, ): super().__init__() self._settings = settings self.left_panel = left_image self._ch_control2 = channel_control2 self.synchronize_val = False self.hide_left_panel_chk = QCheckBox("Hide left panel") self.hide_left_panel_chk.stateChanged.connect(self.hide_left_panel) self.synchronize_checkbox = QCheckBox("Synchronize view") self.synchronize_checkbox.stateChanged.connect( synchronize.set_synchronize) self.interactive_use = QCheckBox("Interactive use") self.execute_btn = QPushButton("Execute") self.execute_btn.clicked.connect(self.execute_algorithm) self.execute_btn.setStyleSheet("QPushButton{font-weight: bold;}") self.save_pipe_btn = QPushButton("Save pipeline") self.save_pipe_btn.clicked.connect(self.save_pipeline) self.save_pipe_btn.setToolTip( "Save current pipeline. Last element is last executed algorithm") self.choose_pipe = SearchComboBox() self.choose_pipe.addItem("<none>") # self.choose_pipe.addItems(list(self._settings.roi_pipelines.keys())) self.choose_pipe.textActivated.connect(self.choose_pipeline) self.choose_pipe.setToolTip("Execute chosen pipeline") self.save_profile_btn = QPushButton("Save profile") self.save_profile_btn.setToolTip("Save values from current view") self.save_profile_btn.clicked.connect(self.save_profile) self.choose_profile = SearchComboBox() self.choose_profile.addItem("<none>") # self.choose_profile.addItems(list(self._settings.roi_profiles.keys())) self.choose_profile.setToolTip( "Select profile to restore its settings. Execute if interactive is checked" ) # image state self.compare_btn = QPushButton("Compare") self.compare_btn.setDisabled(True) self.compare_btn.clicked.connect(self.compare_action) left_image.hide_signal.connect(self.compare_btn.setHidden) self.update_tooltips() self.choose_profile.textActivated.connect(self.change_profile) self.interactive_use.stateChanged.connect(self.execute_btn.setDisabled) self.interactive_use.stateChanged.connect(self.interactive_change) self.algorithm_choose_widget = AlgorithmChoose( settings, algorithm_description.analysis_algorithm_dict) self.algorithm_choose_widget.result.connect(self.execution_done) self.algorithm_choose_widget.finished.connect( self.calculation_finished) self.algorithm_choose_widget.value_changed.connect( self.interactive_algorithm_execute) self.algorithm_choose_widget.algorithm_changed.connect( self.interactive_algorithm_execute) self._settings.roi_profiles_changed.connect(self._update_profiles) self._settings.roi_pipelines_changed.connect(self._update_pipelines) self._update_pipelines() self._update_profiles() self.label = TextShow() layout = QVBoxLayout() layout2 = QHBoxLayout() layout2.setSpacing(1) layout2.setContentsMargins(0, 0, 0, 0) layout3 = QHBoxLayout() layout3.setContentsMargins(0, 0, 0, 0) layout.setContentsMargins(0, 0, 0, 0) layout5 = QHBoxLayout() layout5.setContentsMargins(0, 0, 0, 0) layout5.addWidget(self.save_pipe_btn) layout5.addWidget(self.choose_pipe) layout4 = QHBoxLayout() layout4.setContentsMargins(0, 0, 0, 0) layout4.addWidget(self.save_profile_btn) layout4.addWidget(self.choose_profile) layout3.addWidget(self.interactive_use) layout3.addWidget(self.execute_btn) layout.addLayout(layout5) layout.addLayout(layout4) layout.addLayout(layout3) layout.addWidget(self.algorithm_choose_widget, 1) # layout.addLayout(self.stack_layout) layout.addWidget(self.label) # layout.addStretch(1) layout2.addWidget(self.hide_left_panel_chk) layout2.addWidget(self.synchronize_checkbox) layout.addLayout(layout2) layout.addWidget(self._ch_control2) # layout.setSpacing(0) self.setLayout(layout)
def __init__(self, data, win_parent=None): """ +-----------------+ | Edit Node Props | +-----------------+------+ | LEwingTip | | Node2 | | Node3 | | Node4 | | | | 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 | | | | Close | +------------------------+ """ QDialog.__init__(self, win_parent) self.setWindowTitle('Edit Node Properties') #default self.win_parent = win_parent self.out_data = data point_properties = data['point_properties'] print(point_properties) #name = point_properties.name point_size = point_properties.point_size opacity = point_properties.opacity color = point_properties.color show = point_properties.is_visible self.points = data['points'] self.keys = sorted(self.points.keys()) keys = self.keys #nrows = len(keys) active_point = data['active_point'] #self.active_key = keys[0] self.active_key = active_point name = self.active_key description = self.points[self.active_key][0] self._use_old_table = False items = ['Node %i' % val for val in keys] header_labels = ['Nodes'] table_model = Model(items, header_labels, self) view = SingleChoiceQTableView(self) #Call your custom QTableView here view.setModel(table_model) if qt_version == 4: view.horizontalHeader().setResizeMode(QHeaderView.Stretch) else: view.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) self.table = view #self.representation = actor_obj.representation #print('rep =', self.representation) table = self.table #headers = [QtCore.QString('Groups')] header = table.horizontalHeader() header.setStretchLastSection(True) #---------------------------------------------- #self._default_is_apply = False self.color = QLabel("Color:") self.color_edit = QPushButton() #self.color_edit.setFlat(True) color = self.out_data['point_properties'].color opacity = self.out_data['point_properties'].opacity show = self.out_data['point_properties'].is_visible #color = self.out_data[self.active_key].color qcolor = QColor() qcolor.setRgb(*color) #print('color =%s' % str(color)) palette = QPalette( self.color_edit.palette()) # make a copy of the palette #palette.setColor(QPalette.Active, QPalette.Base, \ #qcolor) palette.setColor(QPalette.Background, QColor('blue')) # ButtonText self.color_edit.setPalette(palette) self.color_edit.setStyleSheet("QPushButton {" "background-color: rgb(%s, %s, %s);" % tuple(color) + #"border:1px solid rgb(255, 170, 255); " "}") self.all_nodes_header = QLabel("All Nodes:") self.point_size = QLabel("Point Size:") self.point_size_edit = QSpinBox(self) self.point_size_edit.setRange(1, 10) self.point_size_edit.setSingleStep(1) self.point_size_edit.setValue(point_size) self.opacity = QLabel("Opacity:") self.opacity_edit = QDoubleSpinBox(self) self.opacity_edit.setRange(0.1, 1.0) self.opacity_edit.setDecimals(1) self.opacity_edit.setSingleStep(0.1) self.opacity_edit.setValue(opacity) # show/hide self.checkbox_show = QCheckBox("Show") self.checkbox_hide = QCheckBox("Hide") self.checkbox_show.setChecked(show) self.checkbox_hide.setChecked(not show) #---------------------------------------------- self.nodes_header = QLabel("Single Node:") self.name = QLabel("ID:") self.name_edit = QLineEdit('Node %i' % name) self.name_edit.setDisabled(True) self.description = QLabel("Description:") self.description_edit = QLineEdit(str(description)) #self.description_edit.setDisabled(True) location_x = 0.1 location_y = 0.1 location_z = 0.1 self.location = QLabel("Location:") self.location_x_edit = QDoubleSpinBox(self) self.location_y_edit = QDoubleSpinBox(self) self.location_z_edit = QDoubleSpinBox(self) #self.location_x_edit.setDecimals(1) delta_x = abs(location_x) / 100. if location_x != 0.0 else 0.1 delta_y = abs(location_y) / 100. if location_y != 0.0 else 0.1 delta_z = abs(location_z) / 100. if location_z != 0.0 else 0.1 self.location_x_edit.setSingleStep(delta_x) self.location_y_edit.setSingleStep(delta_y) self.location_z_edit.setSingleStep(delta_z) self.location_x_edit.setValue(location_x) self.location_y_edit.setValue(location_y) self.location_z_edit.setValue(location_z) self.coord = QLabel("Coord:") self.coord_edit = QSpinBox(self) self.coord_edit.setRange(0, 99999999) #self.coord_edit.setSingleStep(1) self.coord_edit.setValue(0) self.coord_type = QLabel("Coord Type:") #---------------------------------------------- # closing #if self._default_is_apply: #self.apply_button.setDisabled(True) self.close_button = QPushButton("Close") self.create_layout() self.set_connections()
class Options(QWidget): def __init__( self, settings: PartSettings, channel_control2: ChannelProperty, left_image: ResultImageView, synchronize: SynchronizeView, ): super().__init__() self._settings = settings self.left_panel = left_image self._ch_control2 = channel_control2 self.synchronize_val = False self.hide_left_panel_chk = QCheckBox("Hide left panel") self.hide_left_panel_chk.stateChanged.connect(self.hide_left_panel) self.synchronize_checkbox = QCheckBox("Synchronize view") self.synchronize_checkbox.stateChanged.connect( synchronize.set_synchronize) self.interactive_use = QCheckBox("Interactive use") self.execute_btn = QPushButton("Execute") self.execute_btn.clicked.connect(self.execute_algorithm) self.execute_btn.setStyleSheet("QPushButton{font-weight: bold;}") self.save_pipe_btn = QPushButton("Save pipeline") self.save_pipe_btn.clicked.connect(self.save_pipeline) self.save_pipe_btn.setToolTip( "Save current pipeline. Last element is last executed algorithm") self.choose_pipe = SearchComboBox() self.choose_pipe.addItem("<none>") # self.choose_pipe.addItems(list(self._settings.roi_pipelines.keys())) self.choose_pipe.textActivated.connect(self.choose_pipeline) self.choose_pipe.setToolTip("Execute chosen pipeline") self.save_profile_btn = QPushButton("Save profile") self.save_profile_btn.setToolTip("Save values from current view") self.save_profile_btn.clicked.connect(self.save_profile) self.choose_profile = SearchComboBox() self.choose_profile.addItem("<none>") # self.choose_profile.addItems(list(self._settings.roi_profiles.keys())) self.choose_profile.setToolTip( "Select profile to restore its settings. Execute if interactive is checked" ) # image state self.compare_btn = QPushButton("Compare") self.compare_btn.setDisabled(True) self.compare_btn.clicked.connect(self.compare_action) left_image.hide_signal.connect(self.compare_btn.setHidden) self.update_tooltips() self.choose_profile.textActivated.connect(self.change_profile) self.interactive_use.stateChanged.connect(self.execute_btn.setDisabled) self.interactive_use.stateChanged.connect(self.interactive_change) self.algorithm_choose_widget = AlgorithmChoose( settings, algorithm_description.analysis_algorithm_dict) self.algorithm_choose_widget.result.connect(self.execution_done) self.algorithm_choose_widget.finished.connect( self.calculation_finished) self.algorithm_choose_widget.value_changed.connect( self.interactive_algorithm_execute) self.algorithm_choose_widget.algorithm_changed.connect( self.interactive_algorithm_execute) self._settings.roi_profiles_changed.connect(self._update_profiles) self._settings.roi_pipelines_changed.connect(self._update_pipelines) self._update_pipelines() self._update_profiles() self.label = TextShow() layout = QVBoxLayout() layout2 = QHBoxLayout() layout2.setSpacing(1) layout2.setContentsMargins(0, 0, 0, 0) layout3 = QHBoxLayout() layout3.setContentsMargins(0, 0, 0, 0) layout.setContentsMargins(0, 0, 0, 0) layout5 = QHBoxLayout() layout5.setContentsMargins(0, 0, 0, 0) layout5.addWidget(self.save_pipe_btn) layout5.addWidget(self.choose_pipe) layout4 = QHBoxLayout() layout4.setContentsMargins(0, 0, 0, 0) layout4.addWidget(self.save_profile_btn) layout4.addWidget(self.choose_profile) layout3.addWidget(self.interactive_use) layout3.addWidget(self.execute_btn) layout.addLayout(layout5) layout.addLayout(layout4) layout.addLayout(layout3) layout.addWidget(self.algorithm_choose_widget, 1) # layout.addLayout(self.stack_layout) layout.addWidget(self.label) # layout.addStretch(1) layout2.addWidget(self.hide_left_panel_chk) layout2.addWidget(self.synchronize_checkbox) layout.addLayout(layout2) layout.addWidget(self._ch_control2) # layout.setSpacing(0) self.setLayout(layout) @ensure_main_thread def _update_profiles(self): self.update_combo_box(self.choose_profile, self._settings.roi_profiles) self.update_tooltips() @ensure_main_thread def _update_pipelines(self): self.update_combo_box(self.choose_pipe, self._settings.roi_pipelines) self.update_tooltips() def compare_action(self): if self.compare_btn.text() == "Compare": self._settings.set_segmentation_to_compare(self._settings.roi_info) self.compare_btn.setText("Remove") else: self._settings.set_segmentation_to_compare(ROIInfo(None)) self.compare_btn.setText("Compare") def calculation_finished(self): self.execute_btn.setDisabled(self.interactive_use.isChecked()) self.interactive_use.setEnabled(True) def save_pipeline(self): history = self._settings.get_history() if not history: QMessageBox.information(self, "No mask created", "There is no new mask created", QMessageBox.Ok) return mask_history = [] for el in history: mask = el.mask_property segmentation = ROIExtractionProfile( name="Unknown", algorithm=el.roi_extraction_parameters["algorithm_name"], values=el.roi_extraction_parameters["values"], ) new_el = SegmentationPipelineElement(mask_property=mask, segmentation=segmentation) mask_history.append(new_el) name = self._settings.last_executed_algorithm if not name: QMessageBox.information(self, "No segmentation", "No segmentation executed", QMessageBox.Ok) return values = self._settings.get(f"algorithms.{name}", {}) if len(values) == 0: QMessageBox.information(self, "Some problem", "Pleas run execution again", QMessageBox.Ok) return current_segmentation = ROIExtractionProfile(name="Unknown", algorithm=name, values=values) while True: text, ok = QInputDialog.getText(self, "Pipeline name", "Input pipeline name here") if not ok: return if text in self._settings.roi_pipelines and QMessageBox.No == QMessageBox.warning( self, "Already exists", "Profile with this name already exist. Overwrite?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No, ): continue profile = SegmentationPipeline(name=text, segmentation=current_segmentation, mask_history=mask_history) self._settings.roi_pipelines[text] = profile self._settings.dump() self.choose_pipe.addItem(text) break def choose_pipeline(self, text): if text == "<none>": return pipeline = self._settings.roi_pipelines[text] process_thread = CalculatePipelineThread(self._settings.image, self._settings.mask, pipeline) dial = WaitingDialog(process_thread) if dial.exec_() and process_thread.result: pipeline_result = process_thread.result self._settings.mask = pipeline_result.mask self._settings.roi = pipeline_result.roi_info.roi self._settings.set_history(pipeline_result.history) self.label.setText(pipeline_result.description) self.algorithm_choose_widget.change_algorithm( pipeline.segmentation.algorithm, pipeline.segmentation.values) self.choose_pipe.setCurrentIndex(0) def update_tooltips(self): for i in range(1, self.choose_profile.count()): if self.choose_profile.itemData(i, Qt.ToolTipRole) is not None: continue text = self.choose_profile.itemText(i) profile: ROIExtractionProfile = self._settings.roi_profiles[text] tool_tip_text = str(profile) self.choose_profile.setItemData(i, tool_tip_text, Qt.ToolTipRole) for i in range(1, self.choose_pipe.count()): if self.choose_pipe.itemData(i, Qt.ToolTipRole) is not None: continue text = self.choose_pipe.itemText(i) profile: SegmentationPipeline = self._settings.roi_pipelines[text] tool_tip_text = str(profile) self.choose_pipe.setItemData(i, tool_tip_text, Qt.ToolTipRole) @staticmethod def update_combo_box(combo_box: QComboBox, dkt: dict): current_names = set(dkt.keys()) prev_names = { combo_box.itemText(i) for i in range(1, combo_box.count()) } new_names = current_names - prev_names delete_names = prev_names - current_names if len(delete_names) > 0: i = 1 while i < combo_box.count(): if combo_box.itemText(i) in delete_names: combo_box.removeItem(i) else: i += 1 if len(new_names) > 0: combo_box.addItems(list(sorted(new_names))) def keyPressEvent(self, event: QKeyEvent): if event.key() in [Qt.Key_Enter, Qt.Key_Return ] and event.modifiers() == Qt.ControlModifier: self.execute_btn.click() def save_profile(self): widget: InteractiveAlgorithmSettingsWidget = self.algorithm_choose_widget.current_widget( ) while True: text, ok = QInputDialog.getText(self, "Profile Name", "Input profile name here") if not ok: return if text in self._settings.roi_profiles and QMessageBox.No == QMessageBox.warning( self, "Already exists", "Profile with this name already exist. Overwrite?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No, ): continue resp = ROIExtractionProfile(text, widget.name, widget.get_values()) self._settings.roi_profiles[text] = resp self._settings.dump() break def change_profile(self, val): self.choose_profile.setToolTip("") if val == "<none>": return interactive = self.interactive_use.isChecked() self.interactive_use.setChecked(False) profile = self._settings.roi_profiles[val] self.algorithm_choose_widget.change_algorithm(profile.algorithm, profile.values) self.choose_profile.blockSignals(True) self.choose_profile.setCurrentIndex(0) self.choose_profile.blockSignals(False) self.interactive_use.setChecked(interactive) @property def segmentation(self): return self._settings.roi @property def interactive(self): return self.interactive_use.isChecked() def hide_left_panel(self, val): self._settings.set_in_profile("hide_left_panel", val) if val: self.synchronize_val = self.synchronize_checkbox.isChecked() self.synchronize_checkbox.setChecked(False) else: self.synchronize_checkbox.setChecked(self.synchronize_val) self.synchronize_checkbox.setDisabled(val) self.left_panel.parent().setHidden(val) def interactive_change(self, val): if val: self.execute_algorithm() def algorithm_change(self, val): self._settings.set("current_algorithm", val) if self.interactive: self.execute_algorithm() def interactive_algorithm_execute(self): if self.interactive: self.execute_algorithm() def execute_algorithm(self): widget: InteractiveAlgorithmSettingsWidget = self.algorithm_choose_widget.current_widget( ) if self._settings.image.is_time and not widget.algorithm.support_time( ): QMessageBox.information( self, "Not supported", "This algorithm do not support time data. You can convert it in image adjust" ) return if self._settings.image.is_stack and not widget.algorithm.support_z(): QMessageBox.information( self, "Not supported", "This algorithm do not support stack data. You can convert it in image adjust" ) return self._settings.last_executed_algorithm = widget.name self.execute_btn.setDisabled(True) self.interactive_use.setDisabled(True) widget.execute() def execution_done(self, segmentation: ROIExtractionResult): if segmentation.info_text != "": QMessageBox.information(self, "Algorithm info", segmentation.info_text) self._settings.set_segmentation_result(segmentation) self.compare_btn.setEnabled( isinstance(segmentation.roi, np.ndarray) and np.any(segmentation.roi)) self.label.setText(self.sender().get_info_text()) def showEvent(self, _event): self.hide_left_panel_chk.setChecked( self._settings.get_from_profile("hide_left_panel", False))
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) selectProjectButton = QPushButton() selectProjectButton.setCursor(Qt.PointingHandCursor) selectProjectButton.setObjectName("selectProjectButton") selectProjectButton.setText("Select project") self.selectProjectButton = selectProjectButton pathLabel = QLabel() pathLabel.setText("Path:") pathLabel.setToolTip("Project path") pathLabel.setWordWrap(False) pathLabel.setAlignment(Qt.AlignRight) pathValueLabel = QElidedLabel() pathValueLabel.setText("none") pathValueLabel.setToolTip("none") pathValueLabel.setWordWrap(False) self.pathValueLabel = pathValueLabel nameLabel = QLabel() nameLabel.setText("Name:") nameLabel.setToolTip("Project name") nameLabel.setWordWrap(False) nameLabel.setAlignment(Qt.AlignRight) nameValueLabel = QElidedLabel() nameValueLabel.setText("none") nameValueLabel.setToolTip("none") nameValueLabel.setWordWrap(False) self.nameValueLabel = nameValueLabel projectStatusGrid = QGridLayout() projectStatusGrid.setContentsMargins(2, 2, 2, 2) projectStatusGrid.setColumnStretch(0, 0) projectStatusGrid.setColumnStretch(1, 1) projectStatusGrid.addWidget(pathLabel, 0, 0) projectStatusGrid.addWidget(nameLabel, 1, 0) projectStatusGrid.addWidget(pathValueLabel, 0, 1) projectStatusGrid.addWidget(nameValueLabel, 1, 1) projectGroupBox = QGroupBox() projectGroupBox.setTitle("Current project") projectGroupBox.setLayout(projectStatusGrid) statusLayout = QVBoxLayout() statusLayout.addWidget(selectProjectButton, stretch=0) statusLayout.addSpacing(10) statusLayout.addWidget(projectGroupBox, stretch=0) statusLayout.addStretch(1) statusLayout.setContentsMargins(0, 0, 0, 0) statusLayout.setSpacing(0) statusWidget = QWidget() statusWidget.setLayout(statusLayout) statusWidget.setContentsMargins(0, 0, 0, 0) statusWidget.setFixedWidth(250) noProjectSetLabel = QLabel() noProjectSetLabel.setObjectName("noProjectSetLabel") noProjectSetLabel.setText("No project set") noProjectSetLabel.setAlignment(Qt.AlignCenter) layout = QHBoxLayout() layout.setContentsMargins(6, 6, 6, 6) layout.addWidget(statusWidget, stretch=0) layout.addSpacing(3) layout.addWidget(noProjectSetLabel, stretch=1) self.setLayout(layout)
def setup(self): """Setup the ShortcutEditor with the provided arguments.""" # Widgets icon_info = HelperToolButton() icon_info.setIcon(get_std_icon('MessageBoxInformation')) layout_icon_info = QVBoxLayout() layout_icon_info.setContentsMargins(0, 0, 0, 0) layout_icon_info.setSpacing(0) layout_icon_info.addWidget(icon_info) layout_icon_info.addStretch(100) self.label_info = QLabel() self.label_info.setText( _("Press the new shortcut and select 'Ok' to confirm, " "click 'Cancel' to revert to the previous state, " "or use 'Clear' to unbind the command from a shortcut.")) self.label_info.setAlignment(Qt.AlignTop | Qt.AlignLeft) self.label_info.setWordWrap(True) layout_info = QHBoxLayout() layout_info.setContentsMargins(0, 0, 0, 0) layout_info.addLayout(layout_icon_info) layout_info.addWidget(self.label_info) layout_info.setStretch(1, 100) self.label_current_sequence = QLabel(_("Current shortcut:")) self.text_current_sequence = QLabel(self.current_sequence) self.label_new_sequence = QLabel(_("New shortcut:")) self.text_new_sequence = ShortcutLineEdit(self) self.text_new_sequence.setPlaceholderText(_("Press shortcut.")) self.helper_button = HelperToolButton() self.helper_button.setIcon(QIcon()) self.label_warning = QLabel() self.label_warning.setWordWrap(True) self.label_warning.setAlignment(Qt.AlignTop | Qt.AlignLeft) self.button_default = QPushButton(_('Default')) self.button_ok = QPushButton(_('Ok')) self.button_ok.setEnabled(False) self.button_clear = QPushButton(_('Clear')) self.button_cancel = QPushButton(_('Cancel')) button_box = QHBoxLayout() button_box.addWidget(self.button_default) button_box.addStretch(100) button_box.addWidget(self.button_ok) button_box.addWidget(self.button_clear) button_box.addWidget(self.button_cancel) # New Sequence button box self.btn_clear_sequence = create_toolbutton( self, icon=ima.icon('editclear'), tip=_("Clear all entered key sequences"), triggered=self.clear_new_sequence) self.button_back_sequence = create_toolbutton( self, icon=ima.icon('ArrowBack'), tip=_("Remove last key sequence entered"), triggered=self.back_new_sequence) newseq_btnbar = QHBoxLayout() newseq_btnbar.setSpacing(0) newseq_btnbar.setContentsMargins(0, 0, 0, 0) newseq_btnbar.addWidget(self.button_back_sequence) newseq_btnbar.addWidget(self.btn_clear_sequence) # Setup widgets self.setWindowTitle(_('Shortcut: {0}').format(self.name)) self.helper_button.setToolTip('') style = """ QToolButton { margin:1px; border: 0px solid grey; padding:0px; border-radius: 0px; }""" self.helper_button.setStyleSheet(style) icon_info.setToolTip('') icon_info.setStyleSheet(style) # Layout layout_sequence = QGridLayout() layout_sequence.setContentsMargins(0, 0, 0, 0) layout_sequence.addLayout(layout_info, 0, 0, 1, 4) layout_sequence.addItem(QSpacerItem(15, 15), 1, 0, 1, 4) layout_sequence.addWidget(self.label_current_sequence, 2, 0) layout_sequence.addWidget(self.text_current_sequence, 2, 2) layout_sequence.addWidget(self.label_new_sequence, 3, 0) layout_sequence.addWidget(self.helper_button, 3, 1) layout_sequence.addWidget(self.text_new_sequence, 3, 2) layout_sequence.addLayout(newseq_btnbar, 3, 3) layout_sequence.addWidget(self.label_warning, 4, 2, 1, 2) layout_sequence.setColumnStretch(2, 100) layout_sequence.setRowStretch(4, 100) layout = QVBoxLayout(self) layout.addLayout(layout_sequence) layout.addSpacing(10) layout.addLayout(button_box) layout.setSizeConstraint(layout.SetFixedSize) # Signals self.button_ok.clicked.connect(self.accept_override) self.button_clear.clicked.connect(self.unbind_shortcut) self.button_cancel.clicked.connect(self.reject) self.button_default.clicked.connect(self.set_sequence_to_default) # Set all widget to no focus so that we can register <Tab> key # press event. widgets = (self.label_warning, self.helper_button, self.text_new_sequence, self.button_clear, self.button_default, self.button_cancel, self.button_ok, self.btn_clear_sequence, self.button_back_sequence) for w in widgets: w.setFocusPolicy(Qt.NoFocus) w.clearFocus()