Beispiel #1
0
    def _add_normalization_option_menu(self, menu, ax):
        # Check if toggling normalization makes sense
        can_toggle_normalization = self._can_toggle_normalization(ax)
        if not can_toggle_normalization:
            return None

        # Create menu
        norm_menu = QMenu("Normalization", menu)
        norm_actions_group = QActionGroup(norm_menu)
        none_action = norm_menu.addAction(
            'None', lambda: self._set_normalization_none(ax))
        norm_action = norm_menu.addAction(
            'Bin Width', lambda: self._set_normalization_bin_width(ax))
        for action in [none_action, norm_action]:
            norm_actions_group.addAction(action)
            action.setCheckable(True)

        # Update menu state
        is_normalized = self._is_normalized(ax)
        if is_normalized:
            norm_action.setChecked(True)
        else:
            none_action.setChecked(True)

        menu.addMenu(norm_menu)
Beispiel #2
0
    def _add_plot_type_option_menu(self, menu, ax):
        with errorbar_caps_removed(ax):
            # Able to change the plot type to waterfall if there is only one axes, it is a MantidAxes, and there is more
            # than one line on the axes.
            if len(ax.get_figure().get_axes()) > 1 or not isinstance(
                    ax, MantidAxes) or len(ax.get_lines()) <= 1:
                return

        plot_type_menu = QMenu("Plot Type", menu)
        plot_type_action_group = QActionGroup(plot_type_menu)
        standard = plot_type_menu.addAction(
            "1D", lambda: self._change_plot_type(
                ax, plot_type_action_group.checkedAction()))
        waterfall = plot_type_menu.addAction(
            "Waterfall", lambda: self._change_plot_type(
                ax, plot_type_action_group.checkedAction()))

        for action in [waterfall, standard]:
            plot_type_action_group.addAction(action)
            action.setCheckable(True)

        if ax.is_waterfall():
            waterfall.setChecked(True)
        else:
            standard.setChecked(True)

        menu.addMenu(plot_type_menu)
Beispiel #3
0
    def _add_plot_type_option_menu(self, menu, ax):
        # Error bar caps are considered lines so they are removed before checking the number of lines on the axes so
        # they aren't confused for "actual" lines.
        error_bar_caps = datafunctions.remove_and_return_errorbar_cap_lines(ax)

        # Able to change the plot type to waterfall if there is only one axes, it is a MantidAxes, and there is more
        # than one line on the axes.
        if len(ax.get_figure().get_axes()) > 1 or not isinstance(
                ax, MantidAxes) or len(ax.get_lines()) <= 1:
            return

        # Re-add error bar caps
        ax.lines += error_bar_caps

        plot_type_menu = QMenu("Plot Type", menu)
        plot_type_action_group = QActionGroup(plot_type_menu)
        standard = plot_type_menu.addAction(
            "1D", lambda: self._change_plot_type(
                ax, plot_type_action_group.checkedAction()))
        waterfall = plot_type_menu.addAction(
            "Waterfall", lambda: self._change_plot_type(
                ax, plot_type_action_group.checkedAction()))

        for action in [waterfall, standard]:
            plot_type_action_group.addAction(action)
            action.setCheckable(True)

        if ax.is_waterfall():
            waterfall.setChecked(True)
        else:
            standard.setChecked(True)

        menu.addMenu(plot_type_menu)
Beispiel #4
0
    def menu_actions(self):
        """
        List of QtWidgets.QActions to be attached to this tool
        as a context menu.
        """
        self.options = []

        component_action_group = QActionGroup(self.tool_bar)

        action = QAction("Off", self.tool_bar, checkable=True)
        action.setChecked(True)
        action.setActionGroup(component_action_group)
        action.triggered.connect(self.viewer.remove_contour)
        self.options.append(action)

        action = QAction("Current Component", self.tool_bar, checkable=True)
        action.setActionGroup(component_action_group)
        action.triggered.connect(self.viewer.default_contour)
        self.options.append(action)

        action = QAction("Custom Component", self.tool_bar, checkable=True)
        action.setActionGroup(component_action_group)
        action.triggered.connect(self.viewer.custom_contour)
        self.options.append(action)

        action = QAction(" ", self.tool_bar)
        action.setSeparator(True)
        self.options.append(action)

        action = QAction("Contour Settings", self.tool_bar)
        action.triggered.connect(self.viewer.edit_contour_settings)
        self.options.append(action)

        return self.options
Beispiel #5
0
    def _add_marker_option_menu(self, menu, event):
        """
        Entry in main context menu to:
         - add horizontal/vertical markers
         - open a marker editor window.
        The editor window allows editing of all currently plotted markers
        :param menu: instance of QMenu to append this submenu to
        :param event: mpl event that generated the call
        """
        marker_menu = QMenu("Markers", menu)
        marker_action_group = QActionGroup(marker_menu)
        x0, x1 = event.inaxes.get_xlim()
        y0, y1 = event.inaxes.get_ylim()
        horizontal = marker_menu.addAction(
            "Horizontal", lambda: self._add_horizontal_marker(
                event.ydata, y0, y1, event.inaxes))
        vertical = marker_menu.addAction(
            "Vertical", lambda: self._add_vertical_marker(
                event.xdata, x0, x1, event.inaxes))
        edit = marker_menu.addAction("Edit",
                                     lambda: self._global_edit_markers())

        for action in [horizontal, vertical, edit]:
            marker_action_group.addAction(action)

        menu.addMenu(marker_menu)
