示例#1
0
 def test_drop_load_data(self):
     m = QtCore.QMimeData()
     m.setUrls([QtCore.QUrl('test.fits')])
     e = MagicMock()
     e.mimeData.return_value = m
     load = MagicMock()
     self.app.load_data = load
     self.app.dropEvent(e)
     assert load.call_count == 1
示例#2
0
    def __init__(self, canvas, frame, name=None):
        """ Create a new toolbar object

        Parameters
        ----------
        canvas : Maptloblib canvas instance
         The drawing canvas to interact with
        frame : QWidget
         The QT frame that the canvas is embedded within.
        """
        self.buttons = {}
        self.__active = None
        self.basedir = None
        NavigationToolbar2QT.__init__(self, canvas, frame)
        if name is not None:
            self.setWindowTitle(name)
        self.setIconSize(QtCore.QSize(25, 25))
        self.layout().setSpacing(1)
        self.setFocusPolicy(Qt.StrongFocus)
        self._idKey = None

        # pyside is prone to segfaults if slots hold the only
        # reference to a signal, so we hold an extra reference
        # see https://bugreports.qt-project.org/browse/PYSIDE-88
        self.__signals = []
示例#3
0
    def paintEvent(self, event):

        # We need to preserve aspect ratio. Figure out bounding box for
        # webcam image.

        im_dx = self._image.width()
        im_dy = self._image.height()
        im_ratio = im_dx / float(im_dy)

        wi_dx = self.width()
        wi_dy = self.height()
        wi_ratio = wi_dx / float(wi_dy)

        if wi_ratio > im_ratio:  # Need to pad on sides

            xmin = wi_dx / 2. - wi_dy / 2. * im_ratio
            ymin = 0.
            width = wi_dy * im_ratio
            height = wi_dy

        else:  # Need to pad on top/bottom

            xmin = 0.
            ymin = wi_dy / 2. - wi_dx / 2. / float(im_ratio)
            width = wi_dx
            height = wi_dx / float(im_ratio)

        painter = QtGui.QPainter(self)
        painter.drawImage(QtCore.QRect(xmin, ymin, width, height), self._image)
示例#4
0
    def _create_terminal(self):
        if self._terminal is not None:  # already set up
            return

        if hasattr(self, '_terminal_exception'):  # already failed to set up
            return

        self._terminal_button = QtGui.QToolButton(self._ui)
        self._terminal_button.setToolTip("Toggle IPython Prompt")
        i = get_icon('IPythonConsole')
        self._terminal_button.setIcon(i)
        self._terminal_button.setIconSize(QtCore.QSize(25, 25))

        self._layer_widget.ui.button_row.addWidget(self._terminal_button)

        try:
            from glue.app.qt.terminal import glue_terminal
            widget = glue_terminal(data_collection=self._data,
                                   dc=self._data,
                                   hub=self._hub,
                                   session=self.session,
                                   application=self,
                                   **vars(env))
            self._terminal_button.clicked.connect(self._toggle_terminal)
        except Exception as e:  # pylint: disable=W0703
            import traceback
            self._terminal_exception = traceback.format_exc()
            self._setup_terminal_error_dialog(e)
            return

        self._terminal = self.add_widget(widget, label='IPython')
        self._hide_terminal()
示例#5
0
文件: colors.py 项目: robintw/glue
 def _update_icons(self):
     self.setIconSize(QtCore.QSize(self.width(), 15))
     for index in range(self.count()):
         cmap = self.itemData(index)
         icon = QtGui.QIcon(
             cmap2pixmap(cmap, size=(self.width(), 15), steps=200))
         self.setItemIcon(index, icon)
示例#6
0
    def index(self, row, column, parent=QtCore.QModelIndex()):
        if column != 0:
            return QtCore.QModelIndex()

        if not parent.isValid():
            parent_item = self.root
        else:
            parent_item = self._get_item(parent)
            if parent_item is None:
                return QtCore.QModelIndex()

        child_item = parent_item.child(row)
        if child_item:
            return self._make_index(row, column, child_item)
        else:
            return QtCore.QModelIndex()
