将 GraphicsObject 添加到两个 ViewBoxes 或 QGraphicsViews
Adding GraphicsObject to two ViewBoxes or QGraphicsViews
最终我希望 pyqtgraph 在多个 ViewBox 中同时显示单个 GraphicsObject,共享一个场景。
同时我想在单个 ViewBox 中仅包含一些其他 GraphicsObjects。
像这样:
vb0 = ViewBox()
vb1 = ViewBox()
# shown only in first ViewBox vb0
local_item = GraphicsObject()
# shown in all ViewBoxes
global_item = GraphicsObject()
vb0.addItem(local_item)
assert vb0.scene() is vb1.scene()
# the magic function i am looking for
vb0.scene().addItemGlobally(global_item)
我非常天真地查看了 ViewBox 源代码并重现了 addItem() 的步骤,如下所示:
import pyqtgraph as pg
from pyqtgraph.Qt import QtCore as qc, QtGui as qg, QtWidgets as qw
class Polygon(pg.GraphicsObject):
"""Just a Triangle..."""
app = qw.QApplication([])
viewer = pg.GraphicsWindow()
vb0 = viewer.addViewBox(0, 0)
vb1 = viewer.addViewBox(0, 1)
viewer.show()
poly_yellow = Polygon((125, 125, 0, 255))
scene = vb0.scene()
added_items = vb1.addedItems = vb0.addedItems
child_group = vb1.childGroup = vb0.childGroup
child_group.setParent(scene)
child_group.itemsChangedListeners.append(vb1)
# here reproducing steps found in addItem()
if scene is not poly_yellow.scene():
scene.addItem(poly_yellow)
poly_yellow.setParentItem(child_group)
added_items.append(poly_yellow)
vb0.updateAutoRange()
# vb1.updateAutoRange()
# checking if ViewBoxes share relevant attributes
assert vb0.scene() is vb1.scene()
assert vb0.scene() is poly_yellow.scene()
assert vb0.addedItems is vb1.addedItems
assert vb0.childGroup is vb1.childGroup
app.exec_()
运行 这给了我两个 ViewBox,但只有 vb0 显示了三角形。此外,这种方法只会给我全局项目。有没有办法在不完全重新实现 ViewBoxes 的情况下获得类似 local/global 的东西?
编辑: 我认为用 pyqtgraph ViewBoxes 不可能实现我想要的。全局项目的转换必须在绘画之前发生。
我发现使用 ViewBox 并不容易。但是,我们可以使用 pyqtgraphs GraphicsView,实现 ViewBox class 中的许多功能。
我现在的做法是根据需要生成尽可能多的GraphicsView,然后通过GraphicsView.setScene()
将它们全部设置到一个场景中
场景包含 'global' 个项目,显示在每个视图中。使用 GraphicsView.drawBackground() 函数绘制特定于视图的本地项目。
我没有对其进行太多测试,但它似乎工作得很好,对于这种情况,场景中添加了数千个项目,但只有少数项目被绘制到背景中。
最终我希望 pyqtgraph 在多个 ViewBox 中同时显示单个 GraphicsObject,共享一个场景。 同时我想在单个 ViewBox 中仅包含一些其他 GraphicsObjects。
像这样:
vb0 = ViewBox()
vb1 = ViewBox()
# shown only in first ViewBox vb0
local_item = GraphicsObject()
# shown in all ViewBoxes
global_item = GraphicsObject()
vb0.addItem(local_item)
assert vb0.scene() is vb1.scene()
# the magic function i am looking for
vb0.scene().addItemGlobally(global_item)
我非常天真地查看了 ViewBox 源代码并重现了 addItem() 的步骤,如下所示:
import pyqtgraph as pg
from pyqtgraph.Qt import QtCore as qc, QtGui as qg, QtWidgets as qw
class Polygon(pg.GraphicsObject):
"""Just a Triangle..."""
app = qw.QApplication([])
viewer = pg.GraphicsWindow()
vb0 = viewer.addViewBox(0, 0)
vb1 = viewer.addViewBox(0, 1)
viewer.show()
poly_yellow = Polygon((125, 125, 0, 255))
scene = vb0.scene()
added_items = vb1.addedItems = vb0.addedItems
child_group = vb1.childGroup = vb0.childGroup
child_group.setParent(scene)
child_group.itemsChangedListeners.append(vb1)
# here reproducing steps found in addItem()
if scene is not poly_yellow.scene():
scene.addItem(poly_yellow)
poly_yellow.setParentItem(child_group)
added_items.append(poly_yellow)
vb0.updateAutoRange()
# vb1.updateAutoRange()
# checking if ViewBoxes share relevant attributes
assert vb0.scene() is vb1.scene()
assert vb0.scene() is poly_yellow.scene()
assert vb0.addedItems is vb1.addedItems
assert vb0.childGroup is vb1.childGroup
app.exec_()
运行 这给了我两个 ViewBox,但只有 vb0 显示了三角形。此外,这种方法只会给我全局项目。有没有办法在不完全重新实现 ViewBoxes 的情况下获得类似 local/global 的东西?
编辑: 我认为用 pyqtgraph ViewBoxes 不可能实现我想要的。全局项目的转换必须在绘画之前发生。
我发现使用 ViewBox 并不容易。但是,我们可以使用 pyqtgraphs GraphicsView,实现 ViewBox class 中的许多功能。
我现在的做法是根据需要生成尽可能多的GraphicsView,然后通过GraphicsView.setScene()
将它们全部设置到一个场景中场景包含 'global' 个项目,显示在每个视图中。使用 GraphicsView.drawBackground() 函数绘制特定于视图的本地项目。
我没有对其进行太多测试,但它似乎工作得很好,对于这种情况,场景中添加了数千个项目,但只有少数项目被绘制到背景中。