gpt4 book ai didi

python - 将端口添加到 QGraphicsPixmapItem 对象

转载 作者:行者123 更新时间:2023-12-01 00:59:50 25 4
gpt4 key购买 nike

img

我创建了这样的东西。我创建了一个 QGraphicsPixmapItem 对象,可以将其添加到 QGraphicsView 中。我想将端口添加到我创建的这些对象中。我想在这些端口和我创建的对象之间建立连接。我不知道该怎么做。你能帮我吗?

我的代码


class Part(QGraphicsPixmapItem):
def __init__(self, name):
super().__init__()
self.name = name
self.setFlags(self.ItemIsSelectable | self.ItemIsMovable | self.ItemIsFocusable)
self.label = QLabel("Deneme")
self.pixmap = QPixmap("image/" + name + ".png")
self.setPixmap(self.pixmap)

self.inputs = {}
self.outputs = {}

def keyPressEvent(self, event):
if (event.matches(QKeySequence.Delete)):
self.delete()

def contextMenuEvent(self, event):
menu = QMenu()
delete = menu.addAction('Delete')
delete.triggered.connect(self.delete)
menu.exec_(event.screenPos())

def showInfo(self,event):
pass

def delete(self):
# Delete all connection connected to the part
for input in self.inputs:
while len(self.inputs[input].connection) > 0:
self.inputs[input].connection[0].delete()
for output in self.outputs:
while len(self.outputs[output].connection) > 0:
self.outputs[output].connection[0].delete()
# Delete the part
self.scene().removeItem(self)



最佳答案

使用 QGraphicsPixmapItem 作为建立连接的基础是一个糟糕的选择,因为很难检测终端在哪里,相反,我建议使用 QGraphicsPathItem,它作为 QGraphicsLineItem 的子项,可能是连接节点。对于实现我基于my old answer .

from PyQt5 import QtCore, QtGui, QtWidgets


class Edge(QtWidgets.QGraphicsLineItem):
def __init__(self, source, dest, parent=None):
super().__init__(parent)
self.source = source
self.dest = dest
self.source.addEdge(self)
self.dest.addEdge(self)
self.setPen(QtGui.QPen(QtCore.Qt.red, 1.75))
self.adjust()

def adjust(self):
self.prepareGeometryChange()
self.setLine(QtCore.QLineF(self.dest.end(), self.source.end()))


class TerminalItem(QtWidgets.QGraphicsLineItem):
def __init__(self, line, parent=None):
super().__init__(line, parent)
self.setAcceptHoverEvents(True)
self.setPen(QtGui.QPen(QtGui.QColor(QtCore.Qt.transparent), 4))
self.edges = []

def addEdge(self, edge):
self.edges.append(edge)

def mousePressEvent(self, event):
event.accept()

def mouseMoveEvent(self, event):
event.accept()

def end(self):
return self.mapToScene(self.line().p1())

def hoverEnterEvent(self, event):
self.setPen(QtGui.QPen(QtGui.QColor(QtCore.Qt.red), 4))

def hoverLeaveEvent(self, event):
self.setPen(QtGui.QPen(QtGui.QColor(QtCore.Qt.transparent), 4))


class PortItem(QtWidgets.QGraphicsPathItem):
def __init__(self, parent=None):
super().__init__(parent)
self.end_ports = []
self.setFlags(
QtWidgets.QGraphicsItem.ItemIsMovable
| QtWidgets.QGraphicsItem.ItemSendsGeometryChanges
)
self.create_path()
self.create_end_ports()

def create_path(self):
raise NotImplementedError

def create_end_ports(self):
raise NotImplementedError

def itemChange(self, change, value):
if change == QtWidgets.QGraphicsItem.ItemPositionHasChanged:
for ports in self.end_ports:
for edge in ports.edges:
edge.adjust()
return super().itemChange(change, value)


class ANDPortItem(PortItem):
def create_path(self):
path = QtGui.QPainterPath()
s = 20
path.moveTo(0, 1)
path.lineTo(2, 1)
path.lineTo(2, 0)
path.lineTo(6, 0)
path.arcTo(QtCore.QRectF(4, 0, 4, 4), 90, -180)
path.lineTo(2, 4)
path.lineTo(2, 1)
path.moveTo(2, 3)
path.lineTo(0, 3)
path.moveTo(8, 2)
path.lineTo(10, 2)
tr = QtGui.QTransform()
tr.scale(s, s)
path = tr.map(path)
self.setPath(path)

def create_end_ports(self):
s = 20
for p1, p2 in (
((0, 1), (0.5, 1)),
((0, 3), (0.5, 3)),
((10, 2), (9.5, 2)),
):
item = TerminalItem(
QtCore.QLineF(s * QtCore.QPointF(*p1), s * QtCore.QPointF(*p2)),
self,
)
self.end_ports.append(item)


