Пример #1
0
    def __init__(self,
                 name=None,
                 *,
                 enable_meter=True,
                 enable_transform=True,
                 parent=None):
        super().__init__(parent=parent)

        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        self._items = set()
        self._plot_items = set()
        self._plot_items2 = set()
        self._annotation_items = []
        self._n_vis_annotation_items = 0

        self._vb = pg.ViewBox(parent=self)
        self._vb2 = None

        if name is not None:
            self._vb.register(name)

        self._legend = None
        self._axes = {}
        self._meter = pg.LabelItem('',
                                   size='11pt',
                                   justify='left',
                                   color='6A3D9A',
                                   parent=self)
        self._title = pg.LabelItem('', size='11pt', parent=self)

        # context menu
        self._show_cross_cb = QCheckBox("Cross cursor")

        self._show_x_grid_cb = QCheckBox("Show X Grid")
        self._show_y_grid_cb = QCheckBox("Show Y Grid")
        self._grid_opacity_sld = QSlider(Qt.Horizontal)
        self._grid_opacity_sld.setMinimum(0)
        self._grid_opacity_sld.setMaximum(255)
        self._grid_opacity_sld.setValue(160)
        self._grid_opacity_sld.setSingleStep(1)

        self._log_x_cb = QCheckBox("Log X")
        self._log_y_cb = QCheckBox("Log Y")

        self._menu = None
        self._enable_transform = enable_transform
        self._enable_meter = enable_meter

        self._show_meter = False

        self._layout = QGraphicsGridLayout()

        self.initUI()
        self.initConnections()
Пример #2
0
    def __init__(self, name, position, players, parent):
        super().__init__(parent=parent)
        self.name = name
        self.position = position
        self.tokens = []
        self.owner = False

        self.layout = QGraphicsLinearLayout()
        self.token_layout = QGraphicsGridLayout()
        self.token_layout.setSpacing(0.5)

        self.name_on_tile = QGraphicsWidget()
        self.info = QGraphicsWidget()

        self.layout.setOrientation(Qt.Vertical)
        self.setContentsMargins(75, 0, 90, 0)

        property_name = QGraphicsTextItem(self.name, parent=self.name_on_tile)
        
        if name in parent.properties:
            self.real_pos = parent.board_positions[parent.properties.index(name)]

            if self.real_pos in mp_core.PROPERTIES:
                self.price = mp_core.PROPERTIES[self.real_pos][name]["Price"]
                self.rent = mp_core.PROPERTIES[self.real_pos][name]["Rent"]
                money_info = QGraphicsTextItem(f"Price: {self.price}", parent=self.info)

            elif self.real_pos in mp_core.SPECIAL_CASES:
                tile = list(mp_core.SPECIAL_CASES[self.real_pos].keys())[0]

                if tile == "Start":
                    money_start = QGraphicsTextItem("Free monay: 200", parent=self.info)

                    for player in players:
                        token = Token(player)
                        token.set_tile(tile)
                        self.tokens.append(token)

                    self.display_game_pieces()

                elif tile in ["Income Tax", "Super Tax"]:
                    money = mp_core.SPECIAL_CASES[self.real_pos][tile]
                    money_tax = QGraphicsTextItem(f"Tax: -{money}", parent=self.info)

        self.layout.addItem(self.name_on_tile)
        self.layout.addItem(self.info)
        self.layout.addItem(self.token_layout)
        self.setLayout(self.layout)

        self.layout.setAlignment(self.layout, Qt.AlignCenter)
Пример #3
0
    def __init__(self, players):
        super().__init__()
        self.total_tokens = []

        for player in players:
            self.total_tokens.append(Token(player))

        self.board_layout = QGraphicsGridLayout()
        self.board_layout.setSpacing(0)

        self.properties = [
            "Free Parking", "Strand", "Chance", "Fleet Street", "Trafalgar Square",
            "Fenchurch Street station", "Leicester Square", "Coventry Street", "Water Works", "Piccadilly", "Go to Jail",
            "Vine Street", "", "", "", "", "", "", "", "", "", "Regent Street",
            "Marlborough Street", "", "", "", "", "", "", "", "", "", "Oxford Street",
            "Community Chest", "", "", "", "", "", "", "", "", "", "Community Chest",
            "Bow Street", "", "", "", "", "", "", "", "", "", "Bond Street",
            "Marylebine station", "", "", "", "", "", "", "", "", "", "Liverpool Street station",
            "Northumberland Avenue", "", "", "", "", "", "", "", "", "", "Chance",
            "Whitehall", "", "", "", "", "", "", "", "", "", "Park Lane",
            "Electric Company", "", "", "", "", "", "", "", "", "", "Super Tax",
            "Pall Mall", "", "", "", "", "", "", "", "", "", "Mayfair",
            "Visit Jail", "Pentonville Road", "Euston Road", "Chance", "The Angel Islington", "King's Cross station",
            "Income Tax", "Whitechapel Road", "Community Chest", "Old Kent Road", "Start"
        ]

        self.board_positions = {
            0: 20, 1: 21, 2: 22, 3: 23, 4: 24,
            5: 25, 6: 26, 7: 27, 8: 28, 9: 29,
            10: 30, 11: 19, 21: 31, 22: 18, 32: 32,
            33: 17, 43: 33, 44: 16, 54: 34, 55: 15,
            65: 35, 66: 14, 76: 36, 77: 13, 87: 37,
            88: 12, 98: 38, 99: 11, 109: 39, 110: 10,
            111: 9, 112: 8, 113: 7, 114: 6, 115: 5,
            116: 4, 117: 3, 118: 2, 119: 1, 120: 0
        }

        positions = [(i, j) for i in range(11) for j in range(11)]

        for position, name in zip(positions, self.properties):
            if name == "":
                continue
            
            self.board_layout.addItem(Tile(name, grid2pos(position), players, parent=self), *position)

        self.setLayout(self.board_layout)
