Exemple #1
0
    def _add_time_point(self, center_x, center_y, time_point):
        """Add a single time point item."""
        x = center_x - (self.TIMEPOINT_DIAMETER / 2)
        y = center_y - (self.TIMEPOINT_DIAMETER / 2)

        # Create the acutal time point item
        time_point_item = QGraphicsEllipseItem(0, 0, self.TIMEPOINT_DIAMETER,
                                               self.TIMEPOINT_DIAMETER)

        # The used color is the strongest one of the FRM II colors.
        time_point_item.setBrush(QBrush(QColor(0x00, 0x71, 0xbb)))
        time_point_item.setPen(QPen(0))

        self.scene().addItem(time_point_item)
        time_point_item.setPos(x, y)

        # place the time point item above the timeline and the selection item
        time_point_item.setZValue(2)

        # Create the label of the time point showing the time in the
        # defined strftime format on the right side of the time point item.
        label = QGraphicsTextItem(time_point.strftime(self.STRFTIME_FMT))
        label.setFont(QFont('Monospace'))
        label_height = label.boundingRect().height()

        # minor height adjustment
        label_y = y - label_height / 6

        self.scene().addItem(label)
        label.setPos(x + self.SELECTION_DIAMETER + self.LABEL_SPACING, label_y)

        # store references to the item and the timepoint in the same dict
        # to be able to use it for forward and reverse lookup
        self._time_point_items[time_point] = time_point_item
        self._time_point_items[time_point_item] = time_point
Exemple #2
0
    def _select_item(self, item):
        """Select the given item by drawing a colored circle beneath the
        selected item (so it looks like a ring around it.
        Also emits the timepointSelected signal."""

        # The selection_item used to signal the selection of a timepoint
        # is always the same and is only moved.
        if self._selection_item is None:
            self._selection_item = QGraphicsEllipseItem(
                0, 0, self.SELECTION_DIAMETER, self.SELECTION_DIAMETER)

            # The used color is a cubical to the time point color
            self._selection_item.setBrush(QBrush(QColor(0x70, 0xbb, 0x00)))
            self._selection_item.setPen(QPen(0))
            self.scene().addItem(self._selection_item)

        # center position of the timepoint circle
        center_x = item.pos().x() + self.TIMEPOINT_DIAMETER / 2
        center_y = item.pos().y() + self.TIMEPOINT_DIAMETER / 2

        # move selection item
        self._selection_item.setPos(center_x - self.SELECTION_DIAMETER / 2,
                                    center_y - self.SELECTION_DIAMETER / 2)

        # store the selection_item like a timepoint item (using the timepoint
        # of the selected item)
        self._time_point_items[self._selection_item] = \
            self._time_point_items[item]

        # emit signal at the end to ensure a valid internal state before
        # anything can react to it
        self.timepointSelected.emit(self._time_point_items[item])
Exemple #3
0
 def update(self):
     outangle, r1 = self._calculate_reflection()
     # print(outangle, r1)
     tp = self.transformOriginPoint()
     tp.setX(r1)
     self.setTransformOriginPoint(tp)
     # print(self.rotation())
     self.setRotation(outangle)
     # print(self._crystal.x(), self.rotation())
     QGraphicsEllipseItem.update(self)
Exemple #4
0
 def __init__(self, x, y, size=60, width=10, parent=None, scene=None):
     self._width = width
     s = size + width / 2
     QGraphicsEllipseItem.__init__(self, QRectF(-QPoint(s, s),
                                   QSizeF(2 * s, 2 * s)), parent)
     self.setBrush(QBrush(statuscolor[status.OK]))
     if not parent and scene:
         scene.addItem(self)
     self.setPos(x, y)
     self.setState(status.OK)
Exemple #5
0
 def __init__(self, x, y, size=20, parent=None, scene=None):
     TableBase.__init__(self, x, y, size, parent, scene)
     self._halowidth = max(size / 4, 10)
     self._halo = Halo(x, y, size, self._halowidth, self, scene)
     self._tuberadius = size / 5
     p = QPointF(self._tuberadius, self._tuberadius)
     s = QSizeF(2 * self._tuberadius, 2 * self._tuberadius)
     self._tube = QGraphicsEllipseItem(QRectF(-p, s), self)
     self._tube.setPen(QPen(QColor('black'), 3))
     self._tube.setBrush(QBrush(QColor('white')))
     self._tube.setZValue(20)
