“如何在两个按钮之间创建lineItem并可以通过按钮移动”
我的程序可以使用名为“添加按钮”的按钮创建新按钮
,我想创建一个lineItem 当我单击创建的两个按钮的名为“连接”的菜单操作时。
现在,我可以在它们之间建立一条线。 但是我仍然希望它们在按钮移动时移动。
我看到一些示例是删除它并建立新行。 但我只想移动线的位置?
那行可以采取行动吗? 以下是我的代码
'In the are lines order printed reverse'
答案 0 :(得分:0)
您应该更多地使用信号/插槽系统:该按钮应通知视图它想要连接,并通知其移动时间。当按钮移动时,该行应自行处理其更新。
这意味着该行已连接到按钮,按钮已连接到视图。
一个简单的例子:
当您想连接信号connectionRequested
时,该按钮将发送信号moved
。
class DragButton(QtWidgets.QPushButton):
connectionRequested = pyqtSignal(QtWidgets.QPushButton)
moved = pyqtSignal()
def __init__(self, title, parent=None):
super().__init__(title, parent)
self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.customContextMenuRequested.connect(self.showMenu)
def showMenu(self):
menu = QtWidgets.QMenu()
menu.addAction("connect", lambda: self.connectionRequested.emit(self))
menu.exec_(self.cursor().pos())
def mouseMoveEvent(self, e):
if e.buttons() != QtCore.Qt.LeftButton:
return
mimeData = QtCore.QMimeData()
drag = QtGui.QDrag(self)
drag.setMimeData(mimeData)
drag.setHotSpot(e.pos() - self.rect().topLeft())
dropAction = drag.exec_(QtCore.Qt.MoveAction)
self.moved.emit()
该行有两个参数:source
和destination
,用于在其位置之间绘制线(您可以定义pos
以外的另一种方法来返回相对位置,例如您的按钮)。
class GraphicsLineItem(QtWidgets.QGraphicsLineItem):
def __init__(self, source, destination, parent=None):
super().__init__(parent)
self.source = source
self.destination = destination
self.move()
self.source.moved.connect(self.move)
self.destination.moved.connect(self.move)
def contextMenuEvent(self, event):
menu = QtWidgets.QMenu()
menu.addAction("Delete", self.remove)
menu.exec_(self.cursor().pos())
print(self.a)
def remove(self):
self.scene().removeItem(self)
def shape(self):
p = super(GraphicsLineItem, self).shape()
stroker = QtGui.QPainterPathStroker()
stroker.setWidth(20)
return stroker.createStroke(p)
def move(self):
self.setLine(QLineF(self.source.pos(), self.destination.pos()))
当您单击第二个按钮的connect
操作时,视图将创建新行。
class View(QtWidgets.QGraphicsView):
def __init__(self, parent=None):
super(View, self).__init__(parent)
self.setScene(QtWidgets.QGraphicsScene(self))
self.setAcceptDrops(True)
self.setSceneRect(QtCore.QRectF(self.viewport().rect()))
self.btn1 = QtWidgets.QPushButton("Start")
self.btn1.setGeometry(230, 80, 100, 30)
self.btn1.setCheckable(True)
self.btn1.clicked.connect(self.add_Text)
self.source = None
def clearScene(self):
self.scene().clear()
self.source = None
def add_Text(self):
button = DragButton('Text', self)
button.setGeometry(230, 80, 100, 30)
button.show()
button.connectionRequested.connect(self.connectButton)
def connectButton(self, button):
# Do not connect a button with itself
if not self.source or button == self.source:
self.source = button
return
line = GraphicsLineItem(self.source, button)
self.scene().addItem(line)
self.source = None
def dragEnterEvent(self, e):
e.accept()
def dragMoveEvent(self, e):
e.accept()
def dropEvent(self, e):
btn = e.source()
position = e.pos()
btn.move(position)
e.setDropAction(QtCore.Qt.MoveAction)
e.accept()