Пример #4
0
    def __init__(self, image=None, fillHistogram=True, bounds: tuple = None):
        GraphicsWidget.__init__(self)
        self.imageItem = lambda: None  # fake a dead weakref

        self.layout = QGraphicsGridLayout()
        self.setLayout(self.layout)
        self.layout.setContentsMargins(1, 1, 1, 1)
        self.layout.setSpacing(0)
        self.vb = ViewBox(parent=self)
        # self.vb.setMaximumHeight(152)
        # self.vb.setMinimumWidth(45)
        self.vb.setMouseEnabled(x=True, y=False)

        self.region = LinearRegionItem([0, 1], 'vertical', swapMode='block', bounds=bounds)
        self.region.setZValue(1000)
        self.vb.addItem(self.region)
        self.region.lines[0].addMarker('<|', 0.5)
        self.region.lines[1].addMarker('|>', 0.5)
        self.region.sigRegionChanged.connect(self.regionChanging)
        self.region.sigRegionChangeFinished.connect(self.regionChanged)

        self.axis = AxisItem('bottom', linkView=self.vb, maxTickLength=-10, parent=self)
        self.layout.addItem(self.axis, 1, 0)
        self.layout.addItem(self.vb, 0, 0)
        self.range = None
        self.vb.sigRangeChanged.connect(self.viewRangeChanged)

        self.plot = PlotCurveItem(pen=(200, 200, 200, 100))
        # self.plot.rotate(90)
        self.vb.addItem(self.plot)

        self.fillHistogram(fillHistogram)
        self._showRegions()

        self.autoHistogramRange()

        if image is not None:
            self.setImageItem(image)
Пример #5
0
    def __init__(self,
                 parent=None,
                 direction=Qt.LeftToRight,
                 node=None,
                 icon=None,
                 iconSize=None,
                 **args):
        QGraphicsWidget.__init__(self, parent, **args)
        self.setAcceptedMouseButtons(Qt.NoButton)
        self.__direction = direction

        self.setLayout(QGraphicsLinearLayout(Qt.Horizontal))

        # Set the maximum size, otherwise the layout can't grow beyond its
        # sizeHint (and we need it to grow so the widget can grow and keep the
        # contents centered vertically.
        self.layout().setMaximumSize(QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX))

        self.setSizePolicy(QSizePolicy.MinimumExpanding,
                           QSizePolicy.MinimumExpanding)

        self.__iconSize = iconSize or QSize(64, 64)
        self.__icon = icon

        self.__iconItem = QGraphicsPixmapItem(self)
        self.__iconLayoutItem = GraphicsItemLayoutItem(item=self.__iconItem)

        self.__channelLayout = QGraphicsGridLayout()
        self.__channelAnchors = []

        if self.__direction == Qt.LeftToRight:
            self.layout().addItem(self.__iconLayoutItem)
            self.layout().addItem(self.__channelLayout)
            channel_alignemnt = Qt.AlignRight

        else:
            self.layout().addItem(self.__channelLayout)
            self.layout().addItem(self.__iconLayoutItem)
            channel_alignemnt = Qt.AlignLeft

        self.layout().setAlignment(self.__iconLayoutItem, Qt.AlignCenter)
        self.layout().setAlignment(self.__channelLayout,
                                   Qt.AlignVCenter | channel_alignemnt)

        if node is not None:
            self.setSchemeNode(node)
Пример #6
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        width = Settings.NUM_BLOCKS_X * (Settings.WIDTH + 1)
        height = Settings.NUM_BLOCKS_Y * (Settings.HEIGHT + 1)
        self.setSceneRect(0, 0, height, width)
        self.setItemIndexMethod(QtWidgets.QGraphicsScene.NoIndex)

        layout = QGraphicsGridLayout()
        layout.setVerticalSpacing(0)
        layout.setHorizontalSpacing(0)

        form = QGraphicsWidget()
        form.setLayout(layout)

        for i in range(Settings.NUM_BLOCKS_X):
            layout.setRowSpacing(i, 0)
            layout.setRowMaximumHeight(i, Settings.HEIGHT)
            for j in range(Settings.NUM_BLOCKS_Y):
                layout.setColumnSpacing(j, 0)
                layout.setColumnMaximumWidth(j, Settings.WIDTH)
                if j - i == 1:
                    rect = RectangleWidget(QRectF(0, 0, Settings.WIDTH,
                                                  Settings.HEIGHT),
                                           path=True)
                elif j - i == 3:
                    rect = RectangleWidget(QRectF(0, 0, Settings.WIDTH,
                                                  Settings.HEIGHT),
                                           item=True)
                else:
                    rect = RectangleWidget(
                        QRectF(0, 0, Settings.WIDTH, Settings.HEIGHT))

                layout.addItem(rect, i, j)

        self.addItem(form)