Exemple #6
0
 def __init__(self, x, y, size=40, parent=None, scene=None):
     self._origin = QPoint(x, y)
     self._size = size
     self._radius = size / 2
     if not self._color:
         self._color = QColor('white')
     QGraphicsEllipseItem.__init__(self, QRectF(-QPoint(size, size),
                                   QSizeF(2 * size, 2 * size)), parent)
     if not parent and scene:
         scene.addItem(self)
     self.setPos(x, y)
     self.setBrush(QBrush(self._color))
Exemple #7
0
class DetTable(TableBase):
    """Class to display the detector including shielding and detector tube."""

    _color = QColor('#ff66ff')

    def __init__(self, x, y, size=20, parent=None, scene=None):
        TableBase.__init__(self, x, y, size, parent, scene)
        self._halowidth = max(size / 4, 10)
        self._halo = Halo(x, y, size, self._halowidth, self, scene)
        self._tuberadius = size / 5
        p = QPointF(self._tuberadius, self._tuberadius)
        s = QSizeF(2 * self._tuberadius, 2 * self._tuberadius)
        self._tube = QGraphicsEllipseItem(QRectF(-p, s), self)
        self._tube.setPen(QPen(QColor('black'), 3))
        self._tube.setBrush(QBrush(QColor('white')))
        self._tube.setZValue(20)