示例#7
0
    def rowCount(self, index=QtCore.QModelIndex()):
        item = self._get_item(index)

        if item is None:
            return self.root.children_count

        return item.children_count
示例#8
0
 def _setup_symbol_combo(self):
     self._symbols = list(POINT_ICONS.keys())
     for idx, symbol in enumerate(self._symbols):
         icon = symbol_icon(symbol)
         self.ui.combo_symbol.addItem(icon, '', userData=symbol)
     self.ui.combo_symbol.setIconSize(QtCore.QSize(20, 20))
     self.ui.combo_symbol.setMinimumSize(10, 32)
示例#9
0
文件: roi.py 项目: robintw/glue
    def paint(self, canvas):
        xy = list(map(int, self._roi.get_center()))
        radius = int(self._roi.get_radius())
        center = QtCore.QPoint(xy[0], canvas.height() - xy[1])

        p = self.get_painter(canvas)
        p.drawEllipse(center, radius, radius)
        p.end()
示例#10
0
    def _update_intensity_label(self, x, y):
        lbl = self._intensity_label(x, y)
        self.label_widget.setText(lbl)

        fm = self.label_widget.fontMetrics()
        w, h = fm.width(lbl), fm.height()
        g = QtCore.QRect(20, self.central_widget.geometry().height() - h, w, h)
        self.label_widget.setGeometry(g)
示例#11
0
    def __init__(self, parent=None):
        super(LayerArtistView, self).__init__(parent)
        self.setDragEnabled(True)
        self.setAcceptDrops(True)
        self.setDragDropMode(QtGui.QAbstractItemView.InternalMove)
        self.setIconSize(QtCore.QSize(15, 15))
        self.setSelectionMode(QtGui.QAbstractItemView.SingleSelection)
        self.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
        self.setContextMenuPolicy(Qt.ActionsContextMenu)
        self.setEditTriggers(self.NoEditTriggers)

        self._set_palette()
        self._actions = {}
        self._create_actions()

        self._timer = QtCore.QTimer(self)
        self._timer.timeout.connect(nonpartial(self._update_viewport))
        self._timer.start(1000)
示例#12
0
class ClickableLabel(QtGui.QLabel):
    """
    A QtGui.QLabel you can click on to generate events
    """

    clicked = QtCore.Signal()

    def mousePressEvent(self, event):
        self.clicked.emit()
示例#13
0
    def parent(self, index=None):

        if index is None:  # overloaded QtCore.QObject.parent()
            return QtCore.QObject.parent(self)

        item = self._get_item(index)
        if item is None:
            return QtCore.QModelIndex()

        return self._make_index(item.row, item.column, item.parent)
示例#14
0
文件: roi.py 项目: robintw/glue
    def draw_polygon(self, canvas, x, y):
        x, y = self._transform(x, y)
        poly = QtGui.QPolygon()
        points = [QtCore.QPoint(xx, yy) for xx, yy in zip(x, y)]
        for p in points:
            poly.append(p)

        p = self.get_painter(canvas)
        p.drawPolyline(poly)
        p.end()
示例#15
0
文件: helpers.py 项目: robintw/glue
def process_dialog(delay=0, accept=False, reject=False, function=None):
    """
    Context manager to automatically capture the active dialog and carry out
    certain actions.

    Note that only one of ``accept``, ``reject``, or ``function`` should be
    specified.

    Parameters
    ----------
    delay : int, optional
        The delay in ms before acting on the dialog (since it may not yet exist
        when the context manager is called).
    accept : bool, optional
        If `True`, accept the dialog after the specified delay.
    reject : bool, optional
        If `False`, reject the dialog after the specified delay
    function : func, optional
        For more complex user actions, specify a function that takes the dialog
        as the first and only argument.
    """
    def _accept(dialog):
        dialog.accept()

    def _reject(dialog):
        dialog.reject()

    n_args = sum((accept, reject, function is not None))

    if n_args > 1:
        raise ValueError("Only one of ``accept``, ``reject``, or "
                         "``function`` should be specified")
    elif n_args == 0:
        raise ValueError("One of ``accept``, ``reject``, or "
                         "``function`` should be specified")

    if accept:
        function = _accept
    elif reject:
        function = _reject

    def wrapper():
        from glue.external.qt import get_qapp
        app = get_qapp()
        dialog = app.focusWidget().window()
        function(dialog)

    timer = QtCore.QTimer()
    timer.setInterval(delay)
    timer.setSingleShot(True)
    timer.timeout.connect(wrapper)
    timer.start()

    yield