Пример #7
0
class Tile(QGraphicsWidget):
    def __init__(self, name, position, players, parent):
        super().__init__(parent=parent)
        self.name = name
        self.position = position
        self.tokens = []
        self.owner = False

        self.layout = QGraphicsLinearLayout()
        self.token_layout = QGraphicsGridLayout()
        self.token_layout.setSpacing(0.5)

        self.name_on_tile = QGraphicsWidget()
        self.info = QGraphicsWidget()

        self.layout.setOrientation(Qt.Vertical)
        self.setContentsMargins(75, 0, 90, 0)

        property_name = QGraphicsTextItem(self.name, parent=self.name_on_tile)
        
        if name in parent.properties:
            self.real_pos = parent.board_positions[parent.properties.index(name)]

            if self.real_pos in mp_core.PROPERTIES:
                self.price = mp_core.PROPERTIES[self.real_pos][name]["Price"]
                self.rent = mp_core.PROPERTIES[self.real_pos][name]["Rent"]
                money_info = QGraphicsTextItem(f"Price: {self.price}", parent=self.info)

            elif self.real_pos in mp_core.SPECIAL_CASES:
                tile = list(mp_core.SPECIAL_CASES[self.real_pos].keys())[0]

                if tile == "Start":
                    money_start = QGraphicsTextItem("Free monay: 200", parent=self.info)

                    for player in players:
                        token = Token(player)
                        token.set_tile(tile)
                        self.tokens.append(token)

                    self.display_game_pieces()

                elif tile in ["Income Tax", "Super Tax"]:
                    money = mp_core.SPECIAL_CASES[self.real_pos][tile]
                    money_tax = QGraphicsTextItem(f"Tax: -{money}", parent=self.info)

        self.layout.addItem(self.name_on_tile)
        self.layout.addItem(self.info)
        self.layout.addItem(self.token_layout)
        self.setLayout(self.layout)

        self.layout.setAlignment(self.layout, Qt.AlignCenter)

    def is_owned(self):
        if self.owner:
            return True
        else:
            return False

    def set_owner(self, player):
        self.owner = player

    def get_owner(self):
        return self.owner

    def add_token(self, token):
        self.tokens.append(token)

    def remove_token(self, token):
        self.tokens.remove(token)

    def get_name(self):
        return self.name

    def get_pos(self):
        return self.position

    def display_game_pieces(self):
        if len(self.tokens) == 6 or len(self.tokens) == 5 or len(self.tokens) == 4:
            sub_layout = True
            sub_pos = 0
        else:
            sub_layout = False

        for i, token in enumerate(self.tokens):
            if (len(self.tokens) == 4 and i >= 2) or (
                len(self.tokens) >= 5 and i >= 3
            ):
                if sub_layout:
                    self.token_layout.addItem(token, 1, sub_pos)
                    sub_pos += 1
            else:
                self.token_layout.addItem(token, 0, i)

        return self.token_layout

    def paint(self, painter, option, widget):
        painter.drawRects(self.boundingRect())

    def has_tokens(self):
        if self.tokens != []:
            return self.tokens
        else:
            return

    def get_token(self, player):
        for token in self.tokens:
            if player == token.get_player():
                return token

        return

    def remove_token_layout(self, token):
        self.token_layout.removeItem(token)
Пример #8
0
 def initUI(self):
     layout = QGraphicsGridLayout()
     layout.setContentsMargins(1, 1, 1, 1)
     layout.setSpacing(0)
     layout.addItem(self._axis, 0, 0)
     layout.addItem(self._vb, 0, 1)
     layout.addItem(self._gradient, 0, 2)
     self.setLayout(layout)