Beispiel #6
0
    def __init__(self, parent=None, image_channel=None, width_channel=None):
        """Initialize widget."""
        # Set the default colormap.
        self._colormap = PyDMColorMap.Inferno
        self._cm_colors = None
        self._imagechannel = None
        self._widthchannel = None
        self.image_waveform = np.zeros(0)
        self._image_width = 0
        self._normalize_data = False
        self._auto_downsample = True
        self._show_axes = False

        # Set default reading order of numpy array data to Fortranlike.
        self._reading_order = ReadingOrder.Fortranlike

        self._redraw_rate = 30

        # Set color map limits.
        self.cm_min = 0.0
        self.cm_max = 255.0

        plot_item = PlotItem()
        ImageView.__init__(self, parent, view=plot_item)
        PyDMWidget.__init__(self)
        self._channels = [None, None]
        self.thread = None
        self.axes = dict({'t': None, "x": 0, "y": 1, "c": None})
        self.showAxes = self._show_axes
        self.imageItem.setOpts(axisOrder="row-major")

        # Hide some itens of the widget.
        self.ui.histogram.hide()
        self.getImageItem().sigImageChanged.disconnect(
            self.ui.histogram.imageChanged)
        self.ui.roiBtn.hide()
        self.ui.menuBtn.hide()

        # Make a right-click menu for changing the color map.
        self.cm_group = QActionGroup(self)
        self.cmap_for_action = {}
        for cm in self.color_maps:
            action = self.cm_group.addAction(cmap_names[cm])
            action.setCheckable(True)
            self.cmap_for_action[action] = cm

        self.colorMap = self._colormap

        # Setup the redraw timer.
        self.needs_redraw = False
        self.redraw_timer = QTimer(self)
        self.redraw_timer.timeout.connect(self.redrawImage)
        self.maxRedrawRate = self._redraw_rate
        self.newImageSignal = self.getImageItem().sigImageChanged
        # Set live channels if requested on initialization
        if image_channel:
            self.imageChannel = image_channel or ''
        if width_channel:
            self.widthChannel = width_channel or ''
Beispiel #7
0
 def get_tool_group(self, groupname):
     group = self.groups.get(groupname, None)
     if group is None:
         group = QActionGroup(self.main)
         self.groups[groupname] = weakref.ref(group)
         return group
     else:
         return group()
Beispiel #8
0
    def __init__(self, parent=None, standalone=False):
        super(Camera, self).__init__(parent)

        # This prevents doing unneeded initialization
        # when QtDesginer loads the plugin.
        if parent is None and not standalone:
            return

        if not multimedia_available:
            return

        self.ui = uic.loadUi(os.path.join(WIDGET_PATH, "camera.ui"), self)

        self.camera = None
        self.imageCapture = None
        self.mediaRecorder = None
        self.isCapturingImage = False
        self.applicationExiting = False

        self.imageSettings = QImageEncoderSettings()
        self.audioSettings = QAudioEncoderSettings()
        self.videoSettings = QVideoEncoderSettings()
        self.videoContainerFormat = ''

        camera_device = QByteArray()

        videoDevicesGroup = QActionGroup(self)

        videoDevicesGroup.setExclusive(True)

        if not QCamera.availableDevices():
            self.ui.devicesCombo.addItem("No Device")
        else:
            for deviceName in QCamera.availableDevices():
                description = QCamera.deviceDescription(deviceName)
                self.ui.devicesCombo.addItem(description)

                videoDeviceAction = QAction(description, videoDevicesGroup)
                videoDeviceAction.setCheckable(True)
                videoDeviceAction.setData(deviceName)

                if camera_device.isEmpty():
                    cameraDevice = deviceName
                    videoDeviceAction.setChecked(True)

                self.ui.devicesCombo.addAction(videoDeviceAction)

        videoDevicesGroup.triggered.connect(self.updateCameraDevice)

        self.ui.captureWidget.currentChanged.connect(self.updateCaptureMode)

        self.ui.devicesCombo.currentIndexChanged.connect(self.get_device_action)

        self.ui.lockButton.hide()
        
        if not IN_DESIGNER:
            # Start camera 2s after the UI has loaded
            QTimer.singleShot(2000, lambda: self.setCamera(camera_device))
Beispiel #9
0
    def _init_menu_buttons(self):
        """
        Add the two menu buttons to the tool bar. Currently two are defined:
            View - for changing the view of the active window
            Data Processing - for applying a data processing step to the data.

        :return:
        """
        self._option_buttons = [
            self.ui.view_option_button, self.ui.cube_option_button
        ]

        # Create the View Menu
        view_menu = self._dict_to_menu(
            OrderedDict([
                ('Hide Axes', ['checkable', self._toggle_viewer_axes]),
                ('Hide Toolbars', ['checkable', self._toggle_toolbars]),
                ('Hide Spaxel Value Tooltip',
                 ['checkable', self._toggle_hover_value]),
                ('Hide Stats', ['checkable', self._toggle_stats_display]),
                ('Convert Flux Units',
                 lambda: self._open_dialog('Convert Flux Units', None)),
                ('Wavelength Units/Redshift',
                 lambda: self._open_dialog('Wavelength Units/Redshift', None))
            ]))

        # Add toggle RA-DEC format:
        format_menu = view_menu.addMenu("RA-DEC Format")
        format_action_group = QActionGroup(format_menu)
        self.ra_dec_format_menu = format_menu

        # Make sure to change all instances of the the names
        # of the formats if modifications are made to them.
        for format_name in ["Sexagesimal", "Decimal Degrees"]:
            act = QAction(format_name, format_menu)
            act.triggered.connect(self._toggle_all_coords_in_degrees)
            act.setActionGroup(format_action_group)
            act.setCheckable(True)
            act.setChecked(
                True) if format == "Sexagesimal" else act.setChecked(False)
            format_menu.addAction(act)

        self.ui.view_option_button.setMenu(view_menu)

        # Create the Data Processing Menu
        cube_menu = self._dict_to_menu(
            OrderedDict([
                ('Collapse Cube',
                 lambda: self._open_dialog('Collapse Cube', None)),
                ('Spatial Smoothing',
                 lambda: self._open_dialog('Spatial Smoothing', None)),
                ('Moment Maps',
                 lambda: self._open_dialog('Moment Maps', None)),
                ('Arithmetic Operations',
                 lambda: self._open_dialog('Arithmetic Operations', None))
            ]))
        self.ui.cube_option_button.setMenu(cube_menu)