class NANDPortItem(ANDPortItem):
def create_path(self):
path = QtGui.QPainterPath()
s = 20
path.moveTo(0, 1)
path.lineTo(2, 1)
path.lineTo(2, 0)
path.lineTo(6, 0)
path.arcTo(QtCore.QRectF(4, 0, 4, 4), 90, -180)
path.lineTo(2, 4)
path.lineTo(2, 1)
path.moveTo(2, 3)
path.lineTo(0, 3)
path.moveTo(8, 2)
path.addEllipse(QtCore.QRectF(8, 2 - 0.25, 0.5, 0.5))
path.moveTo(8.5, 2)
path.lineTo(10, 2)
tr = QtGui.QTransform()
tr.scale(s, s)
path = tr.map(path)
self.setPath(path)


class BulBItem(PortItem):
def create_path(self):
s = 20
path = QtGui.QPainterPath()
path.moveTo(0, 2)
path.lineTo(1, 2)
path.addEllipse(QtCore.QRectF(1, 0, 4, 4))
tr = QtGui.QTransform()
tr.scale(s, s)
path = tr.map(path)
self.setPath(path)

def create_end_ports(self):
s = 20
item = TerminalItem(
QtCore.QLineF(
s * QtCore.QPointF(0, 2), s * QtCore.QPointF(0.75, 2)
),
self,
)
self.end_ports.append(item)


class ClockItem(PortItem):
def create_path(self):
s = 20
path = QtGui.QPainterPath()
path.moveTo(0, 2)
path.lineTo(1, 2)
path.addRect(QtCore.QRectF(1, 0, 4, 4))
tr = QtGui.QTransform()
tr.scale(s, s)
path = tr.map(path)
self.setPath(path)

def create_end_ports(self):
s = 20
item = TerminalItem(
QtCore.QLineF(
s * QtCore.QPointF(0, 2), s * QtCore.QPointF(0.75, 2)
),
self,
)
self.end_ports.append(item)


class GraphicsView(QtWidgets.QGraphicsView):
def __init__(self, scene=None, parent=None):
super().__init__(scene, parent)
self.setRenderHints(QtGui.QPainter.Antialiasing)
self.line_item = QtWidgets.QGraphicsLineItem()
self.line_item.setPen(QtGui.QPen(QtGui.QColor("black"), 4))
self.scene().addItem(self.line_item)
self.line_item.hide()

self.start_item = None

def mousePressEvent(self, event):
items = self.items(event.pos())
for item in items:
if isinstance(item, TerminalItem):
item.setPen(QtGui.QPen(QtCore.Qt.red, 4))
self.line_item.show()
sp = item.end()
line = QtCore.QLineF(sp, sp)
self.line_item.setLine(line)
self.start_item = item
break
super().mousePressEvent(event)

def mouseMoveEvent(self, event):
if self.line_item.isVisible():
l = self.line_item.line()
l.setP2(self.mapToScene(event.pos()))
self.line_item.setLine(l)
for item in self.items():
if (
isinstance(item, TerminalItem)
and item is not self.start_item
):
item.setPen(QtGui.QPen(QtCore.Qt.transparent, 4))

for item in self.items(event.pos()):
if isinstance(item, TerminalItem):
item.setPen(QtGui.QPen(QtCore.Qt.red, 4))
super().mouseMoveEvent(event)

def mouseReleaseEvent(self, event):
if self.line_item.isVisible():
self.line_item.hide()
for item in self.items():
if isinstance(item, TerminalItem) and item:
item.setPen(QtGui.QPen(QtCore.Qt.transparent, 4))
end_item = None
for item in self.items(event.pos()):
if isinstance(item, TerminalItem):
end_item = item
break
if end_item is not None:
edge = Edge(self.start_item, end_item)
self.scene().addItem(edge)
self.start_item = None
super().mouseReleaseEvent(event)


class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
scene = QtWidgets.QGraphicsScene()
graphicsview = GraphicsView(scene)
for t, p in (
(ANDPortItem, QtCore.QPointF(0, 0)),
(BulBItem, QtCore.QPointF(250, 0)),
(ClockItem, QtCore.QPointF(0, 250)),
(NANDPortItem, QtCore.QPointF(250, 250)),
):
item = t()
item.setPos(p)
scene.addItem(item)
self.setCentralWidget(graphicsview)


if __name__ == "__main__":
import sys

app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.resize(640, 480)
w.show()
sys.exit(app.exec_())

enter image description here

关于python - 将端口添加到 QGraphicsPixmapItem 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55892706/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com