示例#16
0
    def set_setting(self, key, value):
        """
        Update a persistent setting in the application.

        :param key: Name of a setting in the ``settings`` registry
        :type key: str
        :param value: New value for the setting
        :type value: str
        """
        super(GlueApplication, self).set_setting(key, value)
        settings = QtCore.QSettings('glue-viz', 'glue')
        settings.setValue(key, value)
示例#17
0
 def start(self):
     # handoff between IOLoop and QApplication event loops
     loop = ioloop.IOLoop.instance()
     # We used to have a value of 0ms as the second argument
     # (callback_time) in the following call, but this caused the
     # application to hang on certain setups, so use 1ms instead.
     stopper = ioloop.PeriodicCallback(loop.stop, 1, loop)
     self.timer = QtCore.QTimer()
     self.timer.timeout.connect(loop.start)
     self.timer.start(100)
     stopper.start()
     super(EmbeddedQtKernelApp, self).start()
示例#18
0
    def __init__(self, parent=None):

        super(WebcamView, self).__init__()

        self._frozen = False

        self._webcam = Webcam()

        self._update_image()

        self._timer = QtCore.QTimer(self)
        self._timer.timeout.connect(self._update_image)
        self._timer.start(100)
示例#19
0
文件: widget.py 项目: robintw/glue
class ColorizedCompletionTextEdit(CompletionTextEdit):

    updated = QtCore.Signal()

    def insertPlainText(self, *args):
        super(ColorizedCompletionTextEdit, self).insertPlainText(*args)
        self.reformat_text()
        self.updated.emit()

    def keyReleaseEvent(self, event):
        super(ColorizedCompletionTextEdit, self).keyReleaseEvent(event)
        self.reformat_text()
        self.updated.emit()

    def reformat_text(self):

        # Here every time a key is released, we re-colorize the expression.
        # We show valid components in blue, and invalid ones in red. We
        # recognized components because they contain a ":" which is not valid
        # Python syntax (except if one considers lambda functions, but we can
        # probably ignore that here)
        text = self.toPlainText()

        # If there are no : in the text we don't need to do anything
        if not ":" in text:
            return

        pattern = '[^\\s]*:[^\\s]*'

        def format_components(m):
            component = m.group(0)
            if component in self.word_list:
                return "<font color='#0072B2'><b>" + component + "</b></font> "
            else:
                return "<font color='#D55E00'><b>" + component + "</b></font> "

        html = re.sub(pattern, format_components, text)

        tc = self.textCursor()
        pos = tc.position()

        self.setHtml(html)

        # Sometimes the HTML gets rid of double spaces so we have to make
        # sure the position isn't greater than the text length.
        text = self.toPlainText()
        pos = min(pos, len(text))

        tc.setPosition(pos)
        self.setTextCursor(tc)
        self.setAlignment(Qt.AlignCenter)
示例#20
0
    def __init__(self, parent=None):
        super(DataCollectionView, self).__init__(parent)
        self.doubleClicked.connect(self._edit)

        # this keeps the full-row of the selection bar in-sync
        self.pressed.connect(nonpartial(self._update_viewport))

        # only edit label on model.new_item
        self.setItemDelegate(LabeledDelegate())
        self.setEditTriggers(self.NoEditTriggers)

        self._timer = QtCore.QTimer(self)
        self._timer.timeout.connect(nonpartial(self._update_viewport))
        self._timer.start(1000)