Beispiel #10
0
    def __init__(self, *args, menuBar, **kwargs):
        super().__init__(*args, **kwargs)
        self._run_to_tabs = collections.defaultdict(list)
        self._title_to_tab = {}
        self._tabs_from_streaming = []
        self._overplot = OverPlotState.individual_tab
        self._overplot_target = None
        self._live_enabled = False

        self._live_run_router = RunRouter([self.route_live_stream])

        self._containers = [TabbedViewingArea(self, menuBar=menuBar) for _ in range(2)]
        layout = QVBoxLayout()
        for container in self._containers:
            layout.addWidget(container)
        self.setLayout(layout)

        overplot_group = QActionGroup(self)
        self.off = QAction('&Off', self)
        self.off.setStatusTip('Drop streaming data.')
        self.individual_tab = QAction('&New Tab', self)
        self.individual_tab.setStatusTip('Open a new viewer tab for each Run.')
        self.latest_live = QAction('&Latest Live Tab', self)
        self.latest_live.setStatusTip('Attempt to overplot on the most recent live Run.')
        self.fixed = QAction('&Fixed Tab...', self)
        self.fixed.setStatusTip('Attempt to overplot on a specific tab.')
        self.fixed.setEnabled(False)
        overplot_group.addAction(self.off)
        overplot_group.addAction(self.individual_tab)
        overplot_group.addAction(self.latest_live)
        overplot_group.addAction(self.fixed)
        for action in overplot_group.actions():
            action.setCheckable(True)
        overplot_group.setExclusive(True)
        self.off.setChecked(True)

        overplot_menu = menuBar().addMenu('&Streaming')
        overplot_menu.addActions(overplot_group.actions())

        self.off.triggered.connect(self.disable_live)
        self.individual_tab.triggered.connect(partial(self.set_overplot_state, OverPlotState.individual_tab))
        self.latest_live.triggered.connect(partial(self.set_overplot_state, OverPlotState.latest_live))

        def set_overplot_target():
            item, ok = QInputDialog.getItem(
                self, "Select Tab", "Tab", tuple(self._title_to_tab), 0, False)
            if not ok:
                # Abort and fallback to Off. Would be better to fall back to
                # previous state (which could be latest_live) but it's not
                # clear how to know what that state was.
                self.off.setChecked(True)
                return
            self.set_overplot_state(OverPlotState.fixed)
            self._overplot_target = item

        self.fixed.triggered.connect(set_overplot_target)
Beispiel #11
0
    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
Beispiel #12
0
 def _add_axes_scale_menu(self, menu):
     """Add the Axes scale options menu to the given menu"""
     axes_menu = QMenu("Axes", menu)
     axes_actions = QActionGroup(axes_menu)
     current_scale_types = self._get_axes_scale_types()
     for label, scale_types in iteritems(AXES_SCALE_MENU_OPTS):
         action = axes_menu.addAction(label, partial(self._quick_change_axes, scale_types))
         if current_scale_types == scale_types:
             action.setCheckable(True)
             action.setChecked(True)
         axes_actions.addAction(action)
     menu.addMenu(axes_menu)
 def _add_colorbar_axes_scale_menu(self, menu, ax):
     """Add the Axes scale options menu to the given menu"""
     axes_menu = QMenu("Color bar", menu)
     axes_actions = QActionGroup(axes_menu)
     images = ax.get_images() + [col for col in ax.collections if isinstance(col, Collection)]
     for label, scale_type in COLORBAR_SCALE_MENU_OPTS.items():
         action = axes_menu.addAction(label, partial(self._change_colorbar_axes, scale_type))
         if type(images[0].norm) == scale_type:
             action.setCheckable(True)
             action.setChecked(True)
         axes_actions.addAction(action)
     menu.addMenu(axes_menu)
    def _single_marker_menu(self, menu, marker):
        """
        Entry in a menu that allows editing/deleting a single marker
        :param menu: instance of QMenu to add this submenu to
        :param marker: marker to be edited with the menu
        """
        marker_menu = QMenu(marker.name, menu)
        marker_action_group = QActionGroup(marker_menu)

        delete = marker_menu.addAction("Delete", lambda: self._delete_marker(marker))
        edit = marker_menu.addAction("Edit", lambda: self._edit_marker(marker))

        for action in [delete, edit]:
            marker_action_group.addAction(action)

        menu.addMenu(marker_menu)
Beispiel #15
0
    def add_header_context_menu(self,
                                checked=None,
                                checkable=None,
                                enabled=None):
        """
        Adds the context menu from using header information

        checked can be a header_name -> boolean dictionary. If given, headers
        with the key name will get the checked value from the dictionary.
        The corresponding column will be hidden if checked is False.

        checkable can be a header_name -> boolean dictionary. If given, headers
        with the key name will get the checkable value from the dictionary.

        enabled can be a header_name -> boolean dictionary. If given, headers
        with the key name will get the enabled value from the dictionary.
        """
        checked = checked if checked is not None else {}
        checkable = checkable if checkable is not None else {}
        enabled = enabled if enabled is not None else {}

        horizontal_header = self._horizontal_header()
        horizontal_header.setContextMenuPolicy(Qt.ActionsContextMenu)

        self.toggle_column_actions_group = QActionGroup(self)
        self.toggle_column_actions_group.setExclusive(False)
        self.__toggle_functions = []  # for keeping references

        for col in range(horizontal_header.count()):
            column_label = self.model().headerData(col, Qt.Horizontal,
                                                   Qt.DisplayRole)
            logger.debug("Adding: col {}: {}".format(col, column_label))
            action = QAction(str(column_label),
                             self.toggle_column_actions_group,
                             checkable=checkable.get(column_label, True),
                             enabled=enabled.get(column_label, True),
                             toolTip=_("Shows or hides "
                                       "the {} column").format(column_label))
            func = self.__make_show_column_function(col)
            self.__toggle_functions.append(func)  # keep reference
            horizontal_header.addAction(action)
            is_checked = checked.get(
                column_label, not horizontal_header.isSectionHidden(col))
            horizontal_header.setSectionHidden(col, not is_checked)
            action.setChecked(is_checked)
            action.toggled.connect(func)
Beispiel #16
0
    def __init__(self):
        super(pluginModeWidget, self).__init__()

        self.GUIPluginActionGroup = QActionGroup(self)

        # Setup font
        self.font = QFont("Zero Threes")
        self.font.setPointSize(16)

        # Align right
        self.setLayoutDirection(Qt.RightToLeft)

        # Subscribe to plugins
        pluginmanager.attach(self.pluginsChanged)

        self._nodes = []

        # Build children
        self.pluginsChanged()
    def _add_plot_type_option_menu(self, menu, ax):
        plot_type_menu = QMenu("Plot Type", menu)
        plot_type_action_group = QActionGroup(plot_type_menu)
        standard = plot_type_menu.addAction(
            "1D", lambda: self._change_plot_type(
                ax, plot_type_action_group.checkedAction()))
        waterfall = plot_type_menu.addAction(
            "Waterfall", lambda: self._change_plot_type(
                ax, plot_type_action_group.checkedAction()))

        for action in [waterfall, standard]:
            plot_type_action_group.addAction(action)
            action.setCheckable(True)

        if ax.is_waterfall():
            waterfall.setChecked(True)
        else:
            standard.setChecked(True)

        menu.addMenu(plot_type_menu)
