gpt4 book ai didi

python - PyQt : How to create a lineItem between two button and can move with button?

转载 作者:太空宇宙 更新时间:2023-11-03 20:52:50 25 4
gpt4 key购买 nike

“如何在两个按钮之间创建一个lineItem并且可以随按钮移动”

我的程序可以使用名为“添加按钮”的按钮创建新按钮

我想创建一个 lineItem当我单击创建的两个按钮的名为“连接”的菜单操作时。

现在,我可以在它们之间建立一条线了。但我仍然希望它们在按钮移动时移动。

我看到一些例子是删除它并构建新行..但我只想移动线的位置?

该线路可以执行该操作吗?以下是我的代码

import sys, os
from PyQt5 import QtCore, QtGui, QtWidgets



can_draw=0
start=0
end=0
first_connect=0
second_connect =0


class DragButton(QtWidgets.QPushButton):
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", self.connectLine)
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)


def connectLine(self):

global can_draw
global start
global end
global first_connect
global second_connect

view = self.parent()

can_draw +=1

if can_draw == 1:


start = QtCore.QPointF(view.mapToScene(self.pos()))


if can_draw == 2:

end = QtCore.QPointF(view.mapToScene(self.pos()))


can_draw -= 2


view.createLineItem(start,end)

class GraphicsLineItem(QtWidgets.QGraphicsLineItem):



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)


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.line = None

def _createLineF(self,start,end):

return QtCore.QLineF(start, end)

def createLineItem(self,start,end):

self.line = GraphicsLineItem(self._createLineF(start,end))
self.scene().addItem(self.line)


def clearScene(self):
self.scene().clear()
self.line = None

def add_Text(self):

self.button = DragButton('Text', self)
self.button.setGeometry(230, 80, 100, 30)

self.button.show()



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)
if self.line:
self.line.setLine(self._createLineF())
e.setDropAction(QtCore.Qt.MoveAction)
e.accept()


class Window(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
self.view = View()
self.button = QtWidgets.QPushButton(
"Clear View", clicked=self.view.scene().clear
)
self.btn1 = QtWidgets.QPushButton("add button")
self.btn1.setCheckable(True)
self.btn1.clicked.connect(self.view.add_Text)
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(self.view)
layout.addWidget(self.btn1)


if __name__ == "__main__":

import sys

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

最佳答案

您应该更多地使用信号/槽系统:按钮应该通知 View 它想要连接并在它移动时发出通知。当按钮移动时,该线应该自行处理更新。

这意味着线连接到按钮,按钮连接到 View 。

一个简单的例子:

当您想要连接按钮时,按钮将发送信号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()

该线有两个参数:sourcedestination,用于在它们的位置之间绘制线(您可以定义除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()))

当您单击第二个按钮的“连接”操作时, View 将创建一个新行。

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()

关于python - PyQt : How to create a lineItem between two button and can move with button?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56206236/

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