超级方法出错

问题描述 投票:0回答:1

我尝试使用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()

代码运行时发生错误

enter image description here

python python-3.x pyqt pycharm pyqt5
1个回答
1
投票

PyQt5是由riverbankcomputing公司创建的Qt5的包装器,而PySide是由当时Qt的创建者创建的Qt4的包装器。除了Qt4和Qt5有很多不同之处,所以这些库根本不兼容,例如在你的情况下PySide项你可以将场景作为参数传递,但在PyQt4或PyQt5的情况下,这个参数是不必要的:

PySide:

class PySide.QtGui.QGraphicsLineItem([parent = None [,scene = None]])

class PySide.QtGui.QGraphicsLineItem(line [,parent = None [,scene = None]])

class PySide.QtGui.QGraphicsLineItem(x1,y1,x2,y2 [,parent = None [,scene = None]])

PyQt5:

QGraphicsLineItem(parent:QGraphicsItem = None)

QGraphicsLineItem(QLineF,parent:QGraphicsItem = None)

QGraphicsLineItem(float,float,float,float,parent:QGraphicsItem = None)

除了这个差别是类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,您可以在以下link中查看它。

© www.soinside.com 2019 - 2024. All rights reserved.