Beispiel #18
0
    def generateContextMenu(self):
        """
        Generate the window's context menu. This first calls the base class's
        context menu generator and then extends it with the filtering options.
        """
        qmenu = super(MessageDisplay, self).generateContextMenu()
        filter_menu = qmenu.addMenu("&View")

        framework_action = QAction('Mantid Log Output', filter_menu)
        framework_action.triggered.connect(self.toggle_filter_framework_output)
        framework_action.setCheckable(True)
        framework_action.setChecked(self.showFrameworkOutput())
        filter_menu.addAction(framework_action)

        filter_menu.addSeparator()

        actions_to_group = []
        active_script_action = QAction("Active Tab Output", filter_menu)
        active_script_action.triggered.connect(self.show_active_script)
        actions_to_group.append(active_script_action)
        all_script_action = QAction('All Script Output', filter_menu)
        all_script_action.triggered.connect(self.show_all_scripts)
        actions_to_group.append(all_script_action)
        hide_all_script_action = QAction("Hide All Script Output", filter_menu)
        hide_all_script_action.triggered.connect(self.hide_all_scripts)
        actions_to_group.append(hide_all_script_action)

        action_group = QActionGroup(filter_menu)
        for action in actions_to_group:
            action_group.addAction(action)
            filter_menu.addAction(action)
            action.setCheckable(True)

        if self.showAllScriptOutput():
            all_script_action.setChecked(True)
        elif self.showActiveScriptOutput():
            active_script_action.setChecked(True)
        else:
            hide_all_script_action.setChecked(True)
        return qmenu
Beispiel #19
0
    def __init__(self, parent=None):
        super(RedisWindow, self).__init__(parent)
        self.load_ui()
        ui = self.ui
        redis_icon = QIcon(_redis_icon)
        self.setWindowIcon(redis_icon)
        self.about_dialog = AboutDialog()

        ui.open_db_action.setIcon(redis_icon)
        ui.open_db_action.triggered.connect(self._on_open_db)
        ui.restart_action.triggered.connect(restart)
        ui.quit_action.triggered.connect(QApplication.quit)
        ui.about_action.triggered.connect(lambda: self.about_dialog.exec_())

        ui.window_mode_action_group = group = QActionGroup(self)
        ui.tabbed_view_action.setActionGroup(group)
        ui.tabbed_view_action.setData(QMdiArea.TabbedView)
        ui.window_view_action.setActionGroup(group)
        ui.window_view_action.setData(QMdiArea.SubWindowView)
        group.triggered.connect(self._on_switch_window_mode)
        self.set_view_mode(QMdiArea.TabbedView)
        ui.tabbed_view_action.setChecked(True)
Beispiel #20
0
    def menu_actions(self):
        """
        List of QtWidgets.QActions to be attached to this tool
        as a context menu.
        """
        self.options = []

        # WARNING: QAction labels are used to identify them.
        #          Changing them can cause problems unless
        #          all references are updated in this package.
        component_action_group = QActionGroup(self.tool_bar)

        action = QAction("Off", self.tool_bar, checkable=True)
        action.setChecked(True)
        action.setActionGroup(component_action_group)
        action.triggered.connect(self.viewer.remove_contour)
        self.options.append(action)

        action = QAction("Current Component", self.tool_bar, checkable=True)
        action.setActionGroup(component_action_group)
        action.triggered.connect(self.viewer.default_contour)
        self.options.append(action)

        action = QAction("Other Component", self.tool_bar, checkable=True)
        action.setActionGroup(component_action_group)
        action.triggered.connect(self.viewer.custom_contour)
        self.options.append(action)

        action = QAction(" ", self.tool_bar)
        action.setSeparator(True)
        self.options.append(action)

        action = QAction("Contour Settings", self.tool_bar)
        action.triggered.connect(self.viewer.edit_contour_settings)
        self.options.append(action)

        return self.options
