优化重叠情况

重构代码,添加流程图自动捕捉,并且像素可以调节,方便调整精度。
This commit is contained in:
侯展意 2020-09-24 21:06:10 +08:00
parent b52c6d3d19
commit c914727edf
4 changed files with 240 additions and 46 deletions

View File

@ -3,7 +3,7 @@ from PyQt5.QtGui import QPolygonF, QPen, QPainterPath, QColor, QPainter, QBrush
from PyQt5.QtWidgets import QGraphicsLineItem, QGraphicsItem, QGraphicsSceneMouseEvent, QGraphicsObject, \ from PyQt5.QtWidgets import QGraphicsLineItem, QGraphicsItem, QGraphicsSceneMouseEvent, QGraphicsObject, \
QStyleOptionGraphicsItem, QWidget, QGraphicsSceneHoverEvent QStyleOptionGraphicsItem, QWidget, QGraphicsSceneHoverEvent
from typing import TYPE_CHECKING, Tuple, List from typing import TYPE_CHECKING, Tuple, List, Callable
if TYPE_CHECKING: if TYPE_CHECKING:
from .flowchart_widget import Node, PMGraphicsScene from .flowchart_widget import Node, PMGraphicsScene
@ -11,9 +11,41 @@ if TYPE_CHECKING:
COLOR_NORMAL = QColor(212, 227, 242) COLOR_NORMAL = QColor(212, 227, 242)
COLOR_HOVER = QColor(255, 200, 00) COLOR_HOVER = QColor(255, 200, 00)
COLOR_HOVER_PORT = QColor(0, 0, 50) COLOR_HOVER_PORT = QColor(0, 0, 50)
COLOR_HOVER_MID_POINT = QColor(0, 0, 200)
COLOR_SELECTED = QColor(255, 255, 0) COLOR_SELECTED = QColor(255, 255, 0)
def round_position(point: QPointF, pixels=5):
x, y = point.x(), point.y()
x_cor, y_cor = round(x * 1.0 / pixels) * pixels, round(y * 1.0 / pixels) * pixels
return QPointF(x_cor, y_cor)
class PMGGraphicsLineItem(QGraphicsLineItem):
def __init__(self, line: QLineF):
super(PMGGraphicsLineItem, self).__init__(line)
self.callback = None
self.parent_line: 'CustomLine' = None
def bind_callback(self, parent_line: 'CustomLine' = None):
self.parent_line = parent_line
def mousePressEvent(self, event: 'QGraphicsSceneMouseEvent') -> None:
'''
这里不能进行继承一旦进行了继承似乎会让下面所有的东西都收到信号从而无法选定
:param event:
:return:
'''
super(PMGGraphicsLineItem, self).mousePressEvent(event)
self.parent_line.on_line_item_pressed(event, self)
def mouseDoubleClickEvent(self, event: 'QGraphicsSceneMouseEvent') -> None:
self.parent_line.add_mid_point(self, pos=event.scenePos())
def bind_mouse_clicked(self, callback: Callable):
self.callback = callback
class CustomLine(QGraphicsLineItem): class CustomLine(QGraphicsLineItem):
''' '''
CustomLine不是QObject没有办法绑定信号只能用回调函数的方式 CustomLine不是QObject没有办法绑定信号只能用回调函数的方式
@ -35,24 +67,61 @@ class CustomLine(QGraphicsLineItem):
repaint_callback = None repaint_callback = None
def __init__(self, start_port: 'CustomPort', end_port: 'CustomPort', canvas: 'PMGraphicsScene' = None, def __init__(self, start_port: 'CustomPort', end_port: 'CustomPort', canvas: 'PMGraphicsScene' = None,
mid_points: 'List[CustomCenterPoint]' = None): mid_points: 'List[CustomMidPoint]' = None):
super(CustomLine, self).__init__() super(CustomLine, self).__init__()
self.color = COLOR_NORMAL self.color = COLOR_NORMAL
self.setFlags(QGraphicsItem.ItemIsMovable | QGraphicsItem.ItemIsSelectable) # 拖动 self.setFlags(QGraphicsItem.ItemIsMovable | QGraphicsItem.ItemIsSelectable) # 拖动
self.start_port = start_port self.start_port = start_port
self.end_port = end_port self.end_port = end_port
if self not in start_port.connected_lines:
start_port.connected_lines.append(self)
if self not in end_port.connected_lines:
end_port.connected_lines.append(self)
self.line_Items: List['QGraphicsLineItem'] = [] self.line_Items: List['QGraphicsLineItem'] = []
self.center_points = mid_points if (mid_points is not None) else [CustomCenterPoint()] self.center_points = mid_points if (mid_points is not None) else []
for p in self.center_points: for p in self.center_points:
canvas.addItem(p) canvas.addItem(p)
p.point_dragged.connect(self.refresh)
center_point = self.center_points[0] p.line = self
center_point.point_dragged.connect(self.refresh)
canvas.signal_clear_selection.connect(self.on_clear_selection) canvas.signal_clear_selection.connect(self.on_clear_selection)
self.refresh() self.refresh()
self.canvas = canvas self.canvas = canvas
self.init_line_items() self.init_line_items()
def remove_mid_point(self, mid_point: 'CustomMidPoint'):
index = self.center_points.index(mid_point)
point_to_remove = self.center_points.pop(index)
line_to_remove = self.line_Items.pop(index)
self.canvas.removeItem(point_to_remove)
self.canvas.removeItem(line_to_remove)
self.canvas.removeItem(mid_point)
self.refresh_line_items()
self.update()
self.canvas.graphics_view.viewport().update()
def add_mid_point(self, line_item: 'PMGGraphicsLineItem', pos: QPointF):
index = self.line_Items.index(line_item)
new_center_point = CustomMidPoint(pos, line=self)
self.canvas.addItem(new_center_point)
self.center_points.insert(index, new_center_point)
new_center_point.point_dragged.connect(self.refresh)
if index == 0:
last_pos = self.start_port.center_pos
else:
last_pos = self.center_points[index].center_pos
next_pos = new_center_point.center_pos
new_line_item = PMGGraphicsLineItem(QLineF(last_pos, next_pos))
new_line_item.bind_callback(self)
pen = QPen()
pen.setColor(self.color)
pen.setWidth(5)
new_line_item.setPen(pen)
self.canvas.addItem(new_line_item)
self.line_Items.insert(index, new_line_item)
self.refresh_line_items()
self.update()
self.canvas.graphics_view.viewport().update()
def init_line_items(self): def init_line_items(self):
''' '''
初始化线段包括其中间节点 初始化线段包括其中间节点
@ -62,8 +131,9 @@ class CustomLine(QGraphicsLineItem):
last_pos = self.start_port.center_pos last_pos = self.start_port.center_pos
for p in self.center_points: for p in self.center_points:
pos = p.center_pos pos = p.center_pos
line_item = QGraphicsLineItem(QLineF(last_pos, pos)) line_item = PMGGraphicsLineItem(QLineF(last_pos, pos))
line_item.mousePressEvent = self.on_line_item_pressed # line_item.mousePressEvent = self.on_line_item_pressed
line_item.bind_callback(self)
pen = QPen() pen = QPen()
pen.setColor(self.color) pen.setColor(self.color)
pen.setWidth(5) pen.setWidth(5)
@ -71,8 +141,9 @@ class CustomLine(QGraphicsLineItem):
self.canvas.addItem(line_item) self.canvas.addItem(line_item)
last_pos = pos last_pos = pos
self.line_Items.append(line_item) self.line_Items.append(line_item)
line_item = QGraphicsLineItem(QLineF(last_pos, self.end_port.center_pos)) line_item = PMGGraphicsLineItem(QLineF(last_pos, self.end_port.center_pos))
line_item.mousePressEvent = self.on_line_item_pressed # line_item.mousePressEvent = self.on_line_item_pressed
line_item.bind_callback(self)
self.canvas.addItem(line_item) self.canvas.addItem(line_item)
self.line_Items.append(line_item) self.line_Items.append(line_item)
@ -93,19 +164,18 @@ class CustomLine(QGraphicsLineItem):
line = QLineF(last_pos, self.end_port.center_pos) line = QLineF(last_pos, self.end_port.center_pos)
self.line_Items[-1].setLine(line) self.line_Items[-1].setLine(line)
def on_line_item_pressed(self, e: 'QGraphicsSceneMouseEvent'): def on_line_item_pressed(self, e: 'QGraphicsSceneMouseEvent', line_item: 'CustomLine'):
''' '''
当线段被点击时触发的事件 当线段被点击时触发的事件
:param e: :param e:
:return: :return:
''' '''
print(e) print(line_item)
if e.button() == Qt.LeftButton: if e.button() == Qt.LeftButton:
if not e.modifiers() == Qt.ControlModifier: if not e.modifiers() == Qt.ControlModifier:
self.canvas.signal_clear_selection.emit() self.canvas.signal_clear_selection.emit()
self.setSelected(True) self.canvas.select_item(self)
print(self.canvas.selectedItems()) print(self.canvas.selected_items)
self.color = COLOR_SELECTED self.color = COLOR_SELECTED
def on_clear_selection(self): def on_clear_selection(self):
@ -114,7 +184,7 @@ class CustomLine(QGraphicsLineItem):
:return: :return:
''' '''
self.color = COLOR_NORMAL self.color = COLOR_NORMAL
self.setSelected(False) self.canvas.unselect_item(self)
# self.update() # self.update()
def refresh(self): def refresh(self):
@ -191,12 +261,36 @@ class CustomLine(QGraphicsLineItem):
self.update() self.update()
def on_delete(self):
'''
删除线对象
首先从起始和结束的端口的连线中删除这个线
然后从画布上移除自身所有的中间线段对象和中继点对象
从画布上删除自身
从所有连线的列表中移除自身
:return:
'''
try:
self.start_port.connected_lines.remove(self)
except ValueError:
pass
try:
self.end_port.connected_lines.remove(self)
except ValueError:
pass
for line_item in self.line_Items:
self.canvas.removeItem(line_item)
for mid_item in self.center_points:
self.canvas.removeItem(mid_item)
self.canvas.removeItem(self)
self.canvas.lines.remove(self)
class CustomCenterPoint(QGraphicsObject):
class CustomMidPoint(QGraphicsObject):
point_dragged = pyqtSignal(QGraphicsObject) point_dragged = pyqtSignal(QGraphicsObject)
def __init__(self, pos=None): def __init__(self, pos: QPointF = None, line: 'CustomLine' = None):
super(CustomCenterPoint, self).__init__() super(CustomMidPoint, self).__init__()
# self.setFlags(QGraphicsItem.ItemIsMovable | QGraphicsItem.ItemIsSelectable) # 拖动 # self.setFlags(QGraphicsItem.ItemIsMovable | QGraphicsItem.ItemIsSelectable) # 拖动
self.setAcceptHoverEvents(True) # 接受鼠标悬停事件 self.setAcceptHoverEvents(True) # 接受鼠标悬停事件
self.relative_pos = (0, 0) self.relative_pos = (0, 0)
@ -204,7 +298,12 @@ class CustomCenterPoint(QGraphicsObject):
self.size = (10, 10) self.size = (10, 10)
# self.line = line # self.line = line
if pos is not None: if pos is not None:
self.setPos(QPointF(*pos)) # self.setPos()
# if isinstance(pos,list) or isinstance(pos,tuple):
# self.setPos(pos[0],pos[1])
# else:
self.setPos(pos)
self.line = line
def boundingRect(self): def boundingRect(self):
return QRectF(0, 0, self.size[0], self.size[1]) return QRectF(0, 0, self.size[0], self.size[1])
@ -214,13 +313,18 @@ class CustomCenterPoint(QGraphicsObject):
return QPointF(self.x() + self.size[0] / 2, self.y() + self.size[1] / 2) return QPointF(self.x() + self.size[0] / 2, self.y() + self.size[1] / 2)
def mouseMoveEvent(self, event: 'QGraphicsSceneMouseEvent') -> None: def mouseMoveEvent(self, event: 'QGraphicsSceneMouseEvent') -> None:
'''
鼠标拖动时触发的事件
:param event:
:return:
'''
mouse_x, mouse_y = event.scenePos().x(), event.scenePos().y() mouse_x, mouse_y = event.scenePos().x(), event.scenePos().y()
self.setPos(QPointF(mouse_x, mouse_y)) self.setPos(round_position(QPointF(mouse_x, mouse_y)))
self.point_dragged.emit(self) self.point_dragged.emit(self)
def paint(self, painter, styles, widget=None): def paint(self, painter, styles, widget=None):
pen1 = QPen(Qt.SolidLine) pen1 = QPen(Qt.SolidLine)
pen1.setColor(QColor(128, 128, 128)) pen1.setColor(self.color)
painter.setPen(pen1) painter.setPen(pen1)
brush1 = QBrush(Qt.SolidPattern) brush1 = QBrush(Qt.SolidPattern)
@ -231,8 +335,7 @@ class CustomCenterPoint(QGraphicsObject):
painter.drawRoundedRect(self.boundingRect(), 10, 10) painter.drawRoundedRect(self.boundingRect(), 10, 10)
def hoverEnterEvent(self, event: 'QGraphicsSceneHoverEvent') -> None: def hoverEnterEvent(self, event: 'QGraphicsSceneHoverEvent') -> None:
self.color = COLOR_HOVER_PORT self.color = COLOR_HOVER_MID_POINT
self.update() self.update()
def hoverLeaveEvent(self, event: 'QGraphicsSceneHoverEvent') -> None: def hoverLeaveEvent(self, event: 'QGraphicsSceneHoverEvent') -> None:
@ -261,6 +364,9 @@ class CustomCenterPoint(QGraphicsObject):
painter.drawRoundedRect(self.boundingRect(), 10, 10) # 绘制函数 painter.drawRoundedRect(self.boundingRect(), 10, 10) # 绘制函数
painter.end() painter.end()
def mouseDoubleClickEvent(self, event: 'QGraphicsSceneMouseEvent') -> None:
self.line.remove_mid_point(self)
class CustomPort(QGraphicsObject): class CustomPort(QGraphicsObject):
port_clicked = pyqtSignal(QGraphicsObject) port_clicked = pyqtSignal(QGraphicsObject)
@ -273,6 +379,8 @@ class CustomPort(QGraphicsObject):
self.id = port_id self.id = port_id
self.size = (10, 10) self.size = (10, 10)
self.content = content self.content = content
self.connected_lines = []
self.canvas = None
def boundingRect(self): def boundingRect(self):
return QRectF(0, 0, self.size[0], self.size[1]) return QRectF(0, 0, self.size[0], self.size[1])
@ -328,6 +436,11 @@ class CustomPort(QGraphicsObject):
pos = self.pos() pos = self.pos()
return pos.x(), pos.y() return pos.x(), pos.y()
def on_delete(self):
for line in self.connected_lines:
line.on_delete()
self.canvas.removeItem(self)
def __repr__(self): def __repr__(self):
return super(CustomPort, self).__repr__() + 'id = ' + str(self.id) return super(CustomPort, self).__repr__() + 'id = ' + str(self.id)
@ -342,8 +455,6 @@ class CustomRect(QGraphicsItem):
self.color = COLOR_NORMAL self.color = COLOR_NORMAL
self.node = node self.node = node
def boundingRect(self): def boundingRect(self):
return QRectF(0, 0, 200, 50) return QRectF(0, 0, 200, 50)
@ -372,7 +483,9 @@ class CustomRect(QGraphicsItem):
self.update() self.update()
def mouseMoveEvent(self, event: QGraphicsSceneMouseEvent) -> None: def mouseMoveEvent(self, event: QGraphicsSceneMouseEvent) -> None:
self.setPos(event.scenePos().x() - self.relative_pos[0], event.scenePos().y() - self.relative_pos[1]) self.setPos(round_position(
QPointF(event.scenePos().x() - self.relative_pos[0],
event.scenePos().y() - self.relative_pos[1])))
self.node.refresh_pos() self.node.refresh_pos()
def mousePressEvent(self, evt: QGraphicsSceneMouseEvent): def mousePressEvent(self, evt: QGraphicsSceneMouseEvent):
@ -385,7 +498,7 @@ class CustomRect(QGraphicsItem):
print(self.relative_pos) print(self.relative_pos)
if not evt.modifiers() == Qt.ControlModifier: if not evt.modifiers() == Qt.ControlModifier:
self.scene().signal_clear_selection.emit() self.scene().signal_clear_selection.emit()
self.setSelected(True) self.scene().select_item(self)
print(self.scene().selectedItems()) print(self.scene().selectedItems())
self.color = COLOR_SELECTED self.color = COLOR_SELECTED
elif evt.button() == Qt.RightButton: elif evt.button() == Qt.RightButton:
@ -408,4 +521,8 @@ class CustomRect(QGraphicsItem):
:return: :return:
''' '''
self.color = COLOR_NORMAL self.color = COLOR_NORMAL
self.setSelected(False) self.scene().unselect_item(self)
def on_delete(self):
self.node.on_delete()
pass

