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

时间:2017-10-17 13:28:46

标签: python pyqt pyqtgraph

我在pyqtgraph github repo中找到了this示例。

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

  • 当用户点击某个节点时,他/她将获得该文本的' -info 那个节点。
  • 单击节点时该节点的颜色,以及 其所有邻居(边和节点)将改变(例如变为黄色)
  • 允许多项选择

代码:

# -*- 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_()

单击某个节点时,上面的代码返回以下信息:

<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]

编辑II

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

1 个答案:

答案 0 :(得分:2)

问题是您的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

修复后,你可以得到这样点击的点:

enter image description here

希望这对你有所帮助。