Beispiel #21
0
    def __init__(self, parent=None, css_path=CSS_PATH):
        SpyderPluginWidget.__init__(self, parent)

        self.internal_shell = None
        self.console = None
        self.css_path = css_path

        self.no_doc_string = _("No documentation available")

        self._last_console_cb = None
        self._last_editor_cb = None

        self.plain_text = PlainText(self)
        self.rich_text = RichText(self)

        color_scheme = self.get_color_scheme()
        self.set_plain_text_font(self.get_font(), color_scheme)
        self.plain_text.editor.toggle_wrap_mode(self.get_option('wrap'))

        # Add entries to read-only editor context-menu
        self.wrap_action = create_action(self, _("Wrap lines"),
                                         toggled=self.toggle_wrap_mode)
        self.wrap_action.setChecked(self.get_option('wrap'))
        self.plain_text.editor.readonly_menu.addSeparator()
        add_actions(self.plain_text.editor.readonly_menu, (self.wrap_action,))

        self.set_rich_text_font(self.get_font(rich_text=True))

        self.shell = None

        # locked = disable link with Console
        self.locked = False
        self._last_texts = [None, None]
        self._last_editor_doc = None

        # Object name
        layout_edit = QHBoxLayout()
        layout_edit.setContentsMargins(0, 0, 0, 0)
        txt = _("Source")
        if sys.platform == 'darwin':
            source_label = QLabel("  " + txt)
        else:
            source_label = QLabel(txt)
        layout_edit.addWidget(source_label)
        self.source_combo = QComboBox(self)
        self.source_combo.addItems([_("Console"), _("Editor")])
        self.source_combo.currentIndexChanged.connect(self.source_changed)
        if (not programs.is_module_installed('rope') and
                not programs.is_module_installed('jedi', '>=0.11.0')):
            self.source_combo.hide()
            source_label.hide()
        layout_edit.addWidget(self.source_combo)
        layout_edit.addSpacing(10)
        layout_edit.addWidget(QLabel(_("Object")))
        self.combo = ObjectComboBox(self)
        layout_edit.addWidget(self.combo)
        self.object_edit = QLineEdit(self)
        self.object_edit.setReadOnly(True)
        layout_edit.addWidget(self.object_edit)
        self.combo.setMaxCount(self.get_option('max_history_entries'))
        self.combo.addItems( self.load_history() )
        self.combo.setItemText(0, '')
        self.combo.valid.connect(self.force_refresh)

        # Plain text docstring option
        self.docstring = True
        self.rich_help = self.get_option('rich_mode', True)
        self.plain_text_action = create_action(self, _("Plain Text"),
                                               toggled=self.toggle_plain_text)

        # Source code option
        self.show_source_action = create_action(self, _("Show Source"),
                                                toggled=self.toggle_show_source)

        # Rich text option
        self.rich_text_action = create_action(self, _("Rich Text"),
                                         toggled=self.toggle_rich_text)

        # Add the help actions to an exclusive QActionGroup
        help_actions = QActionGroup(self)
        help_actions.setExclusive(True)
        help_actions.addAction(self.plain_text_action)
        help_actions.addAction(self.rich_text_action)

        # Automatic import option
        self.auto_import_action = create_action(self, _("Automatic import"),
                                                toggled=self.toggle_auto_import)
        auto_import_state = self.get_option('automatic_import')
        self.auto_import_action.setChecked(auto_import_state)

        # Lock checkbox
        self.locked_button = create_toolbutton(self,
                                               triggered=self.toggle_locked)
        layout_edit.addWidget(self.locked_button)
        self._update_lock_icon()

        # Option menu
        layout_edit.addWidget(self.options_button)

        if self.rich_help:
            self.switch_to_rich_text()
        else:
            self.switch_to_plain_text()
        self.plain_text_action.setChecked(not self.rich_help)
        self.rich_text_action.setChecked(self.rich_help)
        self.source_changed()

        # Main layout
        layout = create_plugin_layout(layout_edit)
        # we have two main widgets, but only one of them is shown at a time
        layout.addWidget(self.plain_text)
        layout.addWidget(self.rich_text)
        self.setLayout(layout)

        # Add worker thread for handling rich text rendering
        self._sphinx_thread = SphinxThread(
                              html_text_no_doc=warning(self.no_doc_string,
                                                       css_path=self.css_path),
                              css_path=self.css_path)
        self._sphinx_thread.html_ready.connect(
                                             self._on_sphinx_thread_html_ready)
        self._sphinx_thread.error_msg.connect(self._on_sphinx_thread_error_msg)

        # Handle internal and external links
        view = self.rich_text.webview
        if not WEBENGINE:
            view.page().setLinkDelegationPolicy(QWebEnginePage.DelegateAllLinks)
        view.linkClicked.connect(self.handle_link_clicks)

        self._starting_up = True
Beispiel #22
0
    def __init__(self, model, *args, **kwargs):
        super(PlotWindow, self).__init__(*args, **kwargs)
        # Hide the icon in the title bar
        self.setWindowIcon(qta.icon('fa.circle', opacity=0))

        # The central widget of the sub window will be a main window so that it
        # can support having tab bars
        self._central_widget = QMainWindow()
        self.setWidget(self._central_widget)

        loadUi(os.path.join(os.path.dirname(__file__), "ui", "plot_window.ui"),
               self._central_widget)

        # The central widget of the main window widget will be the plot
        self._model = model
        self._current_item_index = None

        self._plot_widget = PlotWidget(model=self._model)
        self._plot_widget.plotItem.setMenuEnabled(False)

        self._central_widget.setCentralWidget(self._plot_widget)

        # Setup action group for interaction modes
        mode_group = QActionGroup(self.tool_bar)
        mode_group.addAction(self._central_widget.pan_mode_action)
        self._central_widget.pan_mode_action.setChecked(True)
        mode_group.addAction(self._central_widget.zoom_mode_action)

        def _toggle_mode(state):
            view_state = self.plot_widget.plotItem.getViewBox().state.copy()
            view_state.update({
                'mouseMode':
                pg.ViewBox.RectMode if state else pg.ViewBox.PanMode
            })
            self.plot_widget.plotItem.getViewBox().setState(view_state)

        # Setup plot settings options menu
        self.plot_settings_button = self.tool_bar.widgetForAction(
            self._central_widget.plot_settings_action)
        self.plot_settings_button.setPopupMode(QToolButton.InstantPopup)

        self.plot_settings_menu = QMenu(self.plot_settings_button)
        self.plot_settings_button.setMenu(self.plot_settings_menu)

        self.color_change_action = QAction("Line Color")
        self.plot_settings_menu.addAction(self.color_change_action)

        self.line_width_menu = QMenu("Line Widths")
        self.plot_settings_menu.addMenu(self.line_width_menu)

        # Setup the line width plot setting options
        for i in range(1, 4):
            act = QAction(str(i), self.line_width_menu)
            self.line_width_menu.addAction(act)
            act.triggered.connect(
                lambda *args, size=i: self._on_change_width(size))

        # Setup connections
        self._central_widget.pan_mode_action.triggered.connect(
            lambda: _toggle_mode(False))
        self._central_widget.zoom_mode_action.triggered.connect(
            lambda: _toggle_mode(True))
        self._central_widget.linear_region_action.triggered.connect(
            self.plot_widget._on_add_linear_region)
        self._central_widget.remove_region_action.triggered.connect(
            self.plot_widget._on_remove_linear_region)
        self.color_change_action.triggered.connect(self._on_change_color)
        self._central_widget.export_plot_action.triggered.connect(
            self._on_export_plot)
        self._central_widget.reset_view_action.triggered.connect(
            lambda: self._on_reset_view())