Exemple #8
0
class TimelineWidget(QGraphicsView):
    """General widget to display timeline with a list of ordered timepoints.
    A timepoint is selectable via click and the timepointSelected signal
    can be used to react to it."""
    timepointSelected = pyqtSignal(object)  # datetime.datetime object

    # general layout and design parameters
    TIMEPOINT_DIAMETER = 30
    SELECTION_DIAMETER = 40
    TIMEPOINT_SPACING = 50
    TIMELINE_WIDTH = 5
    LABEL_SPACING = 20
    MARGIN_HORIZONTAL = 5
    STRFTIME_FMT = '%H:%M:%S\n%Y-%m-%d'

    def __init__(self, parent=None):
        QGraphicsView.__init__(self, QGraphicsScene(), parent)
        self.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        self.setRenderHints(QPainter.Antialiasing
                            | QPainter.SmoothPixmapTransform)

        # margins set to 0 to simplify calculations
        self.setContentsMargins(0, 0, 0, 0)
        self.setViewportMargins(0, 0, 0, 0)

        # full viewport updates required to avoid optical double selections
        # caused by scrolling
        self.setViewportUpdateMode(QGraphicsView.FullViewportUpdate)

        self._time_points = []
        self._time_point_items = {}
        self._selection_item = None

        # start with at least one time point (current time) to be able
        # to reuse size calculation methods for the inital size
        self.setTimePoints([datetime.now()])

    @property
    def time_points(self):
        """Sorted list of all timepoints (sorted new to old)"""
        return self._time_points

    @property
    def selected_time_point(self):
        """Get the selected timeout as datetime object. None if there is no
        selection."""
        if self._selection_item is None:
            return None

        return self._time_point_items[self._selection_item]

    @property
    def previous_time_point(self):
        """Get the timepoint before (older than) the currently selected one as
        datetime object. None if there is no selection"""
        try:
            index = self._time_points.index(self.selected_time_point)
            return self._time_points[index + 1]
        except (ValueError, IndexError):
            return None

    def resizeEvent(self, event):
        """Clear and readd all items on resize. Avoids complex scaling."""
        self.scene().clear()
        self.setTimePoints(self._time_points)

    def setTimePoints(self, time_points):
        """Sets and list of datetime objects as timepoints, sets up all
        necessary graphics items and adjusts sizes."""

        self.scene().clear()
        self._selection_item = None

        # store the timepoints sorted from new to old
        self._time_points = list(reversed(sorted(time_points)))
        self._time_point_items = {}

        # draw the timeline
        self._timeline = self._add_timeline()

        # draw the time points
        self._add_time_points()

        # update the scene size and a slightly larger widget size to avoid
        # superfluous scrolling (and displaying of scroll bars)
        size = self.scene().itemsBoundingRect().size()
        self.setSceneRect(0, 0, size.width(), size.height() - 5)

        if time_points:
            self.setMinimumWidth(size.width() * 1.2)
            self.setMaximumWidth(size.width() * 1.2)

    def mousePressEvent(self, event):
        """Handle mouse press events to support item selection."""
        item = self.itemAt(event.pos())
        if item in self._time_point_items:
            self._select_item(item)

        return QGraphicsView.mousePressEvent(self, event)

    def _select_item(self, item):
        """Select the given item by drawing a colored circle beneath the
        selected item (so it looks like a ring around it.
        Also emits the timepointSelected signal."""

        # The selection_item used to signal the selection of a timepoint
        # is always the same and is only moved.
        if self._selection_item is None:
            self._selection_item = QGraphicsEllipseItem(
                0, 0, self.SELECTION_DIAMETER, self.SELECTION_DIAMETER)

            # The used color is a cubical to the time point color
            self._selection_item.setBrush(QBrush(QColor(0x70, 0xbb, 0x00)))
            self._selection_item.setPen(QPen(0))
            self.scene().addItem(self._selection_item)

        # center position of the timepoint circle
        center_x = item.pos().x() + self.TIMEPOINT_DIAMETER / 2
        center_y = item.pos().y() + self.TIMEPOINT_DIAMETER / 2

        # move selection item
        self._selection_item.setPos(center_x - self.SELECTION_DIAMETER / 2,
                                    center_y - self.SELECTION_DIAMETER / 2)

        # store the selection_item like a timepoint item (using the timepoint
        # of the selected item)
        self._time_point_items[self._selection_item] = \
            self._time_point_items[item]

        # emit signal at the end to ensure a valid internal state before
        # anything can react to it
        self.timepointSelected.emit(self._time_point_items[item])

    def _add_timeline(self):
        """Draw the timeline."""

        # height is either the necessary space to display all items or the
        # maximal available display size, so it's looks nicely in larger
        # windows and enables scrolling in smaller ones.
        height = self.TIMEPOINT_DIAMETER * len(self._time_points)
        height += self.TIMEPOINT_SPACING * len(self._time_points)
        height = max(height, self.viewport().height())

        # draw the timeline left aligned with enough space to draw the items
        # and the selection ring.
        x = self.MARGIN_HORIZONTAL + (self.SELECTION_DIAMETER / 2)

        # position the line on the left side of the item
        item = QGraphicsLineItem(0, 0, 0, height)

        # The used color for the timeline is the lightest one of the FRM II
        # colors
        item.setPen(QPen(QBrush(QColor(0xa3, 0xc1, 0xe7)),
                         self.TIMELINE_WIDTH))

        self.scene().addItem(item)

        # move the whole item to the desired timeline position
        item.setPos(x, 0)
        return item

    def _add_time_points(self):
        """Add all time point items."""
        if not self._time_points:
            return

        timeline_pos = self._timeline.pos()
        timeline_size = self._timeline.boundingRect().size()
        height = timeline_size.height()

        # time points are always equally distributed on the timeline
        spacing = height / float(len(self._time_points))

        center_x = timeline_pos.x()

        # add half of the items spacing on the top and bottom of the timeline
        start = timeline_pos.y() - spacing / 2

        for i, entry in enumerate(self._time_points):
            self._add_time_point(center_x, start + spacing * (i + 1), entry)

    def _add_time_point(self, center_x, center_y, time_point):
        """Add a single time point item."""
        x = center_x - (self.TIMEPOINT_DIAMETER / 2)
        y = center_y - (self.TIMEPOINT_DIAMETER / 2)

        # Create the acutal time point item
        time_point_item = QGraphicsEllipseItem(0, 0, self.TIMEPOINT_DIAMETER,
                                               self.TIMEPOINT_DIAMETER)

        # The used color is the strongest one of the FRM II colors.
        time_point_item.setBrush(QBrush(QColor(0x00, 0x71, 0xbb)))
        time_point_item.setPen(QPen(0))

        self.scene().addItem(time_point_item)
        time_point_item.setPos(x, y)

        # place the time point item above the timeline and the selection item
        time_point_item.setZValue(2)

        # Create the label of the time point showing the time in the
        # defined strftime format on the right side of the time point item.
        label = QGraphicsTextItem(time_point.strftime(self.STRFTIME_FMT))
        label.setFont(QFont('Monospace'))
        label_height = label.boundingRect().height()

        # minor height adjustment
        label_y = y - label_height / 6

        self.scene().addItem(label)
        label.setPos(x + self.SELECTION_DIAMETER + self.LABEL_SPACING, label_y)

        # store references to the item and the timepoint in the same dict
        # to be able to use it for forward and reverse lookup
        self._time_point_items[time_point] = time_point_item
        self._time_point_items[time_point_item] = time_point
