pyqtgraph 获取节点文本并在 MouseClick 上更改颜色

pyqtgraph get text of node and change color on MouseClick

我从 pyqtgraph github 存储库中找到了 this 示例。

我想用 pyqtgraph 创建一个具有以下功能的交互式(网络)图:

代码:

# -*- coding: utf-8 -*-
"""
Simple example of subclassing GraphItem.
"""

import initExample ## Add path to library (just for examples; you do not need this)

import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
import numpy as np

# Enable antialiasing for prettier plots
pg.setConfigOptions(antialias=True)

w = pg.GraphicsWindow()
w.setWindowTitle('pyqtgraph example: CustomGraphItem')
v = w.addViewBox()
v.setAspectLocked()

class Graph(pg.GraphItem):
    def __init__(self):
        self.dragPoint = None
        self.dragOffset = None
        self.textItems = []
        pg.GraphItem.__init__(self)
        self.scatter.sigClicked.connect(self.clicked)

    def setData(self, **kwds):
        self.text = kwds.pop('text', [])
        self.data = kwds
        if 'pos' in self.data:
            npts = self.data['pos'].shape[0]
            self.data['data'] = np.empty(npts, dtype=[('index', int)])
            self.data['data']['index'] = np.arange(npts)
        self.setTexts(self.text)
        self.updateGraph()

    def setTexts(self, text):
        for i in self.textItems:
            i.scene().removeItem(i)
        self.textItems = []
        for t in text:
            item = pg.TextItem(t)
            self.textItems.append(item)
            item.setParentItem(self)

    def updateGraph(self):
        pg.GraphItem.setData(self, **self.data)
        for i,item in enumerate(self.textItems):
            item.setPos(*self.data['pos'][i])


    def mouseDragEvent(self, ev):
        if ev.button() != QtCore.Qt.LeftButton:
            ev.ignore()
            return

        if ev.isStart():
            # We are already one step into the drag.
            # Find the point(s) at the mouse cursor when the button was first 
            # pressed:
            pos = ev.buttonDownPos()
            pts = self.scatter.pointsAt(pos)
            if len(pts) == 0:
                ev.ignore()
                return
            self.dragPoint = pts[0]
            ind = pts[0].data()[0]
            self.dragOffset = self.data['pos'][ind] - pos
        elif ev.isFinish():
            self.dragPoint = None
            return
        else:
            if self.dragPoint is None:
                ev.ignore()
                return

        ind = self.dragPoint.data()[0]
        self.data['pos'][ind] = ev.pos() + self.dragOffset
        self.updateGraph()
        ev.accept()

    def clicked(self, pts):
        print("clicked: %s" % pts)


g = Graph()
v.addItem(g)

## Define positions of nodes
pos = np.array([
    [0,0],
    [10,0],
    [0,10],
    [10,10],
    [5,5],
    [15,5]
    ], dtype=float)

## Define the set of connections in the graph
adj = np.array([
    [0,1],
    [1,3],
    [3,2],
    [2,0],
    [1,5],
    [3,5],
    ])

## Define the symbol to use for each node (this is optional)
symbols = ['o','o','o','o','t','+']

## Define the line style for each connection (this is optional)
lines = np.array([
    (255,0,0,255,1),
    (255,0,255,255,2),
    (255,0,255,255,3),
    (255,255,0,255,2),
    (255,0,0,255,1),
    (255,255,255,255,4),
    ], dtype=[('red',np.ubyte),('green',np.ubyte),('blue',np.ubyte),('alpha',np.ubyte),('width',float)])

## Define text to show next to each symbol
texts = ["Point %d" % i for i in range(6)]

## Update the graph
g.setData(pos=pos, adj=adj, pen=lines, size=1, symbol=symbols, pxMode=False, text=texts)




## Start Qt event loop unless running in interactive mode or using pyside.
if __name__ == '__main__':
    import sys
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()

上面的代码returns以下信息,当一个节点被点击时:

<pyqtgraph.graphicsItems.ScatterPlotItem.ScatterPlotItem object at 0x7f1e51657558>

其实就是整个图项(因为点击信号是对整个图调用的)

现在:如何在每个节点上调用 MouseClicking 功能,获取该节点的文本并在单击事件时更改其(及其相邻节点)的颜色?

Another example 显示在另一个图中更改单击曲线的颜色。在这里,点击信号在每条曲线上被调用。我试图以此为起点,在下面第一个提到的代码示例中实现类似的东西,但老实说,我什至不知道如何到达 pyqtgraph 图形对象中的单个节点(因为 [我可能在这里错了], 节点仅通过它们的位置来定义)。

一如既往,我们将不胜感激。

编辑:感谢kesumu的回答,我能够像这样获取点击节点的文本内容:

def clicked(self, scatter, pts):
    data_list = scatter.data.tolist()
    mypoint = [tup for tup in data_list if pts[0] in tup][0]
    mypoint_index = data_list.index(mypoint)
    mypoint_text = self.text[mypoint_index]

编辑二:

可以找到同一问题的更详细示例 here

问题是你的clicked函数有误。

应该是这样的:

def clicked(self, scatter, pts):
    print(scatter)
    print(pts[0])
    print("clicked: %s" % pts)

因为 sigClicked 有两个参数:self,points。这是它的定义:

sigClicked = QtCore.Signal(object, object)  ## self, points

修复后可以得到点击点数:

希望对您有所帮助。