Beispiel #23
0
    def setup(self):
        self.wrap_action = self.create_action(
            name=HelpWidgetActions.ToggleWrap,
            text=_("Wrap lines"),
            toggled=True,
            initial=self.get_conf('wrap'),
            option='wrap'
        )
        self.copy_action = self.create_action(
            name=HelpWidgetActions.CopyAction,
            text=_("Copy"),
            triggered=lambda value: self.plain_text.copy(),
            register_shortcut=False,
        )
        self.select_all_action = self.create_action(
            name=HelpWidgetActions.SelectAll,
            text=_("Select All"),
            triggered=lambda value: self.plain_text.select_all(),
            register_shortcut=False,
        )
        self.auto_import_action = self.create_action(
            name=HelpWidgetActions.ToggleAutomaticImport,
            text=_("Automatic import"),
            toggled=True,
            initial=self.get_conf('automatic_import'),
            option='automatic_import'
        )
        self.show_source_action = self.create_action(
            name=HelpWidgetActions.ToggleShowSource,
            text=_("Show Source"),
            toggled=True,
            option='show_source'
        )
        self.rich_text_action = self.create_action(
            name=HelpWidgetActions.ToggleRichMode,
            text=_("Rich Text"),
            toggled=True,
            initial=self.get_conf('rich_mode'),
            option='rich_mode'
        )
        self.plain_text_action = self.create_action(
            name=HelpWidgetActions.TogglePlainMode,
            text=_("Plain Text"),
            toggled=True,
            initial=self.get_conf('plain_mode'),
            option='plain_mode'
        )
        self.locked_action = self.create_action(
            name=HelpWidgetActions.ToggleLocked,
            text=_("Lock/Unlock"),
            toggled=True,
            icon=self.create_icon('lock_open'),
            initial=self.get_conf('locked'),
            option='locked'
        )
        self.home_action = self.create_action(
            name=HelpWidgetActions.Home,
            text=_("Home"),
            triggered=self.show_intro_message,
            icon=self.create_icon('home'),
        )

        # Add the help actions to an exclusive QActionGroup
        help_actions = QActionGroup(self)
        help_actions.setExclusive(True)
        help_actions.addAction(self.plain_text_action)
        help_actions.addAction(self.rich_text_action)

        # Menu
        menu = self.get_options_menu()
        for item in [self.rich_text_action, self.plain_text_action,
                     self.show_source_action]:
            self.add_item_to_menu(
                item,
                menu=menu,
                section=HelpWidgetOptionsMenuSections.Display,
            )

        self.add_item_to_menu(
            self.auto_import_action,
            menu=menu,
            section=HelpWidgetOptionsMenuSections.Other,
        )

        # Plain text menu
        self._plain_text_context_menu = self.create_menu(
            "plain_text_context_menu")
        self.add_item_to_menu(
            self.copy_action,
            self._plain_text_context_menu,
            section="copy_section",
        )
        self.add_item_to_menu(
            self.select_all_action,
            self._plain_text_context_menu,
            section="select_section",
        )
        self.add_item_to_menu(
            self.wrap_action,
            self._plain_text_context_menu,
            section="wrap_section",
        )

        # Toolbar
        toolbar = self.get_main_toolbar()
        for item in [self.source_label, self.source_combo, self.object_label,
                     self.object_combo, self.object_edit, self.home_action,
                     self.locked_action]:
            self.add_item_to_toolbar(
                item,
                toolbar=toolbar,
                section=HelpWidgetMainToolbarSections.Main,
            )

        self.source_changed()
        self.switch_to_rich_text()
        self.show_intro_message()

        # Signals
        self.plain_text.sig_custom_context_menu_requested.connect(
            self._show_plain_text_context_menu)
Beispiel #24
0
    def setup_menu_actions(self):

        # flow designs
        light_themes_menu = QMenu('light')
        for d in self.session.design.flow_themes:
            design_action = QAction(d.name, self)
            if d.type_ == 'dark':
                self.ui.menuFlow_Design_Style.addAction(design_action)
            else:
                light_themes_menu.addAction(design_action)

            design_action.triggered.connect(self.on_design_action_triggered)
            self.flow_view_theme_actions.append(design_action)

        self.ui.menuFlow_Design_Style.addMenu(light_themes_menu)

        self.ui.actionImport_Nodes.triggered.connect(self.on_import_nodes_triggered)
        self.ui.actionSave_Project.triggered.connect(self.on_save_project_triggered)
        self.ui.actionEnableInfoMessages.triggered.connect(self.on_enable_info_msgs_triggered)
        self.ui.actionDisableInfoMessages.triggered.connect(self.on_disable_info_msgs_triggered)
        self.ui.actionSave_Pic_Viewport.triggered.connect(self.on_save_scene_pic_viewport_triggered)
        self.ui.actionSave_Pic_Whole_Scene_scaled.triggered.connect(self.on_save_scene_pic_whole_triggered)

        # performance mode
        self.ac_perf_mode_fast = QAction('Fast', self)
        self.ac_perf_mode_fast.setCheckable(True)

        self.ac_perf_mode_pretty = QAction('Pretty', self)
        self.ac_perf_mode_pretty.setCheckable(True)

        perf_mode_ag = QActionGroup(self)
        perf_mode_ag.addAction(self.ac_perf_mode_fast)
        perf_mode_ag.addAction(self.ac_perf_mode_pretty)

        self.ac_perf_mode_fast.setChecked(self.session.design.performance_mode == 'fast')
        self.ac_perf_mode_pretty.setChecked(self.session.design.performance_mode == 'pretty')

        perf_mode_ag.triggered.connect(self.on_performance_mode_changed)

        perf_menu = QMenu('Performance Mode', self)
        perf_menu.addAction(self.ac_perf_mode_fast)
        perf_menu.addAction(self.ac_perf_mode_pretty)

        self.ui.menuView.addMenu(perf_menu)

        # animations
        self.ac_anims_active = QAction('Enabled', self)
        self.ac_anims_active.setCheckable(True)

        self.ac_anims_inactive = QAction('Disabled', self)
        self.ac_anims_inactive.setCheckable(True)

        anims_ag = QActionGroup(self)
        anims_ag.addAction(self.ac_anims_active)
        anims_ag.addAction(self.ac_anims_inactive)

        self.ac_anims_active.setChecked(self.session.design.animations_enabled)
        self.ac_anims_inactive.setChecked(not self.session.design.animations_enabled)

        anims_ag.triggered.connect(self.on_animation_enabling_changed)

        animations_menu = QMenu('Animations', self)
        animations_menu.addAction(self.ac_anims_active)
        animations_menu.addAction(self.ac_anims_inactive)

        self.ui.menuView.addMenu(animations_menu)