Пример #9
0
class PlotArea(pg.GraphicsWidget):
    """GraphicsWidget implementing a standard 2D plotting area with axes.

    Implemented based on pyqtgraph.PlotItem.

    It has the following functionalities:

    - Manage placement of a ViewBox, AxisItems, and LabelItems;
    - Manage a list of GraphicsItems displayed inside the ViewBox;
    - Implement a context menu with display options.
    """

    cross_toggled_sgn = pyqtSignal(bool)

    _METER_ROW = 0
    _TITLE_ROW = 1

    _MAX_ANNOTATION_ITEMS = 10

    def __init__(self,
                 name=None,
                 *,
                 enable_meter=True,
                 enable_transform=True,
                 parent=None):
        super().__init__(parent=parent)

        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        self._items = set()
        self._plot_items = set()
        self._plot_items2 = set()
        self._annotation_items = []
        self._n_vis_annotation_items = 0

        self._vb = pg.ViewBox(parent=self)
        self._vb2 = None

        if name is not None:
            self._vb.register(name)

        self._legend = None
        self._axes = {}
        self._meter = pg.LabelItem('',
                                   size='11pt',
                                   justify='left',
                                   color='6A3D9A',
                                   parent=self)
        self._title = pg.LabelItem('', size='11pt', parent=self)

        # context menu
        self._show_cross_cb = QCheckBox("Cross cursor")

        self._show_x_grid_cb = QCheckBox("Show X Grid")
        self._show_y_grid_cb = QCheckBox("Show Y Grid")
        self._grid_opacity_sld = QSlider(Qt.Horizontal)
        self._grid_opacity_sld.setMinimum(0)
        self._grid_opacity_sld.setMaximum(255)
        self._grid_opacity_sld.setValue(160)
        self._grid_opacity_sld.setSingleStep(1)

        self._log_x_cb = QCheckBox("Log X")
        self._log_y_cb = QCheckBox("Log Y")

        self._menu = None
        self._enable_transform = enable_transform
        self._enable_meter = enable_meter

        self._show_meter = False

        self._layout = QGraphicsGridLayout()

        self.initUI()
        self.initConnections()

    def initUI(self):
        layout = self._layout

        layout.setContentsMargins(1, 1, 1, 1)
        layout.setHorizontalSpacing(0)
        layout.setVerticalSpacing(0)

        layout.addItem(self._meter, self._METER_ROW, 1)
        layout.addItem(self._title, self._TITLE_ROW, 1)
        layout.addItem(self._vb, 3, 1)

        for i in range(5):
            layout.setRowPreferredHeight(i, 0)
            layout.setRowMinimumHeight(i, 0)
            layout.setRowSpacing(i, 0)
            layout.setRowStretchFactor(i, 1)

        for i in range(3):
            layout.setColumnPreferredWidth(i, 0)
            layout.setColumnMinimumWidth(i, 0)
            layout.setColumnSpacing(i, 0)
            layout.setColumnStretchFactor(i, 1)

        layout.setRowStretchFactor(2, 100)
        layout.setColumnStretchFactor(1, 100)

        self.setLayout(layout)

        self._initAxisItems()
        self.setTitle()
        self.showMeter(self._show_meter)

        self._initContextMenu()

    def initConnections(self):
        self._show_cross_cb.toggled.connect(self._onShowCrossChanged)

        self._show_x_grid_cb.toggled.connect(self._onShowGridChanged)
        self._show_y_grid_cb.toggled.connect(self._onShowGridChanged)
        self._grid_opacity_sld.sliderReleased.connect(self._onShowGridChanged)

        self._log_x_cb.toggled.connect(self._onLogXChanged)
        self._log_y_cb.toggled.connect(self._onLogYChanged)

    def _initContextMenu(self):
        self._menu = [QMenu("Meter"), QMenu("Grid"), QMenu("Transform")]

        meter_menu = self._menu[0]
        cross_act = QWidgetAction(meter_menu)
        cross_act.setDefaultWidget(self._show_cross_cb)
        meter_menu.addAction(cross_act)

        grid_menu = self._menu[1]
        show_x_act = QWidgetAction(grid_menu)
        show_x_act.setDefaultWidget(self._show_x_grid_cb)
        grid_menu.addAction(show_x_act)
        show_y_act = QWidgetAction(grid_menu)
        show_y_act.setDefaultWidget(self._show_y_grid_cb)
        grid_menu.addAction(show_y_act)
        opacity_act = QWidgetAction(grid_menu)
        widget = QWidget()
        layout = QHBoxLayout()
        layout.addWidget(QLabel("Opacity"))
        layout.addWidget(self._grid_opacity_sld)
        widget.setLayout(layout)
        opacity_act.setDefaultWidget(widget)
        grid_menu.addAction(opacity_act)

        transform_menu = self._menu[2]
        log_x_act = QWidgetAction(transform_menu)
        log_x_act.setDefaultWidget(self._log_x_cb)
        transform_menu.addAction(log_x_act)
        log_y_act = QWidgetAction(transform_menu)
        log_y_act.setDefaultWidget(self._log_y_cb)
        transform_menu.addAction(log_y_act)

    def _initAxisItems(self):
        for orient, pos in (('top', (2, 1)), ('bottom', (4, 1)),
                            ('left', (3, 0)), ('right', (3, 2))):
            axis = pg.AxisItem(orientation=orient, parent=self)

            axis.linkToView(self._vb)
            self._axes[orient] = {'item': axis, 'pos': pos}
            self._layout.addItem(axis, *pos)
            axis.setZValue(-1000)
            axis.setFlag(axis.ItemNegativeZStacksBehindParent)

            self.showAxis(orient, orient in ['left', 'bottom'])

    def getViewBox(self):
        return self._vb

    def clearAllPlotItems(self):
        """Clear data on all the plot items."""
        for item in chain(self._plot_items, self._plot_items2):
            item.setData([], [])

    @pyqtSlot(bool)
    def _onShowCrossChanged(self, state):
        self.showMeter(state)
        self.cross_toggled_sgn.emit(state)

    @pyqtSlot()
    def _onShowGridChanged(self):
        alpha = self._grid_opacity_sld.value()
        x = alpha if self._show_x_grid_cb.isChecked() else False
        y = alpha if self._show_y_grid_cb.isChecked() else False
        self.getAxis('bottom').setGrid(x)
        self.getAxis('left').setGrid(y)

    @pyqtSlot(bool)
    def _onLogXChanged(self, state):
        for item in chain(self._plot_items, self._plot_items2):
            item.setLogX(state)
        self.getAxis("bottom").setLogMode(state)
        self._vb.autoRange(disableAutoRange=False)

    @pyqtSlot(bool)
    def _onLogYChanged(self, state):
        for item in self._plot_items:
            item.setLogY(state)
        self.getAxis("left").setLogMode(state)
        self._vb.autoRange(disableAutoRange=False)

    def addItem(self, item, ignore_bounds=False, y2=False):
        """Add a graphics item to ViewBox."""
        if item in self._items:
            warnings.warn(f'Item {item} already added to PlotItem, ignoring.')
            return

        self._items.add(item)

        if isinstance(item, pg.PlotItem):
            if y2:
                if self._log_x_cb.isChecked():
                    item.setLogX(True)

                self._plot_items2.add(item)
            else:
                if self._log_x_cb.isChecked():
                    item.setLogX(True)

                if self._log_y_cb.isChecked():
                    item.setLogY(True)

                self._plot_items.add(item)

            name = item.name()
            if self._legend is not None and name:
                self._legend.addItem(item, name)

        if y2:
            vb = self._vb2
            if vb is None:
                vb = pg.ViewBox()
                self.scene().addItem(vb)
                right_axis = self.getAxis('right')
                right_axis.linkToView(vb)
                right_axis.show()
                vb.setXLink(self._vb)
                self._vb2 = vb
                self._vb.sigResized.connect(self._updateY2View)
        else:
            vb = self._vb

        vb.addItem(item, ignoreBounds=ignore_bounds)

    def _updateY2View(self):
        self._vb2.setGeometry(self._vb.sceneBoundingRect())
        # not sure this is required
        # vb.linkedViewChanged(self._plot_area.vb, vb.XAxis)

    def removeItem(self, item):
        """Add a graphics item to ViewBox."""
        if item not in self._items:
            return

        if item in self._annotation_items:
            # it is tricky to update n_vis_annotation_items
            raise RuntimeError("Annotation item is not allowed to be removed "
                               "using 'removeItem' method!")

        self._items.remove(item)

        if item in self._plot_items2:
            self._plot_items2.remove(item)
            if self._legend is not None and item.name():
                self._legend.removeItem(item)
            self._vb2.removeItem(item)
            return

        if item in self._plot_items:
            self._plot_items.remove(item)
            if self._legend is not None and item.name():
                self._legend.removeItem(item)

        self._vb.removeItem(item)

    def removeAllItems(self):
        """Remove all graphics items from the ViewBox."""
        for item in self._items:
            if item in self._plot_items2:
                self._vb2.removeItem(item)
            else:
                self._vb.removeItem(item)

        if self._legend is not None:
            self._legend.clear()

        self._plot_items.clear()
        self._plot_items2.clear()
        self._annotation_items.clear()
        self._n_vis_annotation_items = 0
        self._items.clear()

    def getContextMenus(self, event):
        """Override."""
        start = 0
        end = len(self._menu)
        if not self._enable_transform:
            end -= 1
        if not self._enable_meter:
            start += 1
        return self._menu[start:end]

    def getAxis(self, axis):
        """Return the specified AxisItem.

        :param str axis: one of 'left', 'bottom', 'right', or 'top'.
        """
        return self._axes[axis]['item']

    def showAxis(self, axis, show=True):
        """Show or hide the given axis.

        :param str axis: one of 'left', 'bottom', 'right', or 'top'.
        :param bool show: whether to show the axis.
        """
        s = self.getAxis(axis)
        if show:
            s.show()
        else:
            s.hide()

    def addLegend(self, offset=(30, 30), **kwargs):
        """Add a LegendItem if it does not exist."""
        if self._legend is None:
            self._legend = pg.LegendItem(offset=offset, pen='k', **kwargs)
            self._legend.setParentItem(self._vb)

            for item in chain(self._plot_items, self._plot_items2):
                name = item.name()
                if name:
                    self._legend.addItem(item, name)

        return self._legend

    def showLegend(self, show=True):
        """Show or hide the legend.

        :param bool show: whether to show the legend.
        """
        if show:
            self._legend.show()
        else:
            self._legend.hide()

    def setLabel(self, axis, text=None, units=None, **args):
        """Set the label for an axis. Basic HTML formatting is allowed.

        :param str axis: one of 'left', 'bottom', 'right', or 'top'.
        :param str text: text to display along the axis. HTML allowed.
        """
        self.getAxis(axis).setLabel(text=text, units=units, **args)
        self.showAxis(axis)

    def showLabel(self, axis, show=True):
        """Show or hide one of the axis labels.

        :param str axis: one of 'left', 'bottom', 'right', or 'top'.
        :param bool show: whether to show the label.
        """
        self.getAxis(axis).showLabel(show)

    def showMeter(self, show=True):
        """Show or hide the meter bar.

        :param bool show: whether to show the meter bar.
        """
        row = self._METER_ROW
        if not show:
            self._meter.setMaximumHeight(0)
            self._layout.setRowFixedHeight(row, 0)
            self._meter.setVisible(False)
        else:
            self._meter.setMaximumHeight(30)
            self._layout.setRowFixedHeight(row, 30)
            self._meter.setVisible(True)

        self._show_meter = show

    def setMeter(self, pos):
        """Set the meter of the plot."""
        if not self._show_meter:
            return

        if pos is None:
            self._meter.setText("")
        else:
            x, y = pos
            self._meter.setText(f"x = {x}, y = {y}")

    def setAnnotationList(self, x, y, values=None):
        """Set a list of annotation items.

        :param list-like x: x coordinate of the annotated point.
        :param list-like y: y coordinate of the annotated point.
        :param list-like values: a list of annotation text.
        """

        # Don't waste time to check the list lengths.

        a_items = self._annotation_items

        if values is None:
            values = x
        values = values[:self._MAX_ANNOTATION_ITEMS]
        n_pts = len(values)

        n_items = len(a_items)
        if n_items < n_pts:
            for i in range(n_pts - n_items):
                item = pg.TextItem(color=FColor.mkColor('b'), anchor=(0.5, 2))
                self.addItem(item)
                a_items.append(item)

        n_vis = self._n_vis_annotation_items
        if n_vis < n_pts:
            for i in range(n_vis, n_pts):
                a_items[i].show()
        elif n_vis > n_pts:
            for i in range(n_pts, n_vis):
                a_items[i].hide()
        self._n_vis_annotation_items = n_pts

        for i in range(n_pts):
            a_items[i].setPos(x[i], y[i])
            a_items[i].setText(f"{values[i]:.4f}")

    def setTitle(self, *args, **kwargs):
        """Set the title of the plot."""
        row = self._TITLE_ROW
        title = None if len(args) == 0 else args[0]
        if title is None:
            self._title.setMaximumHeight(0)
            self._layout.setRowFixedHeight(row, 0)
            self._title.setVisible(False)
        else:
            self._title.setMaximumHeight(30)
            self._layout.setRowFixedHeight(row, 30)
            self._title.setText(title, **kwargs)
            self._title.setVisible(True)

    def setAspectLocked(self, *args, **kwargs):
        self._vb.setAspectLocked(*args, **kwargs)

    def invertX(self, *args, **kwargs):
        self._vb.invertX(*args, **kwargs)

    def invertY(self, *args, **kwargs):
        self._vb.invertY(*args, **kwargs)

    def autoRange(self, *args, **kwargs):
        self._vb.autoRange(*args, **kwargs)

    def mapSceneToView(self, *args, **kwargs):
        return self._vb.mapSceneToView(*args, **kwargs)