Exemple #9
0
    def __init__(self):
        scene = QGraphicsScene()
        QGraphicsView.__init__(self, scene)
        self.setRenderHints(QPainter.Antialiasing)

        self._sample = Sample(0, 0, scene=scene)

        # draw the center point of the detector circle
        scene.addItem(QGraphicsEllipseItem(-2, -2, 4, 4))

        # draw the detector circle
        # scene.addItem(ArcGraphicsItem(0, 0, self.detradius + 10, 0, 180))

        # draw detector box
        self._detbox = DetectorBox(self.detradius, self.detopen)
        scene.addItem(self._detbox)

        # default values (used when no such devices are configured)
        self.values = {
            'rd1': 27.5,
            'rd2': 25.0,
            'rd3': 22.5,
            'rd4': 20.0,
            'rd5': 17.5,
            'rd6': 15.0,
            'rd7': 12.5,
            'rd8': 10.0,
            'rd9': 7.5,
            'rd10': 5.0,
            'rd11': 2.5,
            'rg1': 0.0,
            'rg2': 0.0,
            'rg3': 0.0,
            'rg4': 0.0,
            'rg5': 0.0,
            'rg6': 0.0,
            'rg7': 0.0,
            'rg8': 0.0,
            'rg9': 0.0,
            'rg10': 0.0,
            'rg11': 0.0,
            'ra1': 0.0,
            'ra2': 0.0,
            'ra3': 0.0,
            'ra4': 0.0,
            'ra5': 0.0,
            'ra6': 0.0,
            'ra7': 0.0,
            'ra8': 0.0,
            'ra9': 0.0,
            'ra10': 0.0,
            'ra11': 0.0,
            'ta1': 125.0,
            'ta2': 112.0,
            'ta3': 99.0,
            'ta4': 86.0,
            'ta5': 73.0,
            'ta6': 60.0,
            'ta7': 47.0,
            'ta8': 34.0,
            'ta9': 21.0,
            'ta10': 8.0,
            'ta11': -5.0,
            'cad': 0.0,
            'lsa': 910.,
        }
        self.targets = self.values.copy()
        self.status = {
            'rd1': status.OK,
            'rd2': status.OK,
            'rd3': status.OK,
            'rd4': status.OK,
            'rd5': status.OK,
            'rd6': status.OK,
            'rd7': status.OK,
            'rd8': status.OK,
            'rd9': status.OK,
            'rd10': status.OK,
            'rd11': status.OK,
            'rg1': status.OK,
            'rg2': status.OK,
            'rg3': status.OK,
            'rg4': status.OK,
            'rg5': status.OK,
            'rg6': status.OK,
            'rg7': status.OK,
            'rg8': status.OK,
            'rg9': status.OK,
            'rg10': status.OK,
            'rg11': status.OK,
            'ra1': status.OK,
            'ra2': status.OK,
            'ra3': status.OK,
            'ra4': status.OK,
            'ra5': status.OK,
            'ra6': status.OK,
            'ra7': status.OK,
            'ra8': status.OK,
            'ra9': status.OK,
            'ra10': status.OK,
            'ra11': status.OK,
            'ta1': status.OK,
            'ta2': status.OK,
            'ta3': status.OK,
            'ta4': status.OK,
            'ta5': status.OK,
            'ta6': status.OK,
            'ta7': status.OK,
            'ta8': status.OK,
            'ta9': status.OK,
            'ta10': status.OK,
            'ta11': status.OK,
            'cad': status.OK,
            'lsa': status.OK,
        }

        for i in range(self.num_crystals):
            dt = DetectorTable(self.detsize, self.detradius, scene=scene)
            self._detectors.append(dt)
            self._guides.append(DetectorGuide(dt))

            t = TableTarget(0, 0, self.detsize, scene=scene)
            # move the origin to make the rotation very easy
            t.setPos(-self.detradius, -self.detsize)
            t.setTransformOriginPoint(self.detradius, 0)
            self._detectors_t.append(t)

            y = (self.num_crystals // 2 - i) * 20
            self._crystals.append(
                CrystalTable(0, y, self.crystalsize, scene=scene))
            self._crystals_t.append(
                TableTarget(0, y, self.crystalsize, scene=scene))
            self._inbeams.append(
                Beam(self._sample, self._crystals[i], scene=scene))
            self._outbeams.append(
                Beam(self._crystals[i], self._detectors[i], scene=scene))
            # self._outbeams.append(
            #    Beam(self._crystals[i], self._reflections[i], scene=scene))
            # self._reflections.append(
            #     Reflex(r, self._crystals[i], self._sample,
            #            self._detectors[i], scene=scene))
        QGraphicsView.update(self)