示例#21
0
文件: mpl_widget.py 项目: rguter/glue
class MplWidget(QtGui.QWidget):
    """Widget defined in Qt Designer"""

    # signals
    rightDrag = QtCore.Signal(float, float)
    leftDrag = QtCore.Signal(float, float)

    def __init__(self, parent=None):
        # initialization of Qt MainWindow widget
        QtGui.QWidget.__init__(self, parent)
        # set the canvas to the Matplotlib widget
        self.canvas = MplCanvas()
        # create a vertical box layout
        self.vbl = QtGui.QVBoxLayout()
        self.vbl.setContentsMargins(0, 0, 0, 0)
        self.vbl.setSpacing(0)
        # add mpl widget to the vertical box
        self.vbl.addWidget(self.canvas)
        # set the layout to the vertical box
        self.setLayout(self.vbl)

        self.canvas.rightDrag.connect(self.rightDrag)
        self.canvas.leftDrag.connect(self.leftDrag)
示例#22
0
    def move_artist(self, artist, row):
        """Move an artist before the entry in row

        Row could be the end of the list (-> put it at the end)
        """
        if len(self.artists) < 2:  # can't rearrange lenght 0 or 1 list
            return

        try:
            loc = self.artists.index(artist)
        except ValueError:
            return

        dest = row
        if not self.beginMoveRows(QtCore.QModelIndex(), loc, loc,
                                  QtCore.QModelIndex(), dest):
            return
        if dest >= loc:
            row -= 1
        self.artists.pop(loc)
        self.artists.insert(row, artist)
        self._update_zorder()
        self.endMoveRows()
示例#23
0
文件: colors.py 项目: robintw/glue
class QColorBox(QtGui.QLabel):

    mousePressed = QtCore.Signal()
    colorChanged = QtCore.Signal()

    def __init__(self, *args, **kwargs):
        super(QColorBox, self).__init__(*args, **kwargs)
        self.mousePressed.connect(nonpartial(self.query_color))
        self.colorChanged.connect(nonpartial(self.on_color_change))
        self.setColor("#000000")

    def mousePressEvent(self, event):
        self.mousePressed.emit()
        event.accept()

    def query_color(self):
        color = QtGui.QColorDialog.getColor(self._qcolor, parent=self)
        if color.isValid():
            self.setColor(qt4_to_mpl_color(color))

    def setColor(self, color):
        self._color = color
        self.colorChanged.emit()

    def color(self):
        return self._color

    def on_color_change(self):
        self._qcolor = mpl_to_qt4_color(self.color())
        image = QtGui.QImage(70, 22, QtGui.QImage.Format_RGB32)
        try:
            image.fill(self._qcolor)
        except TypeError:
            # PySide and old versions of PyQt require a RGBA integer
            image.fill(self._qcolor.rgba())
        pixmap = QtGui.QPixmap.fromImage(image)
        self.setPixmap(pixmap)
示例#24
0
def test_style_dialog():

    # This is in part a regression test for a bug in Python 3. It is not a
    # full test of StyleDialog.

    session = simple_session()
    hub = session.hub
    collect = session.data_collection

    image = Data(label='im',
                 x=[[1, 2], [3, 4]],
                 y=[[2, 3], [4, 5]])

    pos = QtCore.QPoint(10, 10)
    st = NonBlockingStyleDialog.dropdown_editor(image, pos)