Пример #10
0
    def __init__(self, dither, detectors, *args):
        super().__init__(*args)

        self._enabled_detectors = detectors

        self._boxes = {
        }  # this will be of the form {detector_number: DetectorBox}

        self.gv_layout = QGraphicsGridLayout()

        self.gv_layout.setSpacing(0)

        min_length = DetectorBox.length * 4 + 6

        self._min_length = min_length

        self._dither = dither

        self.gv_layout.setMinimumSize(min_length, min_length)
        self.gv_layout.setMaximumSize(min_length, min_length)
        self.gv_layout.setContentsMargins(0, 0, 0, 0)

        self.setMinimumWidth(min_length)
        self.setMinimumHeight(min_length)

        self.setMaximumWidth(min_length + 20)
        self.setMaximumHeight(min_length + 20)

        self._init_boxes()

        gv_widget = QGraphicsWidget()

        gv_widget.setLayout(self.gv_layout)

        gv_widget.setContentsMargins(0, 0, 0, 0)

        scene = QGraphicsScene()

        scene.addItem(gv_widget)

        scene.setSceneRect(0, 0, min_length, min_length)

        view = QGraphicsView()

        view.setMouseTracking(True)

        view.setViewportMargins(0, 0, 0, 0)

        view.setGeometry(0, 0, min_length, min_length)

        view.setStyleSheet("border: 0px; margin: 0px; padding: 0px;")

        view.setScene(scene)

        view.setTransform(flip_vertical, True)

        layout = QVBoxLayout()

        layout.addWidget(view)

        self.setLayout(layout)
