如何在PyQt

时间:2019-05-14 17:24:45

标签: python python-3.x pyqt pyqt5 qgraphicsview

我想知道哪种最好的方法来绘制一条两端都带有端点的线,将来将其用于将线的末端移动到另一点?

我的想法是使用多个类,其中一个类负责点,另一类负责线,另一类负责拖动点。我能够得到要绘制的点,并能绘制到每个点的线,但是我无法使端点显示在那条线上。

这是正确的方法还是有更好的方法来完成我要实现的目标?谢谢您的宝贵时间和任何建议。

更新

我一直在尝试使用这些示例被标记为重复时给出的示例,但我认为最终目标并不相同。这些示例分别制作了线和节点。我一直在尝试使我的代码适应它们,但是我不确定如何将其更改为我想要的方式。这些示例虽然很棒,但它们并不是我要尝试做的。

我希望较小的正方形在线条的末端并在绘制线条时放置,而不是像示例中那样放在前面。在我的项目代码中,线连接的点将无法移动。

我想要的结果看起来像Example

Example 1 Example 2

代码

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import sys
from math import sqrt,cos,acos,asin,degrees,pi,hypot


class LogObject(QObject):
    hovered = pyqtSignal()
    notHovered = pyqtSignal()

def create_square():
    scale = 250
    path = QPainterPath()
    path.addRect(-0.076,-0.07,0.1520,0.1400)
    tr = QTransform()
    tr.scale(scale, scale)
    path = tr.map(path)
    return path

def create_circle():
    scale = 250
    path = QPainterPath()
    path.addEllipse(QPointF(0,0), 0.0750, 0.0750) # Using QPointF will center it
    tr = QTransform()
    tr.scale(scale, scale)
    path = tr.map(path)
    return path

def drawPath(x1,y1,x2,y2):
    scale = 250
    path = QPainterPath()
    path.moveTo(x1,y1)
    path.lineTo(x2,y2)
    return path

def create_drag_point_square():
    scale = 250
    path = QPainterPath()
    path.addRect(-0.0532,-0.049,0.1064,0.098)
    tr = QTransform()
    tr.scale(scale, scale)
    path = tr.map(path)
    return path

class DragPoint(QGraphicsPathItem):
    def __init__(self,x,y):
        super(DragPoint,self).__init__()
        self.x = x
        self.y = y
        self.name = ''
        self.setFlag(QGraphicsItem.ItemIsSelectable,True)
        self.setPath(create_drag_point_square())
        self.setAcceptHoverEvents(True)
        self.log = LogObject()
        pen = QPen(Qt.white)
        pen.setStyle(Qt.SolidLine)
        pen.setWidthF(6)
        self.setPen(pen)
        self.isSelected = False

    def itemChange(self, change, value):
        if change == self.ItemSelectedChange:
            color = QColor(Qt.green) if value else QColor(Qt.white)
            pen = self.pen()
            pen.setColor(color)
            self.setPen(pen)
        return QGraphicsItem.itemChange(self, change, value)

    def hoverEnterEvent(self, event):
        color = QColor("red")
        pen = self.pen()
        pen.setColor(color)
        self.setPen(pen)
        self.log.hovered.emit()
        QGraphicsItem.hoverMoveEvent(self, event)

    def hoverLeaveEvent(self, event):
        color = QColor(Qt.green) if self.isSelected else QColor(Qt.white)
        pen = self.pen()
        pen.setColor(color)
        self.setPen(pen)
        self.log.notHovered.emit()
        QGraphicsItem.hoverMoveEvent(self, event)

class PathLine(QGraphicsPathItem):
    def __init__(self,x1,y1,x2,y2,selectable=True):
        super(PathLine,self).__init__()
        self.x1 = x1
        self.y1 = y1
        self.x2 = x2
        self.y2 = y2
        self.name = ''
        self.setFlag(QGraphicsItem.ItemIsSelectable,selectable)
        self.setPath(drawPath(x1,y1,x2,y2))
        self.setAcceptHoverEvents(True)
        self.log = LogObject()
        pen = QPen(Qt.white)
        pen.setStyle(Qt.SolidLine)
        pen.setWidthF(3)
        self.setPen(pen)
        self.isSelected = False
        self.objectNameStart =''
        self.objectNameEnd = ''
        self.dpStart = DragPoint(x1,y1)
        self.dpEnd = DragPoint(x2,y2)

    def updateEndCords(self,x,y):
        self.x2 = x
        self.y2 = y
        self.setPath(drawPath(self.x1,self.y1,x,y))
        self.update()

    def itemChange(self, change, value):
        if change == self.ItemSelectedChange:
            color = QColor(Qt.green) if value else QColor(Qt.white)
            pen = self.pen()
            pen.setColor(color)
            self.setPen(pen)
        return QGraphicsItem.itemChange(self, change, value)

    def hoverEnterEvent(self, event):
        color = QColor("red")
        pen = self.pen()
        pen.setColor(color)
        self.setPen(pen)
        self.log.hovered.emit()
        QGraphicsItem.hoverMoveEvent(self, event)

    def hoverLeaveEvent(self, event):
        color = QColor(Qt.green) if self.isSelected else QColor(Qt.white)
        pen = self.pen()
        pen.setColor(color)
        self.setPen(pen)
        self.log.notHovered.emit()
        QGraphicsItem.hoverMoveEvent(self, event)


