我尝试使用PyQt5将两个椭圆与一条线连接起来。要做到这一点,请稍加修改github的类。我使用的不是PySide,而是PyQt5。代码摘自这里:https://github.com/PySide/Examples/blob/master/examples/graphicsview/diagramscene/diagramscene.py
class Arrow(QGraphicsLineItem):
def __init__(self, start_item, end_item, parent=None, scene=None):
super(Arrow, self).__init__(parent, scene)
self.arrowHead = QPolygonF()
self.my_start_item = start_item
self.my_end_item = end_item
self.setFlag(QGraphicsItem.ItemIsSelectable, True)
self.my_color = QtCore.Qt.black
self.setPen(QPen(self.my_color, 2, QtCore.Qt.SolidLine,
QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin))
def set_color(self, color):
self.my_color = color
def start_item(self):
return self.my_start_item
def end_item(self):
return self.my_end_item
def boundingRect(self):
extra = (self.pen().width() + 20) / 2.0
p1 = self.line().p1()
p2 = self.line().p2()
return QtCore.QRectF(p1, QtCore.QSizeF(p2.x() - p1.x(), p2.y() - p1.y())).normalized().adjusted(-extra, -extra, extra, extra)
def shape(self):
path = super(Arrow, self).shape()
path.addPolygon(self.arrowHead)
return path
def update_position(self):
line = QtCore.QLineF(self.mapFromItem(self.my_start_item, 0, 0), self.mapFromItem(self.my_end_item, 0, 0))
self.setLine(line)
def paint(self, painter, option, widget=None):
if self.my_start_item.collidesWithItem(self.my_end_item):
return
my_start_item = self.my_start_item
my_end_item = self.my_end_item
my_color = self.my_color
my_pen = self.pen()
my_pen.setColor(self.my_color)
arrow_size = 20.0
painter.setPen(my_pen)
painter.setBrush(self.my_color)
center_line = QtCore.QLineF(my_start_item.pos(), my_end_item.pos())
end_polygon = my_end_item.polygon()
p1 = end_polygon.at(0) + my_end_item.pos()
intersect_point = QtCore.QPointF()
for i in end_polygon:
p2 = i + my_end_item.pos()
poly_line = QtCore.QLineF(p1, p2)
intersect_type, intersect_point = poly_line.intersect(center_line)
if intersect_type == QtCore.QLineF.BoundedIntersection:
break
p1 = p2
self.setLine(QtCore.QLineF(intersect_point, my_start_item.pos()))
line = self.line()
angle = math.acos(line.dx() / line.length())
if line.dy() >= 0:
angle = (math.pi * 2.0) - angle
arrow_p1 = line.p1() + QtCore.QPointF(math.sin(angle + math.pi / 3.0) * arrow_size,
math.cos(angle + math.pi / 3) * arrow_size)
arrow_p2 = line.p1() + QtCore.QPointF(math.sin(angle + math.pi - math.pi / 3.0) * arrow_size,
math.cos(angle + math.pi - math.pi / 3.0) * arrow_size)
self.arrowHead.clear()
for point in [line.p1(), arrow_p1, arrow_p2]:
self.arrowHead.append(point)
painter.drawLine(line)
painter.drawPolygon(self.arrowHead)
if self.isSelected():
painter.setPen(QPen(my_color, 1, QtCore.Qt.DashLine))
my_line = QtCore.QLineF(line)
my_line.translate(0, 4.0)
painter.drawLine(my_line)
my_line.translate(0, -8.0)
painter.drawLine(my_line)
创建箭头
arrow = Arrow(start, end, scene=scene)
scene.addItem(arrow)
arrow.update_position()
运行代码时发生的错误。
发布于 2017-12-21 17:25:53
PyQt5是由河岸计算公司创建的Qt5的包装器,PySide是由Qt的同一创建者创建的Qt4的包装器。除了Qt4和Qt5有许多不同,因此这些库根本不兼容,例如,在您的示例中,PySide项可以将场景作为参数传递,但对于PyQt4或PyQt5,则没有必要使用该参数:
PySide:
类PySide.QtGui.QGraphicsLineItem([parent=None,scene=None]) 类PySide.QtGui.QGraphicsLineItem(行[,parent=None,scene=None]) PySide.QtGui.QGraphicsLineItem类(x1,y1,x2,y2[,parent=None,scene=None])
PyQt5:
QGraphicsLineItem(父母: QGraphicsItem =无) QGraphicsLineItem(QLineF,父母: QGraphicsItem = None) QGraphicsLineItem(浮动,父: QGraphicsItem =无)
除此之外,还有类Signal()
和pyqtSignal
,很明显,从Qt4到Qt5的步骤是将一些属于QtGui的类分离为QtWidgets。
在您的情况下,解决方案是消除场景参数,因为它会更改:
class Arrow(QGraphicsLineItem):
def __init__(self, start_item, end_item, parent=None, scene=None):
super(Arrow, self).__init__(parent, scene)
至:
class Arrow(QGraphicsLineItem):
def __init__(self, start_item, end_item, parent=None):
super(Arrow, self).__init__(parent)
我已经将该项目翻译为PyQt5,您可以在下面的链接中检查它。
https://stackoverflow.com/questions/47928724
复制相似问题