Пример #11
0
class MultiDetectorSelector(QWidget):
    """
    Constructs a detector selector consisting of 4 x 4 squares, numbered to be consistent with the SIR numbering scheme.
    This allows the user to specify which detectors they are interested in viewing / inspecting.
    """

    updated = pyqtSignal()

    def __init__(self, dither, detectors, *args):
        super().__init__(*args)

        self._enabled_detectors = detectors

        self._boxes = {
        }  # this will be of the form {detector_number: DetectorBox}

        self.gv_layout = QGraphicsGridLayout()

        self.gv_layout.setSpacing(0)

        min_length = DetectorBox.length * 4 + 6

        self._min_length = min_length

        self._dither = dither

        self.gv_layout.setMinimumSize(min_length, min_length)
        self.gv_layout.setMaximumSize(min_length, min_length)
        self.gv_layout.setContentsMargins(0, 0, 0, 0)

        self.setMinimumWidth(min_length)
        self.setMinimumHeight(min_length)

        self.setMaximumWidth(min_length + 20)
        self.setMaximumHeight(min_length + 20)

        self._init_boxes()

        gv_widget = QGraphicsWidget()

        gv_widget.setLayout(self.gv_layout)

        gv_widget.setContentsMargins(0, 0, 0, 0)

        scene = QGraphicsScene()

        scene.addItem(gv_widget)

        scene.setSceneRect(0, 0, min_length, min_length)

        view = QGraphicsView()

        view.setMouseTracking(True)

        view.setViewportMargins(0, 0, 0, 0)

        view.setGeometry(0, 0, min_length, min_length)

        view.setStyleSheet("border: 0px; margin: 0px; padding: 0px;")

        view.setScene(scene)

        view.setTransform(flip_vertical, True)

        layout = QVBoxLayout()

        layout.addWidget(view)

        self.setLayout(layout)

    @property
    def dither_number(self):
        return self._dither

    @property
    def min_length(self):
        return self._min_length

    def _init_boxes(self):
        for row in range(4):
            for column in range(4):
                detector_id = box_id(row, column)
                enabled = detector_id in self._enabled_detectors
                box = DetectorBox(row, column, enabled)
                box.set_parent_selector(self)
                self._boxes[detector_id] = box
                box_layout = DetectorBoxLayout(box)
                self.gv_layout.addItem(box_layout, row, column)
                self.gv_layout.setRowAlignment(row, Qt.AlignCenter)
                self.gv_layout.setColumnAlignment(column, Qt.AlignCenter)

    def selected_detectors(self):
        '''
        Returns a list of IDs of the selected boxes. If there are no selected boxes, then None is returned
        '''
        selected = [
            box.detector_id for box in self._boxes.values() if box.selected
        ]

        return selected if len(selected) > 0 else None

    def selection_changed(self):
        self.updated.emit()
Пример #12
0
class HistogramItem(GraphicsWidget):
    """
    This is a graphicsWidget which provides controls for adjusting the display of an image.

    Includes:

    - Image histogram 
    - Movable region over histogram to select black/white levels

    Parameters
    ----------
    image : ImageItem or None
        If *image* is provided, then the control will be automatically linked to
        the image and changes to the control will be immediately reflected in
        the image's appearance.
    fillHistogram : bool
        By default, the histogram is rendered with a fill.
        For performance, set *fillHistogram* = False.
    """

    sigLevelsChanged = pyqtSignal(object)
    sigLevelChangeFinished = pyqtSignal(object)

    def __init__(self, image=None, fillHistogram=True, bounds: tuple = None):
        GraphicsWidget.__init__(self)
        self.imageItem = lambda: None  # fake a dead weakref

        self.layout = QGraphicsGridLayout()
        self.setLayout(self.layout)
        self.layout.setContentsMargins(1, 1, 1, 1)
        self.layout.setSpacing(0)
        self.vb = ViewBox(parent=self)
        # self.vb.setMaximumHeight(152)
        # self.vb.setMinimumWidth(45)
        self.vb.setMouseEnabled(x=True, y=False)

        self.region = LinearRegionItem([0, 1], 'vertical', swapMode='block', bounds=bounds)
        self.region.setZValue(1000)
        self.vb.addItem(self.region)
        self.region.lines[0].addMarker('<|', 0.5)
        self.region.lines[1].addMarker('|>', 0.5)
        self.region.sigRegionChanged.connect(self.regionChanging)
        self.region.sigRegionChangeFinished.connect(self.regionChanged)

        self.axis = AxisItem('bottom', linkView=self.vb, maxTickLength=-10, parent=self)
        self.layout.addItem(self.axis, 1, 0)
        self.layout.addItem(self.vb, 0, 0)
        self.range = None
        self.vb.sigRangeChanged.connect(self.viewRangeChanged)

        self.plot = PlotCurveItem(pen=(200, 200, 200, 100))
        # self.plot.rotate(90)
        self.vb.addItem(self.plot)

        self.fillHistogram(fillHistogram)
        self._showRegions()

        self.autoHistogramRange()

        if image is not None:
            self.setImageItem(image)

    def fillHistogram(self, fill=True, level=0.0, color=(100, 100, 200)):
        if fill:
            self.plot.setFillLevel(level)
            self.plot.setBrush(color)
        else:
            self.plot.setFillLevel(None)


    def paint(self, p, *args):
        rgn = self.getLevels()
        self.vb.mapFromViewToItem(self, Point(self.vb.viewRect().center().x(), rgn[0]))
        self.vb.mapFromViewToItem(self, Point(self.vb.viewRect().center().x(), rgn[1]))


    def setHistogramRange(self, mn, mx, padding=0.1):
        """Set the Y range on the histogram plot. This disables auto-scaling."""
        self.vb.enableAutoRange(self.vb.XAxis, False)
        self.vb.setYRange(mn, mx, padding)

    def autoHistogramRange(self):
        """Enable auto-scaling on the histogram plot."""
        self.vb.enableAutoRange(self.vb.XYAxes)

    def setImageItem(self, img):
        """Set an ImageItem to have its levels and LUT automatically controlled
        by this HistogramLUTItem.
        """
        self.imageItem = weakref.ref(img)
        img.sigImageChanged.connect(self.imageChanged)
        self.regionChanged()
        self.imageChanged(autoLevel=True)

    def viewRangeChanged(self):
        self.update()

    def regionChanged(self):
        if self.imageItem() is not None:
            self.imageItem().setLevels(self.getLevels())
        self.sigLevelChangeFinished.emit(self)

    def regionChanging(self):
        if self.imageItem() is not None:
            self.imageItem().setLevels(self.getLevels())
        self.sigLevelsChanged.emit(self)
        self.update()

    def imageChanged(self, autoLevel=False):
        if self.imageItem() is None:
            return

        self.plot.setVisible(True)
        # plot one histogram for all image data
        h = self.imageItem().getHistogram()
        if h[0] is None:
            return
        self.plot.setData(*h)
        if autoLevel:
            mn = h[0][0]
            mx = h[0][-1]
            self.region.setRegion([mn, mx])
        else:
            mn, mx = self.imageItem().levels
            self.region.setRegion([mn, mx])

    def getLevels(self):
        """
        Return the min and max levels.
        """
        return self.region.getRegion()

    def setLevels(self, min=None, max=None):
        """
        Set the min/max (bright and dark) levels.
        """
        assert None not in (min, max)
        self.region.setRegion((min, max))

    def _showRegions(self):
        self.region.setVisible(True)

    def saveState(self):
        return {
            'levels': self.getLevels(),
        }

    def restoreState(self, state):
        self.setLevels(*state['levels'])