View File

@ -2,11 +2,12 @@ import sys
from typing import Tuple, List, Dict from typing import Tuple, List, Dict
import json import json
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QToolButton, QSpacerItem, QSizePolicy, QGraphicsView, \ from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QToolButton, QSpacerItem, QSizePolicy, QGraphicsView, \
QFrame, QApplication, QGraphicsScene, QGraphicsSceneMouseEvent QFrame, QApplication, QGraphicsScene, QGraphicsSceneMouseEvent, QMenu, QGraphicsSceneContextMenuEvent, \
from PyQt5.QtCore import QSize, QCoreApplication, pyqtSignal, QLineF, QObject QGraphicsTextItem
from PyQt5.QtGui import QIcon, QPixmap, QPen, QColor from PyQt5.QtCore import QSize, QCoreApplication, pyqtSignal, QLineF, QObject, QPoint, Qt, QPointF
from PyQt5.QtGui import QIcon, QPixmap, QPen, QColor, QKeyEvent
from pmgwidgets.flowchart.flow_items import CustomRect, CustomPort, CustomLine, CustomCenterPoint from pmgwidgets.flowchart.flow_items import CustomRect, CustomPort, CustomLine, CustomMidPoint
COLOR_NORMAL = QColor(212, 227, 242) COLOR_NORMAL = QColor(212, 227, 242)
COLOR_HOVER = QColor(255, 200, 00) COLOR_HOVER = QColor(255, 200, 00)
@ -18,16 +19,30 @@ class PMGraphicsScene(QGraphicsScene):
signal_port_clicked = pyqtSignal(str) # 点击端口的事件 signal_port_clicked = pyqtSignal(str) # 点击端口的事件
signal_clear_selection = pyqtSignal() # 清除选择的事件 signal_clear_selection = pyqtSignal() # 清除选择的事件
def __init__(self, parent=None, graphics_view: 'QGraphicsView' = None): def __init__(self, parent=None, graphics_view: 'QGraphicsView' = None, flow_widget: 'PMFlowWidget' = None):
super().__init__(parent) super().__init__(parent)
from pmgwidgets.flowchart.flow_items import CustomLine from pmgwidgets.flowchart.flow_items import CustomLine
self.lines: List[CustomLine] = [] self.lines: List[CustomLine] = []
self.nodes: List['Node'] = []
self.drawing_lines = False self.drawing_lines = False
self.line_start_port = None self.line_start_port = None
self.line_start_point = None self.line_start_point = None
self.line_end_port = None self.line_end_port = None
self.line = self.addLine(0, 0, 100, 100, QPen()) self.line = self.addLine(0, 0, 1, 1, QPen())
self.graphics_view = graphics_view self.graphics_view = graphics_view
self.flow_widget: 'PMFlowWidget' = flow_widget
self.menu = QMenu()
self.menu.addAction('New').triggered.connect(lambda x: self.add_node())
self.menu.addAction('Delete Selected').triggered.connect(lambda x: self.delete_selected_item())
self.selected_items = []
def contextMenuEvent(self, event: 'QGraphicsSceneContextMenuEvent') -> None:
super(PMGraphicsScene, self).contextMenuEvent(event)
self.menu.exec_(event.screenPos())
def keyPressEvent(self, event: 'QKeyEvent') -> None:
if event.key() == Qt.Key_Delete:
self.delete_selected_item()
def mouseMoveEvent(self, event: 'QGraphicsSceneMouseEvent') -> None: def mouseMoveEvent(self, event: 'QGraphicsSceneMouseEvent') -> None:
super(PMGraphicsScene, self).mouseMoveEvent(event) super(PMGraphicsScene, self).mouseMoveEvent(event)
@ -46,18 +61,51 @@ class PMGraphicsScene(QGraphicsScene):
self.signal_item_dragged.connect(line.refresh) self.signal_item_dragged.connect(line.refresh)
self.drawing_lines = False self.drawing_lines = False
# def selectionChanged(self) -> None: def add_node(self):
# super(PMGraphicsScene, self).selectionChanged() view = self.graphics_view
# print('selection changed !')
n = Node(self, 'node3', input_ports=[CustomPort(10), CustomPort(11)],
output_ports=[CustomPort(12), CustomPort(13), CustomPort(14)])
n.set_pos(200, 50)
print(n.get_pos())
self.nodes.append(n)
def delete_selected_item(self):
'''
删除被选中的物品
:return:
'''
print(self.selectedItems())
for selected_item in self.selected_items:
if hasattr(selected_item, 'on_delete'):
selected_item.on_delete()
self.selected_items = []
print('delete!')
def unselect_item(self, item):
if item in self.selected_items:
self.selected_items.remove(item)
def select_item(self, item):
if item not in self.selected_items:
self.selected_items.append(item)
class Node(QObject): class Node(QObject):
'''
Node是一个节点的抽象
'''
def __init__(self, canvas: 'PMGraphicsScene', name, input_ports: List[CustomPort] = None, def __init__(self, canvas: 'PMGraphicsScene', name, input_ports: List[CustomPort] = None,
output_ports: List[CustomPort] = None): output_ports: List[CustomPort] = None, content: object = None):
super(Node, self).__init__() super(Node, self).__init__()
self.name = name self.name = name
self.base_rect = CustomRect(self) self.base_rect = CustomRect(self)
self.text = QGraphicsTextItem(parent=self.base_rect)
self.text.setPos(100, 10)
self.text.setPlainText(self.name)
if input_ports == None: if input_ports == None:
self.input_ports = [CustomPort(0), CustomPort(1)] self.input_ports = [CustomPort(0), CustomPort(1)]
else: else:
@ -67,13 +115,25 @@ class Node(QObject):
else: else:
self.output_ports = output_ports self.output_ports = output_ports
self.canvas = canvas self.canvas = canvas
self.content = None
self.setup() self.setup()
def set_pos(self, x: int, y: int): def set_pos(self, x: int, y: int):
'''
设置位置左上角角点
:param x:
:param y:
:return:
'''
self.base_rect.setPos(x, y) self.base_rect.setPos(x, y)
self.refresh_pos() self.refresh_pos()
def get_pos(self) -> Tuple[int, int]: def get_pos(self) -> Tuple[int, int]:
'''
获取位置左上角角点
:return:
'''
pos = self.base_rect.pos() pos = self.base_rect.pos()
return pos.x(), pos.y() return pos.x(), pos.y()
@ -84,15 +144,16 @@ class Node(QObject):
x_input = self.base_rect.x() + 5 x_input = self.base_rect.x() + 5
x_output = self.base_rect.x() + self.base_rect.boundingRect().width() - 15 x_output = self.base_rect.x() + self.base_rect.boundingRect().width() - 15
for i, p in enumerate(self.input_ports): for i, p in enumerate(self.input_ports):
p.setPos(x_input, y + int(dy_input * (1 + i))) p.setPos(QPointF(x_input, y + int(dy_input * (1 + i))))
for i, p in enumerate(self.output_ports): for i, p in enumerate(self.output_ports):
p.setPos(x_output, y + int(dy_output * (1 + i))) p.setPos(QPointF(x_output, y + int(dy_output * (1 + i))))
self.canvas.signal_item_dragged.emit('') self.canvas.signal_item_dragged.emit('')
def setup(self): def setup(self):
self.base_rect.setPos(80, 80) self.base_rect.setPos(80, 80)
self.canvas.signal_clear_selection.connect(self.base_rect.on_clear_selection) self.canvas.signal_clear_selection.connect(self.base_rect.on_clear_selection)
self.canvas.addItem(self.base_rect) self.canvas.addItem(self.base_rect)
for p in self.input_ports + self.output_ports: for p in self.input_ports + self.output_ports:
self.canvas.addItem(p) self.canvas.addItem(p)
p.port_clicked.connect(self.on_port_clicked) p.port_clicked.connect(self.on_port_clicked)
@ -109,6 +170,14 @@ class Node(QObject):
self.canvas.line_start_point = port.center_pos self.canvas.line_start_point = port.center_pos
self.canvas.line_start_port = port self.canvas.line_start_port = port
def on_delete(self):
for port in self.input_ports + self.output_ports:
port.canvas = self.canvas
port.on_delete()
self.canvas.removeItem(self.base_rect)
self.canvas.nodes.remove(self)
self.deleteLater()
def __repr__(self): def __repr__(self):
s = super(Node, self).__repr__() s = super(Node, self).__repr__()
return s + repr(self.input_ports) + repr(self.output_ports) return s + repr(self.input_ports) + repr(self.output_ports)
@ -274,7 +343,7 @@ class PMFlowWidget(QWidget):
# self.rect2 = CustomRect() # self.rect2 = CustomRect()
# self.rect2.setPos(100, 100) # self.rect2.setPos(100, 100)
# #
self.scene = PMGraphicsScene(graphics_view=self.graphicsView) self.scene = PMGraphicsScene(graphics_view=self.graphicsView, flow_widget=self)
self.scene.setSceneRect(0, 0, 300, 300) self.scene.setSceneRect(0, 0, 300, 300)
# self.scene.addItem(self.rect) # self.scene.addItem(self.rect)
@ -294,7 +363,7 @@ class PMFlowWidget(QWidget):
self.nodes = [self.n, self.n2] self.nodes = [self.n, self.n2]
self.nodes: List[Node] = [] self.nodes: List[Node] = self.scene.nodes
self.lines = self.scene.lines self.lines = self.scene.lines
self.load_flowchart() self.load_flowchart()
@ -342,8 +411,6 @@ class PMFlowWidget(QWidget):
node_properties['input_ports'] = input_ports_dic node_properties['input_ports'] = input_ports_dic
node_properties['output_ports'] = output_ports_dic node_properties['output_ports'] = output_ports_dic
nodes_dic[node.name] = node_properties nodes_dic[node.name] = node_properties
# print(nodes_dic)
with open(r'c:\users\12957\desktop\123.txt', 'w') as f: with open(r'c:\users\12957\desktop\123.txt', 'w') as f:
json.dump(fc_info, f, indent=4) json.dump(fc_info, f, indent=4)
pass pass
@ -380,7 +447,7 @@ class PMFlowWidget(QWidget):
mid_positions = line_property['mid_positions'] mid_positions = line_property['mid_positions']
mid_points = [] mid_points = []
for pos in mid_positions: for pos in mid_positions:
mid_points.append(CustomCenterPoint(pos=pos)) mid_points.append(CustomMidPoint(pos=QPointF(*pos)))
print(start_port, end_port, start_id, end_id) print(start_port, end_port, start_id, end_id)
line = CustomLine(canvas=self.scene, start_port=start_port, end_port=end_port, mid_points=mid_points) line = CustomLine(canvas=self.scene, start_port=start_port, end_port=end_port, mid_points=mid_points)

View File

@ -0,0 +1,7 @@
from PyQt5.QtCore import QPointF
def round_position(point: QPointF, pixels=5):
x, y = point.x(), point.y()
x_cor, y_cor = round(x * 1.0 / pixels) * pixels, round(y * 1.0 / pixels) * pixels
return QPointF(x_cor, y_cor)

View File

@ -12,6 +12,9 @@ class Extension(BaseExtension):
app_toolbar_interface = self.extension_lib.get_interface('applications_toolbar') app_toolbar_interface = self.extension_lib.get_interface('applications_toolbar')
import os import os
path = os.path.dirname(__file__) path = os.path.dirname(__file__)
app_toolbar_interface.add_app( group='应用测试', text='测试插件',
icon_path=':/pyqt/source/images/lc_searchdialog.png', callback=lambda :print('this is app'), hint='')
app_toolbar_interface.add_process_action('应用测试', '测试对话框', app_toolbar_interface.add_process_action('应用测试', '测试对话框',
':/pyqt/source/images/lc_searchdialog.png', ':/pyqt/source/images/lc_searchdialog.png',
['python','-u',os.path.join(path,'run_dialog.py')]) ['python','-u',os.path.join(path,'run_dialog.py')])