class Point(QGraphicsPathItem):
    def __init__(self, x, y, r, name):
        super(Point, self).__init__()
        self.setFlag(QGraphicsItem.ItemIsSelectable, True)
        self.name = name
        if self.name.split('__')[1] == '0':
            self.setPath(create_circle())
        else:
            self.setPath(create_square())
        self.setScale(1.5)
        self.x = x
        self.y = y
        self.r = r
        self.setRotation(180+self.r)
        self.setAcceptHoverEvents(True)
        self.log = LogObject()
        self.setPos(x, y)
        self.isSelected = False

        pen = QPen(Qt.white)
        pen.setStyle(Qt.SolidLine)
        pen.setWidthF(3)
        self.setPen(pen)

    def itemChange(self, change, value):
        if change == self.ItemSelectedChange:
            color = QColor(Qt.green) if value else QColor(Qt.white)
            pen = self.pen()
            pen.setColor(color)
            self.setPen(pen)
        return QGraphicsItem.itemChange(self, change, value)

    def hoverEnterEvent(self, event):
        color = QColor("red")
        pen = self.pen()
        pen.setColor(color)
        self.setPen(pen)
        self.log.hovered.emit()
        QGraphicsItem.hoverMoveEvent(self, event)

    def hoverLeaveEvent(self, event):
        color = QColor(Qt.green) if self.isSelected else QColor(Qt.white)
        pen = self.pen()
        pen.setColor(color)
        self.setPen(pen)
        self.log.notHovered.emit()
        QGraphicsItem.hoverMoveEvent(self, event)

    def mouseDoubleClickEvent(self,event):
        print(self.name)

class Viewer(QGraphicsView):
    photoClicked = pyqtSignal(QPoint)
    rectChanged = pyqtSignal(QRect)

    def __init__(self, parent):
        super(Viewer, self).__init__(parent)
        self.setMouseTracking(True)
        self.origin = QPoint()
        self.setRenderHints(QPainter.Antialiasing)

        self._zoom = 0
        self._empty = True
        self.setScene(QGraphicsScene(self))

        self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
        self.setResizeAnchor(QGraphicsView.AnchorUnderMouse)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setFrameShape(QFrame.NoFrame)
        self.area = float()
        self.setPoints()
        self.viewport().setCursor(Qt.ArrowCursor)
        QTimer.singleShot(0, self.reset_fit)
        self.selectedItems = []
        self.setBackgroundBrush(Qt.black)


    def setItems(self):
        self.data = {
            "x": [
                -2415594.9965,
                -2414943.8686,
                -2417160.6592,
            ],
            "y": [
                10453172.2426,
                10454269.7008,
                10454147.2672,
            ],
            "rotation":[
            0,
            313.9962,
            43.9962,
            ]
        }

        self.adjustedPoints = {}
        for i, (x, y,r) in enumerate(zip(self.data["x"], self.data["y"],self.data["rotation"])):
            p = Point(x, y,r, "Point__" + str(i))
            p.log.hovered.connect(self.hoverChange)
            p.log.notHovered.connect(self.notHoverChange)
            self.scene().addItem(p)
            self.adjustedPoints[i] = [x,y,"Point__" + str(i)]

        self.currentLine = PathLine(self.data['x'][0],self.data['y'][0],self.data['x'][1],self.data['y'][1])
        self.scene().addItem(self.currentLine)


    def setPoints(self):
        self.setItems()

    def hoverChange(self):
        self.viewport().setCursor(Qt.PointingHandCursor)

    def notHoverChange(self):
        self.viewport().setCursor(Qt.ArrowCursor)

    def reset_fit(self):
        r = self.scene().itemsBoundingRect()
        self.resetTransform()
        self.setSceneRect(r)
        self.fitInView(r, Qt.KeepAspectRatio)
        self._zoom = 0
        self.scale(1, -1)


class Window(QWidget):
    def __init__(self):
        super(Window, self).__init__()
        self.viewer = Viewer(self)
        VBlayout = QVBoxLayout(self)
        VBlayout.addWidget(self.viewer)


if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    window = Window()
    window.setGeometry(500, 300, 800, 600)
    window.show()
    sys.exit(app.exec_())

0 个答案:

没有答案