Пример #13
0
    def __updateState(self):
        """
        Update the widget with the new source/sink node signal descriptions.
        """
        widget = QGraphicsWidget()
        widget.setLayout(QGraphicsGridLayout())

        # Space between left and right anchors
        widget.layout().setHorizontalSpacing(50)

        left_node = EditLinksNode(self,
                                  direction=Qt.LeftToRight,
                                  node=self.source)

        left_node.setSizePolicy(QSizePolicy.MinimumExpanding,
                                QSizePolicy.MinimumExpanding)

        right_node = EditLinksNode(self,
                                   direction=Qt.RightToLeft,
                                   node=self.sink)

        right_node.setSizePolicy(QSizePolicy.MinimumExpanding,
                                 QSizePolicy.MinimumExpanding)

        left_node.setMinimumWidth(150)
        right_node.setMinimumWidth(150)

        widget.layout().addItem(
            left_node,
            0,
            0,
        )
        widget.layout().addItem(
            right_node,
            0,
            1,
        )

        title_template = "<center><b>{0}<b></center>"

        left_title = GraphicsTextWidget(self)
        left_title.setHtml(title_template.format(escape(self.source.title)))
        left_title.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)

        right_title = GraphicsTextWidget(self)
        right_title.setHtml(title_template.format(escape(self.sink.title)))
        right_title.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)

        widget.layout().addItem(left_title,
                                1,
                                0,
                                alignment=Qt.AlignHCenter | Qt.AlignTop)
        widget.layout().addItem(right_title,
                                1,
                                1,
                                alignment=Qt.AlignHCenter | Qt.AlignTop)

        widget.setParentItem(self)

        max_w = max(
            left_node.sizeHint(Qt.PreferredSize).width(),
            right_node.sizeHint(Qt.PreferredSize).width())

        # fix same size
        left_node.setMinimumWidth(max_w)
        right_node.setMinimumWidth(max_w)
        left_title.setMinimumWidth(max_w)
        right_title.setMinimumWidth(max_w)

        self.layout().addItem(widget)
        self.layout().activate()

        self.sourceNodeWidget = left_node
        self.sinkNodeWidget = right_node
        self.sourceNodeTitle = left_title
        self.sinkNodeTitle = right_title
Пример #14
0
    def __init__(
        self,
        name,
        board_pos,
        price,
        rent,
        mortgage,
        players,
        color,
        group_name,
        number_in_group,
        house_price,
        parent,
    ):
        super().__init__(parent=parent)
        self.name = name
        self.board_pos = board_pos
        self.price = price
        self.rent = rent
        self.mortgage = mortgage
        self.color = color
        self.group_name = group_name
        self.number_in_group = number_in_group
        self.tokens = []
        self.owner = False
        self.house_price = house_price
        self.nb_houses = 0
        self.hotel = False

        self.layout = QGraphicsLinearLayout()
        self.token_layout = QGraphicsGridLayout()

        self.color_property = QGraphicsWidget()
        self.name_on_tile = QGraphicsWidget()
        self.info = QGraphicsWidget()

        self.layout.setOrientation(Qt.Vertical)

        property_name = QGraphicsTextItem(self.name, parent=self.name_on_tile)

        if name in parent.properties:
            if self.board_pos in core.PROPERTIES:
                money_info = QGraphicsTextItem(f"Price: {self.price}",
                                               parent=self.info)
                self.color_rect = self.color_tile(color)

            elif self.board_pos in core.SPECIAL_CASES:
                if name == "Start":
                    money_start = QGraphicsTextItem(
                        f"Free monay: {self.price}", parent=self.info)

                    for player, color in players.items():
                        token = Token.Token(player, color)
                        token.set_tile(self)
                        self.tokens.append(token)

                    self.display_game_pieces()

                elif name in ["Income Tax", "Super Tax"]:
                    money_tax = QGraphicsTextItem(f"Tax: -{self.price}",
                                                  parent=self.info)

        self.token_layout.setColumnMaximumWidth(0, 22)
        self.token_layout.setColumnMaximumWidth(1, 22)
        self.token_layout.setColumnMaximumWidth(2, 22)
        self.token_layout.setSpacing(1)

        self.layout.addItem(self.color_property)
        self.layout.addItem(self.name_on_tile)
        self.layout.addItem(self.info)
        self.layout.addItem(self.token_layout)
        self.setLayout(self.layout)
        self.setContentsMargins(0, 0, 100, 0)