示例#25
0
    def make_toolbar(self):
        tb = QtGui.QToolBar(parent=self)
        tb.setIconSize(QtCore.QSize(25, 25))
        tb.layout().setSpacing(1)
        tb.setFocusPolicy(Qt.StrongFocus)

        agroup = QtGui.QActionGroup(tb)
        agroup.setExclusive(True)
        for (mode_text, mode_icon, mode_cb) in self._mouse_modes():
            # TODO: add icons similar to the Matplotlib toolbar
            action = tb.addAction(mode_icon, mode_text)
            action.setCheckable(True)
            action.toggled.connect(mode_cb)
            agroup.addAction(action)

        action = tb.addAction(get_icon('glue_move'), "Pan")
        self.mode_actns['pan'] = action
        action.setCheckable(True)
        action.toggled.connect(lambda tf: self.mode_cb('pan', tf))
        agroup.addAction(action)
        icon = QtGui.QIcon(os.path.join(ginga_icon_dir, 'hand_48.png'))
        action = tb.addAction(icon, "Free Pan")
        self.mode_actns['freepan'] = action
        action.setCheckable(True)
        action.toggled.connect(lambda tf: self.mode_cb('freepan', tf))
        agroup.addAction(action)
        icon = QtGui.QIcon(os.path.join(ginga_icon_dir, 'rotate_48.png'))
        action = tb.addAction(icon, "Rotate")
        self.mode_actns['rotate'] = action
        action.setCheckable(True)
        action.toggled.connect(lambda tf: self.mode_cb('rotate', tf))
        agroup.addAction(action)
        action = tb.addAction(get_icon('glue_contrast'), "Contrast")
        self.mode_actns['contrast'] = action
        action.setCheckable(True)
        action.toggled.connect(lambda tf: self.mode_cb('contrast', tf))
        agroup.addAction(action)
        icon = QtGui.QIcon(os.path.join(ginga_icon_dir, 'cuts_48.png'))
        action = tb.addAction(icon, "Cuts")
        self.mode_actns['cuts'] = action
        action.setCheckable(True)
        action.toggled.connect(lambda tf: self.mode_cb('cuts', tf))
        agroup.addAction(action)

        cmap_w = _colormap_mode(self, self.client.set_cmap)
        tb.addWidget(cmap_w)
        return tb
示例#26
0
    def _setup_widgets(self):
        self.layout = QtGui.QFormLayout()

        self.size_widget = QtGui.QSpinBox()
        self.size_widget.setMinimum(1)
        self.size_widget.setMaximum(40)
        self.size_widget.setValue(self.layer.style.markersize)

        self.label_widget = QtGui.QLineEdit()
        self.label_widget.setText(self.layer.label)
        self.label_widget.selectAll()

        self.symbol_widget = QtGui.QComboBox()
        for idx, symbol in enumerate(self._symbols):
            icon = symbol_icon(symbol)
            self.symbol_widget.addItem(icon, '')
            if symbol is self.layer.style.marker:
                self.symbol_widget.setCurrentIndex(idx)
        self.symbol_widget.setIconSize(QtCore.QSize(20, 20))
        self.symbol_widget.setMinimumSize(10, 32)

        self.color_widget = ColorWidget()
        self.color_widget.setStyleSheet('ColorWidget {border: 1px solid;}')
        color = self.layer.style.color
        color = mpl_to_qt4_color(color, alpha=self.layer.style.alpha)
        self.set_color(color)

        self.okcancel = QtGui.QDialogButtonBox(QtGui.QDialogButtonBox.Ok |
                                               QtGui.QDialogButtonBox.Cancel)

        if self._edit_label:
            self.layout.addRow("Label", self.label_widget)
        self.layout.addRow("Symbol", self.symbol_widget)
        self.layout.addRow("Color", self.color_widget)
        self.layout.addRow("Size", self.size_widget)

        self.layout.addWidget(self.okcancel)

        self.setLayout(self.layout)
        self.layout.setContentsMargins(6, 6, 6, 6)
示例#27
0
文件: mpl_widget.py 项目: rguter/glue
    def __init__(self):
        self._draw_count = 0
        interactive = matplotlib.is_interactive()
        matplotlib.interactive(False)
        self.roi_callback = None

        self.fig = Figure(facecolor='#ffffff')

        FigureCanvas.__init__(self, self.fig)
        FigureCanvas.setSizePolicy(self, QtGui.QSizePolicy.Expanding,
                                   QtGui.QSizePolicy.Expanding)

        FigureCanvas.updateGeometry(self)
        self.manager = FigureManager(self, 0)
        matplotlib.interactive(interactive)

        self._resize_timer = QtCore.QTimer()
        self._resize_timer.setInterval(250)
        self._resize_timer.setSingleShot(True)
        self._resize_timer.timeout.connect(self._on_timeout)

        self.renderer = None
示例#28
0
 def add_artist(self, row, artist):
     """Add a new artist"""
     self.beginInsertRows(QtCore.QModelIndex(), row, row)
     self.artists.insert(row, artist)
     self.endInsertRows()
     self.rowsInserted.emit(self.index(row), row, row)
