Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使覆盖的QGraphicsTextItem可编辑&;可移动的?_Python_Qt_Pyqt_Pyqt5 - Fatal编程技术网

Python 如何使覆盖的QGraphicsTextItem可编辑&;可移动的?

Python 如何使覆盖的QGraphicsTextItem可编辑&;可移动的?,python,qt,pyqt,pyqt5,Python,Qt,Pyqt,Pyqt5,我正在使用PyQt,并试图重新实现一个QGraphicsTextItem,但似乎我遗漏了一些东西 我想使节点tag项的文本可编辑。我已尝试设置标志,例如Qt.TextEditorInteraction和QGraphicsItem.ItemIsMovable,但这些似乎被忽略了 以下是一个最小的可复制示例: 导入系统 从PyQt5.QtWidgets导入QGraphicscene、QGraphicsView、QMainWindow、QApplication、QGraphicsSitem、QGrap

我正在使用PyQt,并试图重新实现一个QGraphicsTextItem,但似乎我遗漏了一些东西

我想使节点tag项的文本可编辑。我已尝试设置标志,例如Qt.TextEditorInteractionQGraphicsItem.ItemIsMovable,但这些似乎被忽略了

以下是一个最小的可复制示例:

导入系统 从PyQt5.QtWidgets导入QGraphicscene、QGraphicsView、QMainWindow、QApplication、QGraphicsSitem、QGraphicsTextItem 从PyQt5.QtCore导入* 从PyQt5.QtGui导入QPen 类节点标记(QGraphicsTextItem): 定义初始化(self,text): QGraphicsTextItem.\uuuuu init\uuuuuuu(self,text) self.text=文本 self.setPos(0,0) self.setTextInteractionFlags(Qt.TextEditorInteraction) #self.setFlag(QGraphicsItem.ItemIsFocusable,True)#所有这些标志都被忽略。。。 #self.setFlag(QGraphicsItem.ItemIsSelectable,True) self.setFlag(QGraphicsItem.ItemIsMovable,True) def boundingRect(自): 返回QRectF(0,0,80,25) def绘制(自绘制、绘制、选项、小部件): 画师设置笔(QPen(Qt.blue,2,Qt.SolidLine)) painter.drawRect(self.boundingRect()) painter.drawText(self.boundingRect(),self.text) def鼠标压力事件(自身、事件): 打印(“单击!”) #self.setTextInteractionFlags(Qt.TextEditorInteraction)#单击可编辑文本 #self.setFocus() 类别GView(QGraphicsView): 定义初始化(自、父、*args、**kwargs): super() self.parent=parent self.setGeometry(100100700450) self.show() 课堂场景(Qgraphicscene): 定义初始化(自身,父级): super()。\uuuu init\uuuu(父级) self.parent=parent tagItem=NodeTag(“myText”)#创建一个NodeTag项 self.addItem(标记项) 类主窗口(QMainWindow): 定义初始化(自): super() 自设置几何体(900、70、1000、800) self.createGraphicView() self.show() def createGraphicView(自): self.scene=场景(self) gView=gView(自) 场景=场景(gView) gView.setScene(场景) #设置主窗口的中心小部件 self.setCentralWidget(gView) #运行程序 如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu': app=QApplication(sys.argv) 窗口=主窗口() sys.exit(app.exec_()) 正如你所看到的,我也尝试过覆盖mousePressEvent并在那里设置标志,但到目前为止运气不佳。 感谢您的帮助

试试看:

...

        
class NodeTag(QGraphicsTextItem):
    def __init__(self, text, parent=None):
        super(NodeTag, self).__init__(parent)
        self.text = text
        self.setPlainText(text)

        self.setFlag(QGraphicsItem.ItemIsMovable)
        self.setFlag(QGraphicsItem.ItemIsSelectable)

    def focusOutEvent(self, event):
        self.setTextInteractionFlags(QtCore.Qt.NoTextInteraction)
        super(NodeTag, self).focusOutEvent(event)

    def mouseDoubleClickEvent(self, event):
        if self.textInteractionFlags() == QtCore.Qt.NoTextInteraction:
            self.setTextInteractionFlags(QtCore.Qt.TextEditorInteraction)
        super(NodeTag, self).mouseDoubleClickEvent(event)
       
    def paint(self,painter,option,widget):
        painter.setPen(QPen(Qt.blue, 2, Qt.SolidLine))
        painter.drawRect(self.boundingRect())
