我正在使用PyQt,并试图重新实现一个QGraphicsTextItem,但似乎我遗漏了一些东西
我想使节点tag项的文本可编辑。我已尝试设置标志,例如Qt.TextEditorInteraction和QGraphicsItem.ItemIsMovable,但这些似乎被忽略了
以下是一个最小的可复制示例:
import sys
from PyQt5.QtWidgets import QGraphicsScene, QGraphicsView, QMainWindow, QApplication, QGraphicsItem, QGraphicsTextItem
from PyQt5.QtCore import *
from PyQt5.QtGui import QPen
class NodeTag(QGraphicsTextItem):
def __init__(self,text):
QGraphicsTextItem.__init__(self,text)
self.text = text
self.setPos(0,0)
self.setTextInteractionFlags(Qt.TextEditorInteraction)
# self.setFlag(QGraphicsItem.ItemIsFocusable, True) # All these flags are ignored...
# self.setFlag(QGraphicsItem.ItemIsSelectable, True)
self.setFlag(QGraphicsItem.ItemIsMovable, True)
def boundingRect(self):
return QRectF(0,0,80,25)
def paint(self,painter,option,widget):
painter.setPen(QPen(Qt.blue, 2, Qt.SolidLine))
painter.drawRect(self.boundingRect())
painter.drawText(self.boundingRect(),self.text)
def mousePressEvent(self, event):
print("CLICK!")
# self.setTextInteractionFlags(Qt.TextEditorInteraction) # make text editable on click
# self.setFocus()
class GView(QGraphicsView):
def __init__(self, parent, *args, **kwargs):
super().__init__(*args, **kwargs)
self.parent = parent
self.setGeometry(100, 100, 700, 450)
self.show()
class Scene(QGraphicsScene):
def __init__(self, parent):
super().__init__(parent)
self.parent = parent
tagItem = NodeTag("myText") # create a NodeTag item
self.addItem(tagItem)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__() # create default constructor for QWidget
self.setGeometry(900, 70, 1000, 800)
self.createGraphicView()
self.show()
def createGraphicView(self):
self.scene = Scene(self)
gView = GView(self)
scene = Scene(gView)
gView.setScene(scene)
# Set the main window's central widget
self.setCentralWidget(gView)
# Run program
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
sys.exit(app.exec_())
正如你所看到的,我也尝试过覆盖mousePressEvent并在那里设置标志,但到目前为止运气不佳。 感谢您的帮助
试试看:
所有QGraphicsItem子类都有一个
paint
方法,所有绘制某些内容的项都覆盖了该方法,以便它们实际上可以绘制自己该机制与标准QWidgets相同,对于标准QWidgets,有一个
paintEvent
(区别在于QGraphicsItem的paint
接收一个已经实例化的QPaint),因此,如果您想在类已经提供的基础上进一步绘制其他,则必须调用基本实现认为绘画总是自下而上,所以需要画出的东西后面的EEM >底漆必须在之前调用eEM>调用^ {CD4>},并且缺省绘画的前面中的所有东西都要放在后。p>
根据具体情况,重写可能需要调用默认的基本实现,这对于
boundingRect
来说也很重要。QGraphicsTextItem在其内容更改时自动调整自身大小,因此不应总是返回固定的QRect。如果需要最小大小,解决方案是将最小矩形与默认boundingRect()
函数提供的合并然后,在QGraphicsTextItem上进行编辑时,项目会被聚焦到上,但由于您也希望能够移动项目,所以这两个操作都是基于鼠标单击的,因此操作会变得更加复杂。如果您希望能够通过单击编辑文本,解决方案是当鼠标按钮被释放并且没有移动一定数量的像素时(即^{} 属性),使项目仅可编辑,否则项目将随鼠标移动。这显然使
ItemIsMovable
标志无用,因为我们将在内部处理该运动最后,由于提供了最小大小,我们还需要重写^{} 方法,以确保正确映射碰撞和单击,并返回包含整个边界rect的QPainterPath(对于正常的QGraphicsSitem,这应该是默认行为,但QGraphicsRecItem不会发生)
下面是上述内容的完整实现:
作为旁注,请记住QGraphicsTextItem支持富文本格式,因此即使您希望对文本绘制过程进行更多控制,也不应使用^{,因为您只需绘制纯文本。事实上,QGraphicsTextItem使用底层text document的^{} 函数绘制其内容
相关问题 更多 >
编程相关推荐