Пример #15
0
class Tile(QGraphicsWidget):
    """ Tile class """
    def __init__(
        self,
        name,
        board_pos,
        price,
        rent,
        mortgage,
        players,
        color,
        group_name,
        number_in_group,
        house_price,
        parent,
    ):
        super().__init__(parent=parent)
        self.name = name
        self.board_pos = board_pos
        self.price = price
        self.rent = rent
        self.mortgage = mortgage
        self.color = color
        self.group_name = group_name
        self.number_in_group = number_in_group
        self.tokens = []
        self.owner = False
        self.house_price = house_price
        self.nb_houses = 0
        self.hotel = False

        self.layout = QGraphicsLinearLayout()
        self.token_layout = QGraphicsGridLayout()

        self.color_property = QGraphicsWidget()
        self.name_on_tile = QGraphicsWidget()
        self.info = QGraphicsWidget()

        self.layout.setOrientation(Qt.Vertical)

        property_name = QGraphicsTextItem(self.name, parent=self.name_on_tile)

        if name in parent.properties:
            if self.board_pos in core.PROPERTIES:
                money_info = QGraphicsTextItem(f"Price: {self.price}",
                                               parent=self.info)
                self.color_rect = self.color_tile(color)

            elif self.board_pos in core.SPECIAL_CASES:
                if name == "Start":
                    money_start = QGraphicsTextItem(
                        f"Free monay: {self.price}", parent=self.info)

                    for player, color in players.items():
                        token = Token.Token(player, color)
                        token.set_tile(self)
                        self.tokens.append(token)

                    self.display_game_pieces()

                elif name in ["Income Tax", "Super Tax"]:
                    money_tax = QGraphicsTextItem(f"Tax: -{self.price}",
                                                  parent=self.info)

        self.token_layout.setColumnMaximumWidth(0, 22)
        self.token_layout.setColumnMaximumWidth(1, 22)
        self.token_layout.setColumnMaximumWidth(2, 22)
        self.token_layout.setSpacing(1)

        self.layout.addItem(self.color_property)
        self.layout.addItem(self.name_on_tile)
        self.layout.addItem(self.info)
        self.layout.addItem(self.token_layout)
        self.setLayout(self.layout)
        self.setContentsMargins(0, 0, 100, 0)

    def is_owned(self):
        if self.owner:
            return True
        else:
            return False

    def set_owner(self, player):
        self.owner = player

    def get_owner(self):
        return self.owner

    def remove_owner(self):
        self.owner = False

    def add_token(self, token):
        self.tokens.append(token)

    def remove_token(self, token):
        self.tokens.remove(token)

    def remove_token_layout(self, token):
        self.token_layout.removeItem(token)

    def add_houses(self, number):
        self.nb_houses += number
        self.display_houses()

    def add_hotel(self):
        self.nb_houses = 0
        self.hotel = True
        self.display_hotel()

    def get_name(self):
        return self.name

    def get_board_pos(self):
        return self.board_pos

    def get_token(self, player):
        for token in self.tokens:
            if player == token.get_player():
                return token

        return

    def get_all_tokens(self):
        return self.tokens

    def get_price(self):
        return self.price

    def get_rent(self):
        if self.hotel:
            return self.rent * self.parent().hotel_multiplier
        elif self.nb_houses:
            return self.rent * self.parent().house2mutliplier[self.nb_houses]
        else:
            return self.rent

    def get_mortgage(self):
        return self.mortgage

    def get_color(self):
        return self.color

    def get_group(self):
        return self.group_name

    def get_nb_houses(self):
        return self.nb_houses

    def get_house_price(self):
        return self.house_price

    def get_number_in_group(self):
        return self.number_in_group

    def has_tokens(self):
        if self.tokens != []:
            return True
        else:
            return False

    def display_game_pieces(self):
        """ Display the tokens on the tile according to their number
        
        i.e. if there's 4, i want a 2x2 grid
             if there's 5 or more, i want a 3xn grid
        """

        if len(self.tokens) >= 4:
            sub_layout = True
            sub_pos = 0
        else:
            sub_layout = False

        for i, token in enumerate(self.tokens):
            if (len(self.tokens) == 4 and i >= 2) or (len(self.tokens) >= 5
                                                      and i >= 3):
                if sub_layout:
                    self.token_layout.addItem(token, 1, sub_pos)
                    sub_pos += 1
            else:
                self.token_layout.addItem(token, 0, i)

    def display_houses(self):
        for i in range(self.nb_houses):
            width, height = self.color_rect.boundingRect().getRect()[2:]
            set_color = QColor()
            set_color.setNamedColor("#00FF00")
            house = QGraphicsRectItem(width / 4 * i + 5, height / 4,
                                      width / 4 - 10, height / 2)
            house.setParentItem(self.color_rect)
            house.setBrush(QBrush(set_color, style=Qt.Dense1Pattern))

    def display_hotel(self):
        if self.hotel:
            width, height = self.color_rect.boundingRect().getRect()[2:]
            houses = self.color_rect.childItems()

            for house in houses:
                house.setParentItem(None)

            rect_color = QColor()
            rect_color.setNamedColor("#FF0000")
            pen_color = QColor()
            pen_color.setNamedColor("#00A500")
            pen = QPen()
            pen.setBrush(QBrush(pen_color))
            pen.setWidth(2)

            hotel = QGraphicsRectItem(width / 4, height / 4, width / 2,
                                      height / 2)
            hotel.setParentItem(self.color_rect)
            hotel.setBrush(QBrush(rect_color, style=Qt.Dense1Pattern))
            hotel.setPen(pen)

    def paint(self, painter, option, widget):
        painter.drawRects(self.boundingRect())

    def color_tile(self, color):
        set_color = QColor()
        set_color.setNamedColor(color)
        color_rect = QGraphicsRectItem(0,
                                       0,
                                       150,
                                       25,
                                       parent=self.color_property)
        color_rect.setBrush(QBrush(set_color, style=Qt.SolidPattern))
        return color_rect