#        painter.drawText(self.boundingRect(),self.text)
        super().paint(painter, option, widget)
 ...
试试看:

...

        
class NodeTag(QGraphicsTextItem):
    def __init__(self, text, parent=None):
        super(NodeTag, self).__init__(parent)
        self.text = text
        self.setPlainText(text)

        self.setFlag(QGraphicsItem.ItemIsMovable)
        self.setFlag(QGraphicsItem.ItemIsSelectable)

    def focusOutEvent(self, event):
        self.setTextInteractionFlags(QtCore.Qt.NoTextInteraction)
        super(NodeTag, self).focusOutEvent(event)

    def mouseDoubleClickEvent(self, event):
        if self.textInteractionFlags() == QtCore.Qt.NoTextInteraction:
            self.setTextInteractionFlags(QtCore.Qt.TextEditorInteraction)
        super(NodeTag, self).mouseDoubleClickEvent(event)
       
    def paint(self,painter,option,widget):
        painter.setPen(QPen(Qt.blue, 2, Qt.SolidLine))
        painter.drawRect(self.boundingRect())
#        painter.drawText(self.boundingRect(),self.text)
        super().paint(painter, option, widget)
 ...

所有QGraphicsItem子类都有一个
paint
方法,所有绘制某些内容的项都覆盖了该方法,以便它们可以实际绘制自己

该机制与标准QWidgets相同,对于标准QWidgets,有一个
paintEvent
(区别在于QGraphicsItem的
paint
接收一个已经实例化的QPainter),因此,如果您想要进行除类已经提供的以外的其他绘制,则必须调用基本实现

考虑到绘制总是从下到上进行,因此需要在基础绘制之后绘制的所有内容都必须在调用
super().paint()
之前完成,并且将要在默认绘制之前绘制的所有内容都必须放在后面

根据具体情况,重写可能需要调用默认的基本实现,这对于
boundingRect
也很重要。QGraphicsTextItem在其内容更改时自动调整自身大小,因此不应总是返回固定的QRect。如果需要最小尺寸,解决方案是将最小矩形与默认的
boundingRect()
函数提供的矩形合并

然后,在QGraphicsTextItem上进行编辑是在项目聚焦时进行的,但由于您也希望能够移动项目,因此这两个操作都是基于鼠标单击的,因此操作会变得更加复杂。如果希望能够通过单击编辑文本,则解决方案是仅当鼠标按钮已释放且未移动一定数量的像素(属性)时,才使该项可编辑,否则将使用鼠标移动该项。这显然使得
ItemIsMovable
标志无用,因为我们将在内部处理移动

最后,由于提供了最小大小,我们还需要重写该方法,以确保正确映射碰撞和单击,并返回包含整个边界矩形的QPainterPath(对于正常的QGraphicsItem,这应该是默认行为,但QGraphicsRecItem不会发生)

下面是上述内容的完整实现:

类节点tag(QGraphicsTextItem):
定义初始化(self,text):
QGraphicsTextItem.\uuuuu init\uuuuuuu(self,text)
self.startPos=None
self.isMoving=False
#以下内容是无用的,不仅仅是因为我们离开了文本
#绘画要基本实现,也因为文字是
#已经可以使用toPlainText()或toHtml()进行访问
#self.text=文本
#这也是不必要的,因为所有新项目始终具有(0,0)位置
#self.setPos(0,0)
def boundingRect(自):
return super().boundingRect()| QRectF(0,0,80,25)
def绘制(自绘制、绘制、选项、小部件):
#在文本前面画边框*(如“后面”)
画师设置笔(QPen(Qt.blue,2,Qt.SolidLine))
painter.drawRect(self.boundingRect())
super().paint(画师、选项、小部件)
def形状(自):
shape=QPainterPath()
shape.addRect(self.boundingRect())
返回形状
def focusOutEvent(自身、事件):
#这是