Beispiel #25
0
    def setup(self, options):
        self.wrap_action = self.create_action(
            name=HelpWidgetActions.ToggleWrap,
            text=_("Wrap lines"),
            toggled=lambda value: self.set_option('wrap', value),
            initial=self.get_option('wrap'),
        )
        self.auto_import_action = self.create_action(
            name=HelpWidgetActions.ToggleAutomaticImport,
            text=_("Automatic import"),
            toggled=lambda value: self.set_option('automatic_import', value),
            initial=self.get_option('automatic_import'),
        )
        self.show_source_action = self.create_action(
            name=HelpWidgetActions.ToggleShowSource,
            text=_("Show Source"),
            toggled=lambda value: self.set_option('show_source', value),
        )
        self.rich_text_action = self.create_action(
            name=HelpWidgetActions.ToggleRichMode,
            text=_("Rich Text"),
            toggled=lambda value: self.set_option('rich_mode', value),
            initial=self.get_option('rich_mode'),
        )
        self.plain_text_action = self.create_action(
            name=HelpWidgetActions.TogglePlainMode,
            text=_("Plain Text"),
            toggled=lambda value: self.set_option('plain_mode', value),
            initial=self.get_option('plain_mode'),
        )
        self.locked_action = self.create_action(
            name=HelpWidgetActions.ToggleLocked,
            text=_("Lock/Unlock"),
            toggled=lambda value: self.set_option('locked', value),
            icon=self.create_icon('lock_open'),
            initial=self.get_option('locked'),
        )

        # TODO: Temporal while code editor migrates to SpyderMixin
        self.plain_text.set_wrap_action(self.wrap_action)

        # Add the help actions to an exclusive QActionGroup
        help_actions = QActionGroup(self)
        help_actions.setExclusive(True)
        help_actions.addAction(self.plain_text_action)
        help_actions.addAction(self.rich_text_action)

        # Menu
        menu = self.get_options_menu()
        for item in [self.rich_text_action, self.plain_text_action,
                     self.show_source_action]:
            self.add_item_to_menu(
                item,
                menu=menu,
                section=HelpWidgetOptionsMenuSections.Display,
            )

        self.add_item_to_menu(
            self.auto_import_action,
            menu=menu,
            section=HelpWidgetOptionsMenuSections.Other,
        )

        # Toolbar
        toolbar = self.get_main_toolbar()
        for item in [self.source_label, self.source_combo, self.object_label,
                     self.object_combo, self.object_edit, self.locked_action]:
            self.add_item_to_toolbar(
                item,
                toolbar=toolbar,
                section=HelpWidgetMainToolBarSections.Main,
            )

        self.source_changed()
        self.switch_to_rich_text()
        self.show_intro_message()
Beispiel #26
0
    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)

        # Load the ui file and attached it to this instance
        loadUi(os.path.join(UI_PATH, "main_window.ui"), self)

        # Load editor ui files
        self._model_editor = QWidget()
        loadUi(os.path.join(UI_PATH, "model_editor.ui"), self._model_editor)
        self._model_editor.add_model_button.setIcon(qta.icon('fa.plus'))
        self._model_editor.remove_model_button.setIcon(qta.icon('fa.minus'))

        self._statistics = QWidget()
        loadUi(os.path.join(UI_PATH, "statistics.ui"), self._statistics)

        # Add spacers to the main tool bar
        spacer = QWidget()
        spacer.setFixedSize(self.tool_bar.iconSize() * 2)
        self.tool_bar.insertWidget(self.load_data_action, spacer)

        spacer = QWidget()
        spacer.setFixedSize(self.tool_bar.iconSize() * 2)
        self.tool_bar.insertWidget(self.new_plot_action, spacer)

        spacer = QWidget()
        size_policy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        size_policy.setHorizontalStretch(1)
        spacer.setSizePolicy(size_policy)
        self.tool_bar.addWidget(spacer)

        # Setup plugin toolbar
        self._plugin_action_group = QActionGroup(self)
        self.model_editor_toggle.setActionGroup(self._plugin_action_group)
        self.statistics_toggle.setActionGroup(self._plugin_action_group)
        self.mask_editor_toggle.setActionGroup(self._plugin_action_group)

        # Hide the plugin dock initially
        self.plugin_dock.hide()

        # Create a default workspace
        self._workspace = Workspace()
        self.setCentralWidget(self._workspace)

        # Update title
        self.setWindowTitle(self._workspace.name + " — SpecViz")

        # Setup workspace action connections

        # We need to be careful here as if Specviz is embedded in another
        # Qt application, the QApplication instance won't have the add_workspace
        # method
        from ..app import Application
        app = QApplication.instance()
        if isinstance(app, Application):
            self.new_workspace_action.triggered.connect(app.add_workspace)

        self.new_plot_action.triggered.connect(self.workspace._on_new_plot)

        # Setup data action connections
        self.load_data_action.triggered.connect(self.workspace._on_load_data)
        self.delete_data_action.triggered.connect(
            self.workspace._on_delete_data)

        # Setup operations menu
        operations_button = self.tool_bar.widgetForAction(
            self.operations_action)
        operations_button.setPopupMode(QToolButton.InstantPopup)

        operations_menu = dict_to_menu(
            self, OrderedDict([('Smoothing', self.workspace._on_smoothing)]))
        operations_button.setMenu(operations_menu)

        # Setup plugin toolbar action actions
        self._plugin_action_group.triggered.connect(
            self._on_toggle_plugin_dock)
        self._last_toggled_action = None

        # Attach individual loading of editors to their actions
        self.model_editor_toggle.triggered.connect(
            lambda: self._on_editor_triggered(self.model_editor_toggle.
                                              objectName()))
        self.statistics_toggle.triggered.connect(
            lambda: self._on_editor_triggered(self.statistics_toggle.
                                              objectName()))
        self.mask_editor_toggle.triggered.connect(
            lambda: self._on_editor_triggered(self.mask_editor_toggle.
                                              objectName()))
