def initialize(self, checked=True): """ Start pydoc server. Parameters ---------- checked: bool, optional This method is connected to the `sig_toggle_view_changed` signal, so that the first time the widget is made visible it will start the server. Default is True. """ if checked and self.server is None: self.sig_toggle_view_changed.disconnect(self.initialize) QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) QApplication.processEvents() self.start_server()
def _update_hover_html_link_style(self, url): """Update style of labels that include rich text and html links.""" link = 'text-decoration:none;' link_hovered = 'text-decoration:underline;' self._url = url if url: QApplication.setOverrideCursor(QCursor(Qt.PointingHandCursor)) new_text, old_text = link_hovered, link else: new_text, old_text = link, link_hovered QApplication.restoreOverrideCursor() text = self.text() new_text = text.replace(old_text, new_text) self.setText(new_text)
def __init__(self, theme=None, stylesheet=None, custom_fonts=[]): app_args = (qtpyvcp.OPTIONS.command_line_args or "").split() super(VCPApplication, self).__init__(app_args) opts = qtpyvcp.OPTIONS self.status = getPlugin('status') # initialize plugins initialisePlugins() theme = opts.theme or theme if theme is not None: self.setStyle(QStyleFactory.create(theme)) stylesheet = opts.stylesheet or stylesheet if stylesheet is not None: self.loadStylesheet(stylesheet, opts.develop) if custom_fonts: if isinstance(custom_fonts, str): # single font or location self.loadCustomFont(custom_fonts) else: # list of fonts or locations for font in custom_fonts: self.loadCustomFont(font) # self.window = self.loadVCPMainWindow(opts, vcp_file) # if self.window is not None: # self.window.show() if opts.hide_cursor: from qtpy.QtGui import QCursor self.setOverrideCursor(QCursor(Qt.BlankCursor)) # Performance monitoring if opts.perfmon: import psutil self.perf = psutil.Process() self.perf_timer = QTimer() self.perf_timer.setInterval(2000) self.perf_timer.timeout.connect(self.logPerformance) self.perf_timer.start() self.aboutToQuit.connect(self.terminate)
def mouseMoveEvent(self, event): """ Detect mouser over indicator and highlight the current scope in the editor (up and down decoration arround the foldable text when the mouse is over an indicator). :param event: event """ super(FoldingPanel, self).mouseMoveEvent(event) th = TextHelper(self.editor) line = th.line_nbr_from_position(event.pos().y()) if line >= 0: block = self.editor.document().findBlockByNumber(line) block = self.find_parent_scope(block) line_number = block.blockNumber() if line_number in self.folding_regions: if self._mouse_over_line is None: # mouse enter fold scope QApplication.setOverrideCursor( QCursor(Qt.PointingHandCursor)) if (self._mouse_over_line != block.blockNumber() and self._mouse_over_line is not None): # fold scope changed, a previous block was highlighter so # we quickly update our highlighting self._mouse_over_line = block.blockNumber() self._highlight_block(block) else: # same fold scope, request highlight self._mouse_over_line = block.blockNumber() try: self._highlight_runner.request_job( self._highlight_block, block) except KeyError: # Catching the KeyError above is necessary to avoid # issue spyder-ide/spyder#11291. pass self._highight_block = block else: # no fold scope to highlight, cancel any pending requests self._highlight_runner.cancel_requests() self._mouse_over_line = None QApplication.restoreOverrideCursor() self.repaint()
def initialize(self, checked=True, force=False): """ Start pydoc server. Parameters ---------- checked: bool, optional This method is connected to the `sig_toggle_view_changed` signal, so that the first time the widget is made visible it will start the server. Default is True. force: bool, optional Force a server start even if the server is running. Default is False. """ server_needed = checked and self.server is None if force or server_needed or not self.is_server_running(): self.sig_toggle_view_changed.disconnect(self.initialize) QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) self.start_server()
def _on_cursor(self, event): """Set the appearance of the mouse cursor. Parameters ---------- event : qtpy.QtCore.QEvent Event from the Qt context. """ cursor = self.viewer.cursor size = self.viewer.cursor_size if cursor == 'square': if size < 10 or size > 300: q_cursor = self._cursors['cross'] else: q_cursor = QCursor( QPixmap(':/icons/cursor/cursor_square.png').scaledToHeight( size)) else: q_cursor = self._cursors[cursor] self.canvas.native.setCursor(q_cursor)
def _on_cursor(self, event): """Set the appearance of the mouse cursor. Parameters ---------- event : qtpy.QtCore.QEvent Event from the Qt context. """ cursor = self.viewer.cursor if cursor == 'square': size = self.viewer.cursor_size # make sure the square fits within the current canvas if size < 8 or size > ( min(*self.viewer.window.qt_viewer.canvas.size) - 4): q_cursor = self._cursors['cross'] else: q_cursor = QCursor(square_pixmap(size)) else: q_cursor = self._cursors[cursor] self.canvas.native.setCursor(q_cursor)
def setup(self, applications=None): """Load installed applications.""" QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) self.list.clear() if applications is None: apps = get_installed_applications() else: apps = applications for app in sorted(apps, key=lambda x: x.lower()): fpath = apps[app] icon = get_application_icon(fpath) item = QListWidgetItem(icon, app) item.setToolTip(fpath) item.fpath = fpath self.list.addItem(item) # FIXME: Use metrics self.list.setMinimumWidth(self.list.sizeHintForColumn(0) + 24) QApplication.restoreOverrideCursor() self._refresh()
def _fix_cursor(self, from_index, to_index): """Fix mouse cursor position to adjust for different tab sizes.""" # The direction is +1 (moving to the right) or -1 (moving to the left) direction = abs(to_index - from_index) / (to_index - from_index) tab_width = self.dock_tabbar.tabRect(to_index).width() tab_x_min = self.dock_tabbar.tabRect(to_index).x() tab_x_max = tab_x_min + tab_width previous_width = self.dock_tabbar.tabRect(to_index - direction).width() delta = previous_width - tab_width if delta > 0: delta = delta * direction else: delta = 0 cursor = QCursor() pos = self.dock_tabbar.mapFromGlobal(cursor.pos()) x, y = pos.x(), pos.y() if x < tab_x_min or x > tab_x_max: new_pos = self.dock_tabbar.mapToGlobal(QPoint(x + delta, y)) cursor.setPos(new_pos)
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.setCursor(QCursor(self._icon.pixmap(16, 16))) self._display_filename = filename 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, self.NEW_WINDOW)) self._show_icon = True
def __init__(self, theme=None, stylesheet=None): app_args = (qtpyvcp.OPTIONS.command_line_args or "").split() super(VCPApplication, self).__init__(app_args) opts = qtpyvcp.OPTIONS from qtpyvcp.core import Prefs, Info self.info = Info() self.prefs = Prefs() self.status = getPlugin('status') self.initialiseDataPlugins() theme = opts.theme or theme if theme is not None: self.setStyle(QStyleFactory.create(theme)) stylesheet = opts.stylesheet or stylesheet if stylesheet is not None: self.loadStylesheet(stylesheet) # self.window = self.loadVCPMainWindow(opts, vcp_file) # if self.window is not None: # self.window.show() if opts.hide_cursor: from qtpy.QtGui import QCursor self.setOverrideCursor(QCursor(Qt.BlankCursor)) # Performance monitoring if opts.perfmon: import psutil self.perf = psutil.Process() self.perf_timer = QTimer() self.perf_timer.setInterval(2000) self.perf_timer.timeout.connect(self.logPerformance) self.perf_timer.start() self.aboutToQuit.connect(self.terminate)
def edit_parameters(self): class DefocusParameterTree(QWidget): def __init__(self, *args, **kwargs): super(DefocusParameterTree, self).__init__(*args, **kwargs) self.setLayout(QVBoxLayout()) self.parameter_tree = ParameterTree() self.layout().addWidget(self.parameter_tree) self.layout().setContentsMargins(0, 0, 0, 0) def setParameters(self, *args, **kwargs): self.parameter_tree.setParameters(*args, **kwargs) # self.parameter_tree = DefocusParameterTree() self.parameter_tree = DefocusParameterTree() self.parameter_tree.setParameters(self.parameter()) self.parameter_tree.setWindowFlags(Qt.FramelessWindowHint | Qt.Popup) # self.parameter_tree = QLabel('blah') self.parameter_tree.show() self.parameter_tree.activateWindow() self.parameter_tree.raise_() self.parameter_tree.move(QCursor().pos()) self.parameter_tree.setFocus(Qt.PopupFocusReason) self.parameter_tree.resize(QSize(300, 400))
def mouseMoveEvent(self, event): """ Detect mouser over indicator and highlight the current scope in the editor (up and down decoration arround the foldable text when the mouse is over an indicator). :param event: event """ super(FoldingPanel, self).mouseMoveEvent(event) th = TextHelper(self.editor) line = th.line_nbr_from_position(event.pos().y()) if line >= 0: block = FoldScope.find_parent_scope( self.editor.document().findBlockByNumber(line - 1)) if TextBlockHelper.is_fold_trigger(block): if self._mouse_over_line is None: # mouse enter fold scope QApplication.setOverrideCursor( QCursor(Qt.PointingHandCursor)) if self._mouse_over_line != block.blockNumber() and \ self._mouse_over_line is not None: # fold scope changed, a previous block was highlighter so # we quickly update our highlighting self._mouse_over_line = block.blockNumber() self._highlight_block(block) else: # same fold scope, request highlight self._mouse_over_line = block.blockNumber() self._highlight_runner.request_job(self._highlight_block, block) self._highight_block = block else: # no fold scope to highlight, cancel any pending requests self._highlight_runner.cancel_requests() self._mouse_over_line = None QApplication.restoreOverrideCursor() self.repaint()
def save_data(self): """Save data""" filename = self.filename if filename is None: filename = getcwd_or_home() extension = osp.splitext(filename)[1].lower() if not extension: # Needed to prevent trying to save a data file without extension # See spyder-ide/spyder#7196 filename = filename + '.spydata' filename, _selfilter = getsavefilename(self, _("Save data"), filename, iofunctions.save_filters) if filename: self.filename = filename else: return False QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) QApplication.processEvents() error_message = self.shellwidget.save_namespace(self.filename) QApplication.restoreOverrideCursor() QApplication.processEvents() if error_message is not None: if 'Some objects could not be saved:' in error_message: save_data_message = ( _("<b>Some objects could not be saved:</b>") + "<br><br><code>{obj_list}</code>".format( obj_list=error_message.split(': ')[1])) else: save_data_message = _( "<b>Unable to save current workspace</b>" "<br><br>" "The error message was:<br>") + error_message QMessageBox.critical(self, _("Save data"), save_data_message)
def save_data(self, filename=None): """Save data""" if filename is None: filename = self.filename if filename is None: filename = getcwd_or_home() filename, _selfilter = getsavefilename(self, _("Save data"), filename, iofunctions.save_filters) if filename: self.filename = filename else: return False QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) QApplication.processEvents() error_message = self.shellwidget.save_namespace(self.filename) self.shellwidget._kernel_reply = None QApplication.restoreOverrideCursor() QApplication.processEvents() if error_message is not None: QMessageBox.critical(self, _("Save data"), _("<b>Unable to save current workspace</b>" "<br><br>Error message:<br>%s") % error_message) self.save_button.setEnabled(self.filename is not None)
def __init__(self, parent=None, **kwargs): super(PCDSSymbolBase, self).__init__(parent=parent, **kwargs) self._expert_display = None self.interlock = None self._channels_prefix = None self._rotate_icon = False self._show_icon = True self._show_status_tooltip = True self._icon_size = -1 self._icon = None self._icon_cursor = self.setCursor( QCursor(IconFont().icon("file").pixmap(16, 16)) ) self._expert_ophyd_class = self.EXPERT_OPHYD_CLASS or "" self.interlock = QFrame(self) self.interlock.setObjectName("interlock") self.interlock.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.controls_frame = QFrame(self) self.controls_frame.setObjectName("controls") self.controls_frame.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) self.setLayout(QVBoxLayout()) self.layout().setSpacing(0) self.layout().setContentsMargins(0, 0, 0, 0) self.layout().addWidget(self.interlock) if not hasattr(self, '_controls_location'): self._controls_location = ContentLocation.Bottom self.setup_icon() self.assemble_layout() self.update_status_tooltip()
def initialize(self): """Start pydoc server""" QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) QApplication.processEvents() self.start_server()
def __init__(self, viewer): super().__init__() self.setAttribute(Qt.WA_DeleteOnClose) self.pool = QThreadPool() QCoreApplication.setAttribute( Qt.AA_UseStyleSheetPropagationInWidgetStyles, True) self.viewer = viewer self.dims = QtDims(self.viewer.dims) self.controls = QtControls(self.viewer) self.layers = QtLayerList(self.viewer.layers) self.layerButtons = QtLayerButtons(self.viewer) self.viewerButtons = QtViewerButtons(self.viewer) self.console = QtConsole({'viewer': self.viewer}) layerList = QWidget() layerList.setObjectName('layerList') layerListLayout = QVBoxLayout() layerListLayout.addWidget(self.layerButtons) layerListLayout.addWidget(self.layers) layerListLayout.addWidget(self.viewerButtons) layerListLayout.setContentsMargins(8, 4, 8, 6) layerList.setLayout(layerListLayout) self.dockLayerList = QtViewerDockWidget( self, layerList, name='layer list', area='left', allowed_areas=['left', 'right'], ) self.dockLayerControls = QtViewerDockWidget( self, self.controls, name='layer controls', area='left', allowed_areas=['left', 'right'], ) self.dockConsole = QtViewerDockWidget( self, self.console, name='console', area='bottom', allowed_areas=['top', 'bottom'], shortcut='Ctrl+Shift+C', ) self.dockConsole.setVisible(False) self.dockLayerControls.visibilityChanged.connect(self._constrain_width) self.dockLayerList.setMaximumWidth(258) self.dockLayerList.setMinimumWidth(258) # This dictionary holds the corresponding vispy visual for each layer self.layer_to_visual = {} if self.console.shell is not None: self.viewerButtons.consoleButton.clicked.connect( lambda: self.toggle_console()) else: self.viewerButtons.consoleButton.setEnabled(False) self.canvas = SceneCanvas(keys=None, vsync=True, parent=self) self.canvas.events.ignore_callback_errors = False self.canvas.events.draw.connect(self.dims.enable_play) self.canvas.native.setMinimumSize(QSize(200, 200)) self.canvas.context.set_depth_func('lequal') self.canvas.connect(self.on_mouse_move) self.canvas.connect(self.on_mouse_press) self.canvas.connect(self.on_mouse_release) self.canvas.connect(self.on_key_press) self.canvas.connect(self.on_key_release) self.canvas.connect(self.on_draw) self.view = self.canvas.central_widget.add_view() self._update_camera() main_widget = QWidget() main_layout = QVBoxLayout() main_layout.setContentsMargins(10, 22, 10, 2) main_layout.addWidget(self.canvas.native) main_layout.addWidget(self.dims) main_layout.setSpacing(10) main_widget.setLayout(main_layout) self.setOrientation(Qt.Vertical) self.addWidget(main_widget) self._last_visited_dir = str(Path.home()) self._cursors = { 'disabled': QCursor( QPixmap(':/icons/cursor/cursor_disabled.png').scaled(20, 20)), 'cross': Qt.CrossCursor, 'forbidden': Qt.ForbiddenCursor, 'pointing': Qt.PointingHandCursor, 'standard': QCursor(), } self._update_palette(viewer.palette) self._key_release_generators = {} self.viewer.events.interactive.connect(self._on_interactive) self.viewer.events.cursor.connect(self._on_cursor) self.viewer.events.reset_view.connect(self._on_reset_view) self.viewer.events.palette.connect( lambda event: self._update_palette(event.palette)) self.viewer.layers.events.reordered.connect(self._reorder_layers) self.viewer.layers.events.added.connect(self._add_layer) self.viewer.layers.events.removed.connect(self._remove_layer) self.viewer.dims.events.camera.connect( lambda event: self._update_camera()) # stop any animations whenever the layers change self.viewer.events.layers_change.connect(lambda x: self.dims.stop()) self.setAcceptDrops(True)
def __init__(self, viewer): from .layer_controls import QtLayerControlsContainer super().__init__() self.setAttribute(Qt.WA_DeleteOnClose) QCoreApplication.setAttribute( Qt.AA_UseStyleSheetPropagationInWidgetStyles, True) self.viewer = viewer self.dims = QtDims(self.viewer.dims) self.controls = QtLayerControlsContainer(self.viewer) self.layers = QtLayerList(self.viewer.layers) self.layerButtons = QtLayerButtons(self.viewer) self.viewerButtons = QtViewerButtons(self.viewer) self._console = None layerList = QWidget() layerList.setObjectName('layerList') layerListLayout = QVBoxLayout() layerListLayout.addWidget(self.layerButtons) layerListLayout.addWidget(self.layers) layerListLayout.addWidget(self.viewerButtons) layerListLayout.setContentsMargins(8, 4, 8, 6) layerList.setLayout(layerListLayout) self.dockLayerList = QtViewerDockWidget( self, layerList, name='layer list', area='left', allowed_areas=['left', 'right'], ) self.dockLayerControls = QtViewerDockWidget( self, self.controls, name='layer controls', area='left', allowed_areas=['left', 'right'], ) self.dockConsole = QtViewerDockWidget( self, QWidget(), name='console', area='bottom', allowed_areas=['top', 'bottom'], shortcut='Ctrl+Shift+C', ) self.dockConsole.setVisible(False) # because the console is loaded lazily in the @getter, this line just # gets (or creates) the console when the dock console is made visible. self.dockConsole.visibilityChanged.connect(lambda visible: self.console if visible else None) self.dockLayerControls.visibilityChanged.connect(self._constrain_width) self.dockLayerList.setMaximumWidth(258) self.dockLayerList.setMinimumWidth(258) self.dockPerformance = self._create_performance_dock_widget() # This dictionary holds the corresponding vispy visual for each layer self.layer_to_visual = {} self.viewerButtons.consoleButton.clicked.connect( self.toggle_console_visibility) self.canvas = KeyModifierFilterSceneCanvas(keys=None, vsync=True, parent=self) self.canvas.events.ignore_callback_errors = False self.canvas.events.draw.connect(self.dims.enable_play) self.canvas.native.setMinimumSize(QSize(200, 200)) self.canvas.context.set_depth_func('lequal') self.canvas.connect(self.on_mouse_move) self.canvas.connect(self.on_mouse_press) self.canvas.connect(self.on_mouse_release) self.canvas.connect(self.on_key_press) self.canvas.connect(self.on_key_release) self.canvas.connect(self.on_mouse_wheel) self.view = self.canvas.central_widget.add_view() self._update_camera() main_widget = QWidget() main_layout = QVBoxLayout() main_layout.setContentsMargins(10, 22, 10, 2) main_layout.addWidget(self.canvas.native) main_layout.addWidget(self.dims) main_layout.setSpacing(10) main_widget.setLayout(main_layout) self.setOrientation(Qt.Vertical) self.addWidget(main_widget) self._last_visited_dir = str(Path.home()) self._cursors = { 'cross': Qt.CrossCursor, 'forbidden': Qt.ForbiddenCursor, 'pointing': Qt.PointingHandCursor, 'standard': QCursor(), } self._update_palette() self.viewer.events.interactive.connect(self._on_interactive) self.viewer.events.cursor.connect(self._on_cursor) self.viewer.events.reset_view.connect(self._on_reset_view) self.viewer.events.palette.connect(self._update_palette) self.viewer.layers.events.reordered.connect(self._reorder_layers) self.viewer.layers.events.added.connect(self._add_layer) self.viewer.layers.events.removed.connect(self._remove_layer) self.viewer.dims.events.camera.connect( lambda event: self._update_camera()) # stop any animations whenever the layers change self.viewer.events.layers_change.connect(lambda x: self.dims.stop()) self.setAcceptDrops(True)
def set_move_cursor(self, cursor, x_pos, y_pos): """Set the style of the cursor to use when the marker is moving""" if cursor is not None: cursor = QCursor(cursor) self.move_cursor = cursor self.override_cursor(x_pos, y_pos)
def paintEvent(self, event): """ Override Qt method. Painting the scroll flag area """ make_flag = self.make_flag_qrect # Fill the whole painting area painter = QPainter(self) painter.fillRect(event.rect(), self.editor.sideareas_color) # Paint warnings and todos block = self.editor.document().firstBlock() for line_number in range(self.editor.document().blockCount() + 1): data = block.userData() if data: if data.code_analysis: # Paint the warnings color = self.editor.warning_color for source, code, severity, message in data.code_analysis: error = severity == DiagnosticSeverity.ERROR if error: color = self.editor.error_color break self.set_painter(painter, color) painter.drawRect(make_flag(line_number)) if data.todo: # Paint the todos self.set_painter(painter, self.editor.todo_color) painter.drawRect(make_flag(line_number)) if data.breakpoint: # Paint the breakpoints self.set_painter(painter, self.editor.breakpoint_color) painter.drawRect(make_flag(line_number)) block = block.next() # Paint the occurrences if self.editor.occurrences: self.set_painter(painter, self.editor.occurrence_color) for line_number in self.editor.occurrences: painter.drawRect(make_flag(line_number)) # Paint the found results if self.editor.found_results: self.set_painter(painter, self.editor.found_results_color) for line_number in self.editor.found_results: painter.drawRect(make_flag(line_number)) # Paint the slider range if not self._unit_testing: alt = QApplication.queryKeyboardModifiers() & Qt.AltModifier else: alt = self._alt_key_is_down cursor_pos = self.mapFromGlobal(QCursor().pos()) is_over_self = self.rect().contains(cursor_pos) is_over_editor = self.editor.rect().contains( self.editor.mapFromGlobal(QCursor().pos())) # We use QRect.contains instead of QWidget.underMouse method to # determined if the cursor is over the editor or the flag scrollbar # because the later gives a wrong result when a mouse button # is pressed. if ((is_over_self or (alt and is_over_editor)) and self.slider): pen_color = QColor(Qt.gray) pen_color.setAlphaF(.85) painter.setPen(pen_color) brush_color = QColor(Qt.gray) brush_color.setAlphaF(.5) painter.setBrush(QBrush(brush_color)) painter.drawRect(self.make_slider_range(cursor_pos)) self._range_indicator_is_visible = True else: self._range_indicator_is_visible = False
def show_right_of_mouse(self, *args): pos = QCursor().pos() # mouse position szhint = self.sizeHint() pos -= QPoint(-14, szhint.height() / 4) self.move(pos) self.show()
def resize_to_contents(self): QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) self.dataTable.resizeColumnsToContents() self.dataModel.fetch_more(columns=True) self.dataTable.resizeColumnsToContents() QApplication.restoreOverrideCursor()
def _setBusyCursor(self, busy): if busy: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) else: QApplication.restoreOverrideCursor()
def import_data(self, filenames=None): """Import data from text file.""" title = _("Import data") if filenames is None: if self.filename is None: basedir = getcwd_or_home() else: basedir = osp.dirname(self.filename) filenames, _selfilter = getopenfilenames(self, title, basedir, iofunctions.load_filters) if not filenames: return elif is_text_string(filenames): filenames = [filenames] for filename in filenames: self.filename = to_text_string(filename) if os.name == "nt": self.filename = remove_backslashes(self.filename) ext = osp.splitext(self.filename)[1].lower() if ext not in iofunctions.load_funcs: buttons = QMessageBox.Yes | QMessageBox.Cancel answer = QMessageBox.question( self, title, _("<b>Unsupported file extension '%s'</b><br><br>" "Would you like to import it anyway " "(by selecting a known file format)?") % ext, buttons) if answer == QMessageBox.Cancel: return formats = list(iofunctions.load_extensions.keys()) item, ok = QInputDialog.getItem(self, title, _('Open file as:'), formats, 0, False) if ok: ext = iofunctions.load_extensions[to_text_string(item)] else: return load_func = iofunctions.load_funcs[ext] # 'import_wizard' (self.setup_io) if is_text_string(load_func): # Import data with import wizard error_message = None try: text, _encoding = encoding.read(self.filename) base_name = osp.basename(self.filename) editor = ImportWizard( self, text, title=base_name, varname=fix_reference_name(base_name)) if editor.exec_(): var_name, clip_data = editor.get_data() self.editor.new_value(var_name, clip_data) except Exception as error: error_message = str(error) else: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) QApplication.processEvents() error_message = self.shellwidget.load_data(self.filename, ext) QApplication.restoreOverrideCursor() QApplication.processEvents() if error_message is not None: QMessageBox.critical( self, title, _("<b>Unable to load '%s'</b>" "<br><br>" "The error message was:<br>%s") % (self.filename, error_message)) self.refresh_table()
def import_data(self, filenames=None): """Import data from text file""" title = _("Import data") if filenames is None: if self.filename is None: basedir = getcwd() else: basedir = osp.dirname(self.filename) filenames, _selfilter = getopenfilenames(self, title, basedir, iofunctions.load_filters) if not filenames: return elif is_text_string(filenames): filenames = [filenames] for filename in filenames: self.filename = to_text_string(filename) ext = osp.splitext(self.filename)[1].lower() if ext not in iofunctions.load_funcs: buttons = QMessageBox.Yes | QMessageBox.Cancel answer = QMessageBox.question( self, title, _("<b>Unsupported file extension '%s'</b><br><br>" "Would you like to import it anyway " "(by selecting a known file format)?") % ext, buttons) if answer == QMessageBox.Cancel: return formats = list(iofunctions.load_extensions.keys()) item, ok = QInputDialog.getItem(self, title, _('Open file as:'), formats, 0, False) if ok: ext = iofunctions.load_extensions[to_text_string(item)] else: return load_func = iofunctions.load_funcs[ext] # 'import_wizard' (self.setup_io) if is_text_string(load_func): # Import data with import wizard error_message = None try: text, _encoding = encoding.read(self.filename) if self.is_internal_shell: self.editor.import_from_string(text) else: base_name = osp.basename(self.filename) editor = ImportWizard( self, text, title=base_name, varname=fix_reference_name(base_name)) if editor.exec_(): var_name, clip_data = editor.get_data() monitor_set_global(self._get_sock(), var_name, clip_data) except Exception as error: error_message = str(error) else: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) QApplication.processEvents() if self.is_internal_shell: namespace, error_message = load_func(self.filename) interpreter = self.shellwidget.interpreter for key in list(namespace.keys()): new_key = fix_reference_name( key, blacklist=list(interpreter.namespace.keys())) if new_key != key: namespace[new_key] = namespace.pop(key) if error_message is None: interpreter.namespace.update(namespace) else: error_message = monitor_load_globals( self._get_sock(), self.filename, ext) QApplication.restoreOverrideCursor() QApplication.processEvents() if error_message is not None: QMessageBox.critical( self, title, _("<b>Unable to load '%s'</b>" "<br><br>Error message:<br>%s") % (self.filename, error_message)) self.refresh_table()
def __init__(self, viewer: ViewerModel, show_welcome_screen: bool = False): # Avoid circular import. from .layer_controls import QtLayerControlsContainer super().__init__() self._instances.add(self) self.setAttribute(Qt.WA_DeleteOnClose) self._show_welcome_screen = show_welcome_screen QCoreApplication.setAttribute( Qt.AA_UseStyleSheetPropagationInWidgetStyles, True ) self.viewer = viewer self.dims = QtDims(self.viewer.dims) self.controls = QtLayerControlsContainer(self.viewer) self.layers = QtLayerList(self.viewer.layers) self.layerButtons = QtLayerButtons(self.viewer) self.viewerButtons = QtViewerButtons(self.viewer) self._key_map_handler = KeymapHandler() self._key_map_handler.keymap_providers = [self.viewer] self._console = None layerList = QWidget() layerList.setObjectName('layerList') layerListLayout = QVBoxLayout() layerListLayout.addWidget(self.layerButtons) layerListLayout.addWidget(self.layers) layerListLayout.addWidget(self.viewerButtons) layerListLayout.setContentsMargins(8, 4, 8, 6) layerList.setLayout(layerListLayout) self.dockLayerList = QtViewerDockWidget( self, layerList, name=trans._('layer list'), area='left', allowed_areas=['left', 'right'], object_name='layer list', close_btn=False, ) self.dockLayerControls = QtViewerDockWidget( self, self.controls, name=trans._('layer controls'), area='left', allowed_areas=['left', 'right'], object_name='layer controls', close_btn=False, ) self.dockConsole = QtViewerDockWidget( self, QWidget(), name=trans._('console'), area='bottom', allowed_areas=['top', 'bottom'], object_name='console', close_btn=False, ) self.dockConsole.setVisible(False) # because the console is loaded lazily in the @getter, this line just # gets (or creates) the console when the dock console is made visible. self.dockConsole.visibilityChanged.connect(self._ensure_connect) # Only created if using perfmon. self.dockPerformance = self._create_performance_dock_widget() # This dictionary holds the corresponding vispy visual for each layer self.layer_to_visual = {} self._create_canvas() # Stacked widget to provide a welcome page self._canvas_overlay = QtWidgetOverlay(self, self.canvas.native) self._canvas_overlay.set_welcome_visible(show_welcome_screen) self._canvas_overlay.sig_dropped.connect(self.dropEvent) self._canvas_overlay.leave.connect(self._leave_canvas) self._canvas_overlay.enter.connect(self._enter_canvas) main_widget = QWidget() main_layout = QVBoxLayout() main_layout.setContentsMargins(0, 2, 0, 2) main_layout.addWidget(self._canvas_overlay) main_layout.addWidget(self.dims) main_layout.setSpacing(0) main_widget.setLayout(main_layout) self.setOrientation(Qt.Vertical) self.addWidget(main_widget) self._cursors = { 'cross': Qt.CrossCursor, 'forbidden': Qt.ForbiddenCursor, 'pointing': Qt.PointingHandCursor, 'standard': QCursor(), } self._on_active_change() self.viewer.layers.events.inserted.connect(self._update_welcome_screen) self.viewer.layers.events.removed.connect(self._update_welcome_screen) self.viewer.layers.selection.events.active.connect( self._on_active_change ) self.viewer.camera.events.interactive.connect(self._on_interactive) self.viewer.cursor.events.style.connect(self._on_cursor) self.viewer.cursor.events.size.connect(self._on_cursor) self.viewer.layers.events.reordered.connect(self._reorder_layers) self.viewer.layers.events.inserted.connect(self._on_add_layer_change) self.viewer.layers.events.removed.connect(self._remove_layer) self.setAcceptDrops(True) for layer in self.viewer.layers: self._add_layer(layer) self.view = self.canvas.central_widget.add_view(border_width=0) self.camera = VispyCamera( self.view, self.viewer.camera, self.viewer.dims ) self.canvas.events.draw.connect(self.camera.on_draw) # Add axes, scale bar self._add_visuals() # Create the experimental QtPool for octree and/or monitor. self._qt_poll = _create_qt_poll(self, self.viewer.camera) # Create the experimental RemoteManager for the monitor. self._remote_manager = _create_remote_manager( self.viewer.layers, self._qt_poll ) # moved from the old layerlist... still feels misplaced. # can you help me move this elsewhere? if config.async_loading: from .experimental.qt_chunk_receiver import QtChunkReceiver # The QtChunkReceiver object allows the ChunkLoader to pass newly # loaded chunks to the layers that requested them. self.chunk_receiver = QtChunkReceiver(self.layers) else: self.chunk_receiver = None # bind shortcuts stored in settings last. self._bind_shortcuts()
def __init__(self, viewer): super().__init__() QCoreApplication.setAttribute( Qt.AA_UseStyleSheetPropagationInWidgetStyles, True ) self.viewer = viewer self.dims = QtDims(self.viewer.dims) self.controls = QtControls(self.viewer) self.layers = QtLayerList(self.viewer.layers) self.buttons = QtLayersButtons(self.viewer) self.console = QtConsole({'viewer': self.viewer}) if self.console.shell is not None: self.console.style().unpolish(self.console) self.console.style().polish(self.console) self.console.hide() self.buttons.consoleButton.clicked.connect( lambda: self._toggle_console() ) else: self.buttons.consoleButton.setEnabled(False) self.canvas = SceneCanvas(keys=None, vsync=True) self.canvas.native.setMinimumSize(QSize(200, 200)) self.canvas.connect(self.on_mouse_move) self.canvas.connect(self.on_mouse_press) self.canvas.connect(self.on_mouse_release) self.canvas.connect(self.on_key_press) self.canvas.connect(self.on_key_release) self.canvas.connect(self.on_draw) self.view = self.canvas.central_widget.add_view() self._update_camera() center = QWidget() center_layout = QVBoxLayout() center_layout.setContentsMargins(15, 20, 15, 10) center_layout.addWidget(self.canvas.native) center_layout.addWidget(self.dims) center.setLayout(center_layout) right = QWidget() right_layout = QVBoxLayout() right_layout.addWidget(self.layers) right_layout.addWidget(self.buttons) right.setLayout(right_layout) right.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding) left = self.controls top = QWidget() top_layout = QHBoxLayout() top_layout.addWidget(left) top_layout.addWidget(center) top_layout.addWidget(right) top.setLayout(top_layout) self.setOrientation(Qt.Vertical) self.addWidget(top) if self.console.shell is not None: self.addWidget(self.console) self._last_visited_dir = str(Path.home()) self._cursors = { 'disabled': QCursor( QPixmap(':/icons/cursor/cursor_disabled.png').scaled(20, 20) ), 'cross': Qt.CrossCursor, 'forbidden': Qt.ForbiddenCursor, 'pointing': Qt.PointingHandCursor, 'standard': QCursor(), } self._update_palette(viewer.palette) self._key_release_generators = {} self.viewer.events.interactive.connect(self._on_interactive) self.viewer.events.cursor.connect(self._on_cursor) self.viewer.events.reset_view.connect(self._on_reset_view) self.viewer.events.palette.connect( lambda event: self._update_palette(event.palette) ) self.viewer.layers.events.reordered.connect(self._update_canvas) self.viewer.dims.events.display.connect( lambda event: self._update_camera() ) self.setAcceptDrops(True)
def __init__(self, viewer, welcome=False): # Avoid circular import. from .layer_controls import QtLayerControlsContainer super().__init__() self.setAttribute(Qt.WA_DeleteOnClose) QCoreApplication.setAttribute( Qt.AA_UseStyleSheetPropagationInWidgetStyles, True ) self.viewer = viewer self.dims = QtDims(self.viewer.dims) self.controls = QtLayerControlsContainer(self.viewer) self.layers = QtLayerList(self.viewer.layers) self.layerButtons = QtLayerButtons(self.viewer) self.viewerButtons = QtViewerButtons(self.viewer) self._key_map_handler = KeymapHandler() self._key_map_handler.keymap_providers = [self.viewer] self._active_layer = None self._console = None layerList = QWidget() layerList.setObjectName('layerList') layerListLayout = QVBoxLayout() layerListLayout.addWidget(self.layerButtons) layerListLayout.addWidget(self.layers) layerListLayout.addWidget(self.viewerButtons) layerListLayout.setContentsMargins(8, 4, 8, 6) layerList.setLayout(layerListLayout) self.dockLayerList = QtViewerDockWidget( self, layerList, name='layer list', area='left', allowed_areas=['left', 'right'], ) self.dockLayerControls = QtViewerDockWidget( self, self.controls, name='layer controls', area='left', allowed_areas=['left', 'right'], ) self.dockConsole = QtViewerDockWidget( self, QWidget(), name='console', area='bottom', allowed_areas=['top', 'bottom'], shortcut='Ctrl+Shift+C', ) self.dockConsole.setVisible(False) # because the console is loaded lazily in the @getter, this line just # gets (or creates) the console when the dock console is made visible. self.dockConsole.visibilityChanged.connect( lambda visible: self.console if visible else None ) self.dockLayerControls.visibilityChanged.connect(self._constrain_width) self.dockLayerList.setMaximumWidth(258) self.dockLayerList.setMinimumWidth(258) # Only created if using perfmon. self.dockPerformance = self._create_performance_dock_widget() # This dictionary holds the corresponding vispy visual for each layer self.layer_to_visual = {} self.viewerButtons.consoleButton.clicked.connect( self.toggle_console_visibility ) self._create_canvas() main_widget = QWidget() main_layout = QVBoxLayout() main_layout.setContentsMargins(10, 22, 10, 2) main_layout.addWidget(self.canvas.native) main_layout.addWidget(self.dims) main_layout.setSpacing(10) main_widget.setLayout(main_layout) self.setOrientation(Qt.Vertical) self.addWidget(main_widget) self._last_visited_dir = str(Path.home()) self._cursors = { 'cross': Qt.CrossCursor, 'forbidden': Qt.ForbiddenCursor, 'pointing': Qt.PointingHandCursor, 'standard': QCursor(), } self._update_theme() self._on_active_layer_change() self.viewer.events.active_layer.connect(self._on_active_layer_change) self.viewer.events.theme.connect(self._update_theme) self.viewer.camera.events.interactive.connect(self._on_interactive) self.viewer.cursor.events.style.connect(self._on_cursor) self.viewer.cursor.events.size.connect(self._on_cursor) self.viewer.layers.events.reordered.connect(self._reorder_layers) self.viewer.layers.events.inserted.connect(self._on_add_layer_change) self.viewer.layers.events.removed.connect(self._remove_layer) # stop any animations whenever the layers change self.viewer.events.layers_change.connect(lambda x: self.dims.stop()) self.setAcceptDrops(True) for layer in self.viewer.layers: self._add_layer(layer) self.view = self.canvas.central_widget.add_view() self.camera = VispyCamera( self.view, self.viewer.camera, self.viewer.dims ) self.canvas.connect(self.camera.on_draw) # Add axes, scale bar and welcome visuals. self._add_visuals(welcome) # Create the experimental QtPool for octree and/or monitor. self._qt_poll = _create_qt_poll(self, self.viewer.camera) # Create the experimental RemoteManager for the monitor. self._remote_manager = _create_remote_manager( self.viewer.layers, self._qt_poll )
def paintEvent(self, event): """ Override Qt method. Painting the scroll flag area There is two cases: - The scroll bar is moving, in which case paint all flags. - The scroll bar is not moving, only paint flags corresponding to visible lines. """ # The area in which the slider handle of the scrollbar may move. groove_rect = self.get_scrollbar_groove_rect() # The scrollbar's scale factor ratio between pixel span height and # value span height scale_factor = groove_rect.height() / self.get_scrollbar_value_height() # The vertical offset of the scroll flag area relative to the # top of the text editor. offset = groove_rect.y() # Note that we calculate the pixel metrics required to draw the flags # here instead of using the convenience methods of the ScrollFlagArea # for performance reason. rect_x = ceil(self.FLAGS_DX / 2) rect_w = self.WIDTH - self.FLAGS_DX rect_h = self.FLAGS_DY # Fill the whole painting area painter = QPainter(self) painter.fillRect(event.rect(), self.editor.sideareas_color) editor = self.editor # Define compute_flag_ypos to position the flags: # Paint flags for the entire document last_line = editor.document().lastBlock().firstLineNumber() # The 0.5 offset is used to align the flags with the center of # their corresponding text edit block before scaling. first_y_pos = self.value_to_position(0.5, scale_factor, offset) - self.FLAGS_DY / 2 last_y_pos = self.value_to_position(last_line + 0.5, scale_factor, offset) - self.FLAGS_DY / 2 def compute_flag_ypos(block): line_number = block.firstLineNumber() if editor.verticalScrollBar().maximum() == 0: geometry = editor.blockBoundingGeometry(block) pos = geometry.y() + geometry.height() / 2 + self.FLAGS_DY / 2 elif last_line != 0: frac = line_number / last_line pos = first_y_pos + frac * (last_y_pos - first_y_pos) else: pos = first_y_pos return ceil(pos) # All the lists of block numbers for flags dict_flag_lists = { "occurrence": editor.occurrences, "found_results": editor.found_results } dict_flag_lists.update(self._dict_flag_list) for flag_type in dict_flag_lists: painter.setBrush(self._facecolors[flag_type]) painter.setPen(self._edgecolors[flag_type]) for block_number in dict_flag_lists[flag_type]: # Find the block block = editor.document().findBlockByNumber(block_number) if not block.isValid(): continue # paint if everything else is fine rect_y = compute_flag_ypos(block) painter.drawRect(rect_x, rect_y, rect_w, rect_h) # Paint the slider range if not self._unit_testing: alt = QApplication.queryKeyboardModifiers() & Qt.AltModifier else: alt = self._alt_key_is_down if self.slider: cursor_pos = self.mapFromGlobal(QCursor().pos()) is_over_self = self.rect().contains(cursor_pos) is_over_editor = editor.rect().contains( editor.mapFromGlobal(QCursor().pos())) # We use QRect.contains instead of QWidget.underMouse method to # determined if the cursor is over the editor or the flag scrollbar # because the later gives a wrong result when a mouse button # is pressed. if is_over_self or (alt and is_over_editor): painter.setPen(self._slider_range_color) painter.setBrush(self._slider_range_brush) x, y, width, height = self.make_slider_range( cursor_pos, scale_factor, offset, groove_rect) painter.drawRect(x, y, width, height) self._range_indicator_is_visible = True else: self._range_indicator_is_visible = False