最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

python - Setting BackgroundBorder of pyqtgraph.Scalebar - Stack Overflow

programmeradmin0浏览0评论

I'm trying to change the background/border color of a pyqtgraph.ScaleBar, because I would like it to have a black border with a white, non-transparent background. The main aim is to achieve a scalebar that, when positioned above some data, is fully visible, instead of overlapping with data (in an pyqtgraph.ImageItem, for instance).

Here is quick minimal example to create a ScaleBar in the pyqtgraph framework:

import pyqtgraph as pg

app = pg.mkQApp()

plot = pg.PlotWidget()

scale_bar = pg.ScaleBar(size=1, width=5, offset=(-10, -20))
scale_bar.setParentItem(plot.getPlotItem().getViewBox())

plot.show()

app.exec()

and here is the documentation:

.html#pyqtgraph.ScaleBar

ScaleBar is supposed to inherit from pyqtgraph.GraphicsObject, which itself inherits from QGraphicsObject and pyqtgraph.GraphicsItem (which is an object).

I tried targetting the ViewBox and the ViewWidget of the scale_bar and setting their respective colors, but that didn't change anything about the appearance of the window that is created when executing the script.

Subclassing ScaleBar to reimplement the paint method also doesn't change the color.

I'm trying to change the background/border color of a pyqtgraph.ScaleBar, because I would like it to have a black border with a white, non-transparent background. The main aim is to achieve a scalebar that, when positioned above some data, is fully visible, instead of overlapping with data (in an pyqtgraph.ImageItem, for instance).

Here is quick minimal example to create a ScaleBar in the pyqtgraph framework:

import pyqtgraph as pg

app = pg.mkQApp()

plot = pg.PlotWidget()

scale_bar = pg.ScaleBar(size=1, width=5, offset=(-10, -20))
scale_bar.setParentItem(plot.getPlotItem().getViewBox())

plot.show()

app.exec()

and here is the documentation:

https://pyqtgraph.readthedocs.io/en/latest/api_reference/graphicsItems/scalebar.html#pyqtgraph.ScaleBar

ScaleBar is supposed to inherit from pyqtgraph.GraphicsObject, which itself inherits from QGraphicsObject and pyqtgraph.GraphicsItem (which is an object).

I tried targetting the ViewBox and the ViewWidget of the scale_bar and setting their respective colors, but that didn't change anything about the appearance of the window that is created when executing the script.

Subclassing ScaleBar to reimplement the paint method also doesn't change the color.

Share edited Nov 20, 2024 at 0:37 eyllanesc 244k19 gold badges200 silver badges279 bronze badges asked Nov 19, 2024 at 18:22 DavidGDavidG 11 bronze badge 1
  • The documentation you link shows that ScaleBar accepts the arguments pen (for the border) and brush (the fill color), which are exactly for what you need. See the related documentation and the Qt docs about QPen, QBrush, QColor. – musicamante Commented Nov 19, 2024 at 22:36
Add a comment  | 

1 Answer 1

Reset to default 0

I realize now that the initial query was not as clear as I thought, but I have found a solution myself (that I should have probably thought of before).

What I wanted to achieve was a ScaleBar that does not superimpose the data that is displayed in a plot (i.e., the ViewBox the ScaleBar is added to), but instead have a separated area.

Using pen and brush as arguments for the ScaleBar initialization "only" changes the bar, like for the following:

Instead I wanted to frame the ScaleBar, so it sits above a non-transparent, white background with a black border:

For future reference, here is a minimal code example for a framed pyqtgraph.ScaleBar using a slightly adapted ScaleBar class (basically just removing the text item):

from PySide6.QtWidgets import QApplication

import pyqtgraph as pg
pg.setConfigOption('background', 'w')
pg.setConfigOption('foreground', 'k')

class BackgroundFill(pg.GraphicsWidgetAnchor, pg.GraphicsObject):
    def __init__(self, size, width=5, brush='white', pen=None, suffix='m', offset=None):
        pg.GraphicsObject.__init__(self)
        pg.GraphicsWidgetAnchor.__init__(self)
        self.setFlag(self.GraphicsItemFlag.ItemHasNoContents)
        self.setAcceptedMouseButtons(pg.Qt.QtCore.Qt.MouseButton.NoButton)
        
        self.brush = pg.functions.mkBrush(brush)
        self.pen = pg.functions.mkPen(pen)
        self._width = width
        self.size = size
        if offset is None:
            offset = (0,0)
        self.offset = offset
        
        self.bar = pg.Qt.QtWidgets.QGraphicsRectItem()
        self.bar.setPen(self.pen)
        self.bar.setBrush(self.brush)
        self.bar.setParentItem(self)
        
    def changeParent(self):
        view = self.parentItem()
        if view is None:
            return
        view.sigRangeChanged.connect(self.updateBar)
        self.updateBar()
        
    def updateBar(self):
        view = self.parentItem()
        if view is None:
            return
        p1 = view.mapFromViewToItem(self, pg.Qt.QtCore.QPointF(0,0))
        p2 = view.mapFromViewToItem(self, pg.Qt.QtCore.QPointF(self.size,0))
        w = (p2-p1).x()
        self.bar.setRect(pg.Qt.QtCore.QRectF(-w-10, -25, w+20, self._width+35))

    def boundingRect(self):
        return pg.Qt.QtCore.QRectF()

    def setParentItem(self, p):
        ret = pg.GraphicsObject.setParentItem(self, p)
        if self.offset is not None:
            offset = pg.Point(self.offset)
            anchorx = 1 if offset[0] <= 0 else 0
            anchory = 1 if offset[1] <= 0 else 0
            anchor = (anchorx, anchory)
            self.anchor(itemPos=anchor, parentPos=anchor, offset=offset)
        return ret

app = QApplication([])

plot_widget = pg.PlotWidget()
plot_widget.show()

plot_widget.plot([1, 2, 3, 4], [10, 20, 10, 40])

background = BackgroundFill(size=1, width=10, pen=pg.mkPen('k'))
background.setParentItem(plot_widget.getViewBox())
background.anchor((1, 1), (1, 1), offset=(-20, -50))

scalebar = pg.ScaleBar(size=1, pen=pg.mkPen('k'), brush=pg.mkBrush('k'))
scalebar.text.setColor('black')
scalebar.setParentItem(plot_widget.getViewBox())
scalebar.anchor((1, 1), (1, 1), offset=(-20, -50))  # Bottom-right corner

app.exec()
发布评论

评论列表(0)

  1. 暂无评论