我有一个使用PyQtGraph渲染的圆圈。在圆圈内部渲染另一个图形。该图由通常的节点和边组成。目前,我可以点击节点然后获取它们的坐标并进行一些计算。但与此同时,如果我点击圆圈的空心表面上的任何地方,它不会调用任何事件。 我的要求是在圆圈内的任何位置获取点击点。您可以在下面找到用于渲染单位半径圆的代码(将圆心视为原点)和自定义类。
import pyqtgraph as pg
import numpy as np
import math
from pyqtgraph.Qt import QtCore, QtGui
class Graph(pg.GraphItem):
def __init__(self):
self.dragPoint = None
self.dragOffset = None
self.textItems = []
pg.GraphItem.__init__(self)
self.scatter.sigClicked.connect(self.onclick)
self.data = lambda x: None
self.text = lambda x: None
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()
# Once a node on the graph is clicked, the clicked node should become the center of the graph
def onclick(plot, points):
x = 0
y = 0
x, y = points.ptsClicked[0]._data[0], points.ptsClicked[0]._data[1] # position of the clicked point
print('Clicked point is (' + str(x) + ', ' + str(y) + ')')
# Construct a unit radius circle for the graph
def plot_poincare_disc(graph_item_1, graph_item_2):
# Two semicircles have been produced first and then joined later
# As PyQtGraph needs a position matrix along with an adjacency matrix, hence pos and adj arrays
# Semi-Circle 1
pos1 = []
adj1 = []
length = 0
# calculating y coordinates for 1000 evenly spaced points in (-1,1)
for x in np.linspace(-1, 1, 1000):
y = math.sqrt(1 - x ** 2)
pos1.append([x, y])
if len(pos1) > 1:
adj1.append([length - 1, length])
length = length + 1
pos1 = np.array(pos1)
adj1 = np.array(adj1)
graph_item_1.setData(pos=pos1, adj=adj1, size=0.07)
# Semi-circle 2
pos2 = []
adj2 = []
length = 0
# calculating y coordinates for 1000 evenly spaced points in (1,-1)
for x in np.linspace(1, -1, 1000):
y = -math.sqrt(1 - x ** 2)
pos2.append([x, y])
if len(pos2) > 1:
adj2.append([length - 1, length])
length = length + 1
pos2 = np.array(pos2)
adj2 = np.array(adj2)
graph_item_2.setData(pos=pos2, adj=adj2, size=0.07)
if __name__ == '__main__':
position = [(-0.5,0), (0.5,0)]
adjacency = [(0,1)]
w = pg.GraphicsWindow()
w.setWindowTitle('Title of the window')
v = w.addViewBox()
v.setAspectLocked()
g = Graph()
v.addItem(g)
g.setData(pos=np.array(position), adj=np.array(adjacency), pxMode=False, size=0.1)
g2 = pg.GraphItem()
v.addItem(g2)
g3 = pg.GraphItem()
v.addItem(g3)
plot_poincare_disc(g2,g3)
import sys
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
QtGui.QGuiApplication.instance().exec_()
我知道,尽管在圆圈内部不包含任何散点,但这就是它不会调用任何事件的原因。是否有可能使内部空心可点击?
Edit1:代码由最小,完整且有意义的代码替换。
答案 0 :(得分:0)
不是绘制点并生成周长,更好的策略是创建一个绘制透明圆的类,使用if(count($galdata) > 0) {
}
方法创建一个指示点击位置的信号。继承必须是mousePressEvent
:
QGraphicsObject