Beispiel #27
0
    def getMenuAction(self, menu, title='notitle', action_name='noaction',
                      args=[], kwargs={}):
        # ToDo: Clean this up, it is very hacky
        env = {'app': QApplication.instance(),
               'win': self,
               'action': actions,
               }

        if action_name is not None:

            if action_name.startswith('settings.'):
                setting_id = action_name[len('settings.'):]
                setting = getSetting(setting_id)

                if setting:
                    if setting.enum_options is not None:
                        submenu = QMenu(parent=self, title=title)

                        group = QActionGroup(self)
                        group.setExclusive(True)
                        group.triggered.connect(lambda a: setting.setValue(a.data()))

                        def update(group, val):
                            for act in group.actions():
                                if act.data() == val:
                                    act.setChecked(True)
                                    break

                        for num, opt in enumerate(setting.enum_options):

                            act = QAction(parent=self, text=opt)
                            act.setCheckable(True)
                            if setting.value == num:
                                act.setChecked(True)

                            act.setData(num)
                            setting.notify(lambda v: update(group, v))

                            act.setActionGroup(group)
                            submenu.addAction(act)
                        menu.addMenu(submenu)

                    elif setting.value_type == bool:
                        # works for bool settings
                        menu_action = QAction(parent=self, text=title)
                        menu_action.setCheckable(True)
                        menu_action.triggered.connect(setting.setValue)
                        setting.notify(menu_action.setChecked)
                        menu.addAction(menu_action)

                    return

            try:
                menu_action = QAction(parent=self, text=title)

                mod, action = action_name.split('.', 1)
                method = getattr(env.get(mod, self), action)
                if menu_action.isCheckable():
                    menu_action.triggered.connect(method)
                else:
                    menu_action.triggered.connect(lambda checked: method(*args, **kwargs))

                menu.addAction(menu_action)
                return
            except:
                pass

            try:
                menu_action = QAction(parent=self, text=title)
                actions.bindWidget(menu_action, action_name)
                menu.addAction(menu_action)
                return
            except actions.InvalidAction:
                LOG.exception('Error binding menu action %s', action_name)

        menu_action = QAction(parent=self, text=title)
        msg = "The <b>{}</b> action specified for the " \
              "<b>{}</b> menu item could not be triggered. " \
              "Check the YAML config file for errors." \
              .format(action_name or '', title.replace('&', ''))
        menu_action.triggered.connect(lambda: QMessageBox.critical(self, "Menu Action Error!", msg))
        menu.addAction(menu_action)
Beispiel #28
0
    def __init__(self,
                 parent=None,
                 image_channel=None,
                 xaxis_channel=None,
                 yaxis_channel=None,
                 roioffsetx_channel=None,
                 roioffsety_channel=None,
                 roiwidth_channel=None,
                 roiheight_channel=None,
                 title='',
                 background='w',
                 image_width=0,
                 image_height=0):
        """Initialize widget."""
        GraphicsLayoutWidget.__init__(self, parent)
        PyDMWidget.__init__(self)
        self.thread = None
        self._imagechannel = None
        self._xaxischannel = None
        self._yaxischannel = None
        self._roioffsetxchannel = None
        self._roioffsetychannel = None
        self._roiwidthchannel = None
        self._roiheightchannel = None
        self._channels = 7 * [
            None,
        ]
        self.image_waveform = np.zeros(0)
        self._image_width = image_width if not xaxis_channel else 0
        self._image_height = image_height if not yaxis_channel else 0
        self._roi_offsetx = 0
        self._roi_offsety = 0
        self._roi_width = 0
        self._roi_height = 0
        self._normalize_data = False
        self._auto_downsample = True
        self._last_yaxis_data = None
        self._last_xaxis_data = None
        self._auto_colorbar_lims = True
        self.format_tooltip = '{0:.4g}, {1:.4g}'

        # ViewBox and imageItem.
        self._view = ViewBox()
        self._image_item = ImageItem()
        self._view.addItem(self._image_item)

        # ROI
        self.ROICurve = PlotCurveItem([0, 0, 0, 0, 0], [0, 0, 0, 0, 0])
        self.ROIColor = QColor('red')
        pen = mkPen()
        pen.setColor(QColor('transparent'))
        pen.setWidth(1)
        self.ROICurve.setPen(pen)
        self._view.addItem(self.ROICurve)

        # Axis.
        self.xaxis = AxisItem('bottom')
        self.xaxis.setPen(QColor(0, 0, 0))
        if not xaxis_channel:
            self.xaxis.setVisible(False)
        self.yaxis = AxisItem('left')
        self.yaxis.setPen(QColor(0, 0, 0))
        if not yaxis_channel:
            self.yaxis.setVisible(False)

        # Colorbar legend.
        self.colorbar = _GradientLegend()

        # Title.
        start_row = 0
        if title:
            self.title = LabelItem(text=title, color='#000000')
            self.addItem(self.title, 0, 0, 1, 3)
            start_row = 1

        # Set layout.
        self.addItem(self._view, start_row, 1)
        self.addItem(self.yaxis, start_row, 0)
        self.addItem(self.colorbar, start_row, 2)
        self.addItem(self.xaxis, start_row + 1, 1)
        self.setBackground(background)
        self.ci.layout.setColumnSpacing(0, 0)
        self.ci.layout.setRowSpacing(start_row, 0)

        # Set color map limits.
        self.cm_min = 0.0
        self.cm_max = 255.0

        # Set default reading order of numpy array data to Clike.
        self._reading_order = ReadingOrder.Clike

        # Make a right-click menu for changing the color map.
        self.cm_group = QActionGroup(self)
        self.cmap_for_action = {}
        for cm in self.color_maps:
            action = self.cm_group.addAction(cmap_names[cm])
            action.setCheckable(True)
            self.cmap_for_action[action] = cm

        # Set the default colormap.
        self._cm_colors = None
        self.colorMap = PyDMColorMap.Inferno

        # Setup the redraw timer.
        self.needs_redraw = False
        self.redraw_timer = QTimer(self)
        self.redraw_timer.timeout.connect(self.redrawImage)
        self._redraw_rate = 30
        self.maxRedrawRate = self._redraw_rate
        self.newImageSignal = self._image_item.sigImageChanged

        # Set Channels.
        self.imageChannel = image_channel
        self.xAxisChannel = xaxis_channel
        self.yAxisChannel = yaxis_channel
        self.ROIOffsetXChannel = roioffsetx_channel
        self.ROIOffsetYChannel = roioffsety_channel
        self.ROIWidthChannel = roiwidth_channel
        self.ROIHeightChannel = roiheight_channel