示例#29
0
    def setupUi(self, ImageWidget):
        ImageWidget.setObjectName("ImageWidget")
        ImageWidget.resize(296, 217)
        ImageWidget.setBaseSize(QtCore.QSize(555, 500))
        ImageWidget.setFocusPolicy(QtCore.Qt.StrongFocus)
        self.verticalLayout_2 = QtGui.QVBoxLayout(ImageWidget)
        self.verticalLayout_2.setContentsMargins(4, 4, 4, 4)
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.option_dashboard = QtGui.QWidget(ImageWidget)
        self.option_dashboard.setObjectName("option_dashboard")
        self.verticalLayout = QtGui.QVBoxLayout(self.option_dashboard)
        self.verticalLayout.setContentsMargins(0, 0, 0, 10)
        self.verticalLayout.setObjectName("verticalLayout")
        self.horizontalLayout = QtGui.QHBoxLayout()
        self.horizontalLayout.setSpacing(2)
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.label = QtGui.QLabel(self.option_dashboard)
        self.label.setObjectName("label")
        self.horizontalLayout.addWidget(self.label)
        self.displayDataCombo = GlueComboBox(self.option_dashboard)
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.displayDataCombo.sizePolicy().hasHeightForWidth())
        self.displayDataCombo.setSizePolicy(sizePolicy)
        self.displayDataCombo.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToMinimumContentsLength)
        self.displayDataCombo.setObjectName("displayDataCombo")
        self.horizontalLayout.addWidget(self.displayDataCombo)
        self.verticalLayout.addLayout(self.horizontalLayout)
        self.horizontalLayout_2 = QtGui.QHBoxLayout()
        self.horizontalLayout_2.setSpacing(2)
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.label_2 = QtGui.QLabel(self.option_dashboard)
        self.label_2.setObjectName("label_2")
        self.horizontalLayout_2.addWidget(self.label_2)
        self.attributeComboBox = GlueComboBox(self.option_dashboard)
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.attributeComboBox.sizePolicy().hasHeightForWidth())
        self.attributeComboBox.setSizePolicy(sizePolicy)
        self.attributeComboBox.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToMinimumContentsLength)
        self.attributeComboBox.setObjectName("attributeComboBox")
        self.horizontalLayout_2.addWidget(self.attributeComboBox)
        self.verticalLayout.addLayout(self.horizontalLayout_2)
        self.horizontalLayout_3 = QtGui.QHBoxLayout()
        self.horizontalLayout_3.setSpacing(2)
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
        self.orientationLabel = QtGui.QLabel(self.option_dashboard)
        self.orientationLabel.setEnabled(True)
        self.orientationLabel.setObjectName("orientationLabel")
        self.horizontalLayout_3.addWidget(self.orientationLabel)
        self.sliceComboBox = GlueComboBox(self.option_dashboard)
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.sliceComboBox.sizePolicy().hasHeightForWidth())
        self.sliceComboBox.setSizePolicy(sizePolicy)
        self.sliceComboBox.setObjectName("sliceComboBox")
        self.horizontalLayout_3.addWidget(self.sliceComboBox)
        self.verticalLayout.addLayout(self.horizontalLayout_3)
        self.imageSlider = QtGui.QSlider(self.option_dashboard)
        self.imageSlider.setEnabled(True)
        self.imageSlider.setOrientation(QtCore.Qt.Horizontal)
        self.imageSlider.setInvertedAppearance(False)
        self.imageSlider.setInvertedControls(True)
        self.imageSlider.setTickPosition(QtGui.QSlider.NoTicks)
        self.imageSlider.setTickInterval(0)
        self.imageSlider.setObjectName("imageSlider")
        self.verticalLayout.addWidget(self.imageSlider)
        spacerItem = QtGui.QSpacerItem(5, 59, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
        self.verticalLayout.addItem(spacerItem)
        self.verticalLayout_2.addWidget(self.option_dashboard)
        self.verticalLayout_2.setStretch(0, 1)

        self.retranslateUi(ImageWidget)
        QtCore.QMetaObject.connectSlotsByName(ImageWidget)
示例#30
0
class RGBEdit(QtGui.QWidget):
    """A widget to set the contrast for individual layers in an RGB image

    Based off the ds9 RGB Frame widget

    :param artist: A :class:`~glue.viewers.image.layer_artist.RGBArtistLayerArtist`
                   instance to control

    :param parent: Optional widget parent

    This widget sets the state of the artist object, such that contrast
    adjustments from a :class:`~glue.viewers.image.client` affect
    a particular RGB slice
    """
    current_changed = QtCore.Signal(str)
    colors_changed = QtCore.Signal()

    def __init__(self, parent=None, artist=None):
        super(RGBEdit, self).__init__(parent)
        self._artist = artist

        l = QtGui.QGridLayout()

        current = QtGui.QLabel("Contrast")
        visible = QtGui.QLabel("Visible")
        l.addWidget(current, 0, 2, 1, 1)
        l.addWidget(visible, 0, 3, 1, 1)
        l.setColumnStretch(0, 0)
        l.setColumnStretch(1, 10)
        l.setColumnStretch(2, 0)
        l.setColumnStretch(3, 0)

        l.setRowStretch(0, 0)
        l.setRowStretch(1, 0)
        l.setRowStretch(2, 0)
        l.setRowStretch(3, 0)
        l.setRowStretch(4, 10)

        curr_grp = QtGui.QButtonGroup()
        self.current = {}
        self.vis = {}
        self.cid = {}

        for row, color in enumerate(['red', 'green', 'blue'], 1):
            lbl = QtGui.QLabel(color.title())

            cid = ComponentIDCombo()

            curr = QtGui.QRadioButton()
            curr_grp.addButton(curr)

            vis = QtGui.QCheckBox()
            vis.setChecked(True)

            l.addWidget(lbl, row, 0, 1, 1)
            l.addWidget(cid, row, 1, 1, 1)
            l.addWidget(curr, row, 2, 1, 1)
            l.addWidget(vis, row, 3, 1, 1)

            curr.clicked.connect(self.update_current)
            vis.toggled.connect(self.update_visible)
            cid.currentIndexChanged.connect(self.update_layers)

            self.cid[color] = cid
            self.vis[color] = vis
            self.current[color] = curr

        self.setLayout(l)
        self.current['red'].click()

    @property
    def attributes(self):
        """A 3-tuple of the ComponentIDs for each RGB layer"""
        return tuple(self.cid[c].component for c in ['red', 'green', 'blue'])

    @attributes.setter
    def attributes(self, cids):
        for cid, c in zip(cids, ['red', 'green', 'blue']):
            if cid is None:
                continue
            self.cid[c].component = cid

    @property
    def rgb_visible(self):
        """ A 3-tuple of the visibility of each layer, as bools """
        return tuple(self.vis[c].isChecked() for c in ['red', 'green', 'blue'])

    @rgb_visible.setter
    def rgb_visible(self, value):
        for v, c in zip(value, 'red green blue'.split()):
            self.vis[c].setChecked(v)

    @property
    def artist(self):
        return self._artist

    @artist.setter
    def artist(self, value):
        self._artist = value
        for cid in self.cid.values():
            cid.data = value.layer
        self.update_layers()

    def update_layers(self):
        if self.artist is None:
            return

        r = self.cid['red'].component
        g = self.cid['green'].component
        b = self.cid['blue'].component
        changed = self.artist.r is not r or \
            self.artist.g is not g or\
            self.artist.b is not b

        self.artist.r = r
        self.artist.g = g
        self.artist.b = b

        if changed:
            self.colors_changed.emit()

        self.artist.update()
        self.artist.redraw()

    def update_current(self, *args):
        if self.artist is None:
            return

        for c in ['red', 'green', 'blue']:
            if self.current[c].isChecked():
                self.artist.contrast_layer = c
                self.current_changed.emit(c)
                break
        else:
            raise RuntimeError("Could not determine which layer is current")

    def update_visible(self, *args):
        if self.artist is None:
            return

        self.artist.layer_visible['red'] = self.vis['red'].isChecked()
        self.artist.layer_visible['green'] = self.vis['green'].isChecked()
        self.artist.layer_visible['blue'] = self.vis['blue'].isChecked()
        self.artist.update()
        self.artist.redraw()