gpt4 book ai didi

python - PyQt : How to create a menu in a QLineItem when I click it

转载 作者:太空宇宙 更新时间:2023-11-04 04:11:35 24 4
gpt4 key购买 nike

我想在单击它时创建一个菜单,就像我下面代码中的按钮一样。并执行“删除”之类的操作可以删除该行

我可以在 QLine 中这样做吗?或者菜单只能在按钮中使用...?

我想删除这条线,而不是清理 View 。

我试试这个 类 add_Line(QLineF):

    def __init__(self, title, parent=None):
super().__init__(title, parent)
menu = QMenu()
menu.addAction = ('delete',self.deleteLater)

但是不行有人可以帮助我吗?

import sys, os
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QDrag
from PyQt5.QtCore import Qt, QMimeData


class Window(QWidget):
def __init__(self):
QWidget.__init__(self)
self.view = View(self)
self.button = QPushButton('Clear View', self)
self.button.clicked.connect(self.handleClearView)
layout = QVBoxLayout(self)
layout.addWidget(self.view)
layout.addWidget(self.button)

def handleClearView(self):
self.view.scene().clear()

class add_Line(QLineF):


def __init__(self, title, parent=None):
super().__init__(title, parent)



class DragButton(QPushButton):
def __init__(self, title, parent=None):
super().__init__(title, parent)
self.setContextMenuPolicy(Qt.CustomContextMenu)
self.customContextMenuRequested.connect(self.showMenu)

def showMenu(self):
menu=QMenu()
menu.addAction('connect', self.connectLine)
menu.exec_(self.cursor().pos())

def connectLine(self):
view = self.parent()
view.createLineItem()


def mouseMoveEvent(self, e):
if e.buttons() != Qt.LeftButton:
return

mimeData = QMimeData()
drag = QDrag(self)
drag.setMimeData(mimeData)
drag.setHotSpot(e.pos() - self.rect().topLeft())
dropAction = drag.exec_(Qt.MoveAction)


class View(QGraphicsView):
def __init__(self, parent):
QGraphicsView.__init__(self, parent)
self.setScene(QGraphicsScene(self))
self.setAcceptDrops(True)
self.setSceneRect(QtCore.QRectF(self.viewport().rect()))
self.btn1=DragButton('Test1', self)
self.btn2=DragButton('Test2', self)
self.line = None

def _createLineF(self):
start = QtCore.QPointF(self.mapToScene(self.btn1.pos()))
end = QtCore.QPointF(self.mapToScene(self.btn2.pos()))
return add_Line(start,end)


def createLineItem(self):
self.line = QGraphicsLineItem(self._createLineF())
self.scene().addItem(self.line)

def clearScene(self):
self.scene().clear()
self.line = 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)
if self.line:
self.line.setLine(self._createLineF())
e.setDropAction(Qt.MoveAction)
e.accept()


if __name__ == '__main__':

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

最佳答案

QLineF只有一条线的几何信息,不是场景中显示的item。显示的项目是 QGraphicsLineItem,该项目确实有 contextMenuEvent 方法,所以 QMenu 必须在那里实现。另一方面,QGraphicsItem 使用形状来指示接收鼠标事件的部分,但默认情况下线的宽度很小,因此很难获得鼠标事件,所以我将形状设置得有点宽使用简单:

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


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 connectLine(self):
view = self.parent()
view.createLineItem()

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)


class GraphicsLineItem(QtWidgets.QGraphicsLineItem):
def contextMenuEvent(self, event):
menu = QtWidgets.QMenu()
menu.addAction("Delete", self.remove)
menu.exec_(self.cursor().pos())

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 = DragButton("Test1", self)
self.btn2 = DragButton("Test2", self)
self.line = None

def _createLineF(self):
start = QtCore.QPointF(self.mapToScene(self.btn1.pos()))
end = QtCore.QPointF(self.mapToScene(self.btn2.pos()))
return QtCore.QLineF(start, end)

def createLineItem(self):
self.line = GraphicsLineItem(self._createLineF())
self.scene().addItem(self.line)

def clearScene(self):
self.scene().clear()
self.line = 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)
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
)
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(self.view)
layout.addWidget(self.button)


if __name__ == "__main__":

import sys

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

关于python - PyQt : How to create a menu in a QLineItem when I click it,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56201118/

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