Python 如何使选定qgraphicsitem的边界矩形自动显示?
我在SO中找到了@serge_gubenko的例子。 然后我做了一些修改,最终得到: 如果我运行该示例并单击图形项,它会自动显示一个虚线框,表示它已被选中。我准备了一些图片来展示这种效果,但是由于我的名声不好,我还不能上传这些图片 在我看来,这是由虚线框自动选择的指示。Python 如何使选定qgraphicsitem的边界矩形自动显示?,python,pyqt4,Python,Pyqt4,我在SO中找到了@serge_gubenko的例子。 然后我做了一些修改,最终得到: 如果我运行该示例并单击图形项,它会自动显示一个虚线框,表示它已被选中。我准备了一些图片来展示这种效果,但是由于我的名声不好,我还不能上传这些图片 在我看来,这是由虚线框自动选择的指示。 在我修改过的示例中,这种情况没有发生,我也不知道为什么?您使用QtGui.QGraphicsItem,因此您定义了boundingRect和paint方法,其中使用了painter-drawerlipse方法。在您发现的第一
在我修改过的示例中,这种情况没有发生,我也不知道为什么?您使用QtGui.QGraphicsItem,因此您定义了boundingRect和paint方法,其中使用了painter-drawerlipse方法。在您发现的第一个示例中,该类直接使用QtGui.QGraphicsEllipseItem,并且它完成了所有不同之处,因为这些方法已经定义。顺便说一句,我不知道为什么在您的案例中没有绘制boundingRect。您使用QtGui.QGraphicsItem,因此您定义了boundingRect和paint方法,其中使用了painter-Dropellipse方法。在您发现的第一个示例中,该类直接使用QtGui.QGraphicsEllipseItem,并且它完成了所有不同之处,因为这些方法已经定义。顺便说一句,我不知道为什么在您的案例中没有绘制boundingRect。这里有一个工作示例,它有自己的drawFocusRect方法 焦点以两种方式表示: 1单击Qgraphicsitem,然后绘制边界矩形。 2将鼠标悬停在项目上方。激发时,笔样式将更改为点线,并在激发时转换回实线
#!d:/python27/python -u
import sys
from PyQt4 import QtGui, QtCore
class GraphicsItem(QtGui.QGraphicsItem):
"""
From the QT docs:
To write your own graphics item, you first create a subclass
of QGraphicsItem, and then start by implementing its two pure
virtual public functions: boundingRect(), which returns an estimate
of the area painted by the item, and paint(),
which implements the actual painting.
"""
# call constructor of GraphicsItem
def __init__(self, rect, pen, brush, tooltip='No tip here', parent=None):
# call constructor of QGraphicsItem
super(GraphicsItem, self).__init__()
self.setFlag(QtGui.QGraphicsItem.ItemIsMovable, True)
self.setFlag(QtGui.QGraphicsItem.ItemIsSelectable, True)
self.setFlag(QtGui.QGraphicsItem.ItemIsFocusable, True)
self.setAcceptsHoverEvents(True)
self.pen = pen
pw = self.pen.widthF()
self.brush = QtGui.QBrush(QtCore.Qt.blue)
self.brush = brush
self.setToolTip(tooltip)
self.parent = parent
self.rect = QtCore.QRectF(rect[0], rect[1], rect[2], rect[3])
self.focusrect = QtCore.QRectF(rect[0]-pw/2, rect[1]-pw/2,
rect[2]+pw, rect[3]+pw)
def mouseMoveEvent(self, event):
# move object
QtGui.QGraphicsItem.mouseMoveEvent(self, event)
def mousePressEvent(self, event):
# select object
# set item as topmost in stack
self.setZValue(self.parent.scene.items()[0].zValue() + 1)
self.setSelected(True)
QtGui.QGraphicsItem.mousePressEvent(self, event)
def boundingRect(self):
return self.rect
def paint(self, painter, option, widget):
painter.setBrush(self.brush)
painter.setPen(self.pen)
painter.drawEllipse(self.rect)
if self.isSelected():
self.drawFocusRect(painter)
def drawFocusRect(self, painter):
self.focusbrush = QtGui.QBrush()
self.focuspen = QtGui.QPen(QtCore.Qt.DotLine)
self.focuspen.setColor(QtCore.Qt.black)
self.focuspen.setWidthF(1.5)
painter.setBrush(self.focusbrush)
painter.setPen(self.focuspen)
painter.drawRect(self.focusrect)
def hoverEnterEvent(self, event):
self.pen.setStyle(QtCore.Qt.DotLine)
QtGui.QGraphicsItem.hoverEnterEvent(self, event)
def hoverLeaveEvent(self, event):
self.pen.setStyle(QtCore.Qt.SolidLine)
QtGui.QGraphicsItem.hoverLeaveEvent(self, event)
class MyMainWindow(QtGui.QMainWindow):
# call constructor of MyMainWindow
def __init__(self, parent=None):
# call constructor of QMainWindow
super(MyMainWindow, self).__init__(parent)
w = 1000
h = 800
self.scene = QtGui.QGraphicsScene(-w/2, -h/2, w, h)
self.view = QtGui.QGraphicsView()
# set QGraphicsView attributes
self.view.setRenderHints(QtGui.QPainter.Antialiasing |
QtGui.QPainter.HighQualityAntialiasing)
self.view.setViewportUpdateMode(QtGui.QGraphicsView.FullViewportUpdate)
self.view.setScene(self.scene)
# set central widget for the application
self.setCentralWidget(self.view)
# add items to the scene
self.addGraphicsItem((0, 0, 250, 250), 8.0, (255, 0, 0), (0, 0, 255), 'My first item')
self.addGraphicsItem((-250, -250, 300, 200), 4.0, (0, 0, 0), (255, 0, 100), 'My 2nd item')
self.addGraphicsItem((200, -200, 200, 200), 10.0, (0, 0, 255), (0, 255, 100), 'My 3rd item')
def addGraphicsItem(self, rect, pw, pc, bc, tooltip):
pen = QtGui.QPen(QtCore.Qt.SolidLine)
pen.setColor(QtGui.QColor(pc[0], pc[1], pc[2], 255))
pen.setWidth(pw)
brush = QtGui.QBrush(QtGui.QColor(bc[0], bc[1], bc[2], 255))
item = GraphicsItem(rect, pen, brush, tooltip, self)
self.scene.addItem(item)
def mousePressEvent(self, event):
#print 'from MainWindow'
pass
def keyPressEvent(self, event):
key = event.key()
if key == QtCore.Qt.Key_Escape:
sys.exit(QtGui.qApp.quit())
else:
super(GraphicsView, self).keyPressEvent(event)
def main():
app = QtGui.QApplication(sys.argv)
form = MyMainWindow()
form.setGeometry(700, 100, 1050, 850)
form.show()
app.exec_()
if __name__ == '__main__':
main()
下面是一个工作示例,它有自己的drawFocusRect方法 焦点以两种方式表示: 1单击Qgraphicsitem,然后绘制边界矩形。 2将鼠标悬停在项目上方。激发时,笔样式将更改为点线,并在激发时转换回实线
#!d:/python27/python -u
import sys
from PyQt4 import QtGui, QtCore
class GraphicsItem(QtGui.QGraphicsItem):
"""
From the QT docs:
To write your own graphics item, you first create a subclass
of QGraphicsItem, and then start by implementing its two pure
virtual public functions: boundingRect(), which returns an estimate
of the area painted by the item, and paint(),
which implements the actual painting.
"""
# call constructor of GraphicsItem
def __init__(self, rect, pen, brush, tooltip='No tip here', parent=None):
# call constructor of QGraphicsItem
super(GraphicsItem, self).__init__()
self.setFlag(QtGui.QGraphicsItem.ItemIsMovable, True)
self.setFlag(QtGui.QGraphicsItem.ItemIsSelectable, True)
self.setFlag(QtGui.QGraphicsItem.ItemIsFocusable, True)
self.setAcceptsHoverEvents(True)
self.pen = pen
pw = self.pen.widthF()
self.brush = QtGui.QBrush(QtCore.Qt.blue)
self.brush = brush
self.setToolTip(tooltip)
self.parent = parent
self.rect = QtCore.QRectF(rect[0], rect[1], rect[2], rect[3])
self.focusrect = QtCore.QRectF(rect[0]-pw/2, rect[1]-pw/2,
rect[2]+pw, rect[3]+pw)
def mouseMoveEvent(self, event):
# move object
QtGui.QGraphicsItem.mouseMoveEvent(self, event)
def mousePressEvent(self, event):
# select object
# set item as topmost in stack
self.setZValue(self.parent.scene.items()[0].zValue() + 1)
self.setSelected(True)
QtGui.QGraphicsItem.mousePressEvent(self, event)
def boundingRect(self):
return self.rect
def paint(self, painter, option, widget):
painter.setBrush(self.brush)
painter.setPen(self.pen)
painter.drawEllipse(self.rect)
if self.isSelected():
self.drawFocusRect(painter)
def drawFocusRect(self, painter):
self.focusbrush = QtGui.QBrush()
self.focuspen = QtGui.QPen(QtCore.Qt.DotLine)
self.focuspen.setColor(QtCore.Qt.black)
self.focuspen.setWidthF(1.5)
painter.setBrush(self.focusbrush)
painter.setPen(self.focuspen)
painter.drawRect(self.focusrect)
def hoverEnterEvent(self, event):
self.pen.setStyle(QtCore.Qt.DotLine)
QtGui.QGraphicsItem.hoverEnterEvent(self, event)
def hoverLeaveEvent(self, event):
self.pen.setStyle(QtCore.Qt.SolidLine)
QtGui.QGraphicsItem.hoverLeaveEvent(self, event)
class MyMainWindow(QtGui.QMainWindow):
# call constructor of MyMainWindow
def __init__(self, parent=None):
# call constructor of QMainWindow
super(MyMainWindow, self).__init__(parent)
w = 1000
h = 800
self.scene = QtGui.QGraphicsScene(-w/2, -h/2, w, h)
self.view = QtGui.QGraphicsView()
# set QGraphicsView attributes
self.view.setRenderHints(QtGui.QPainter.Antialiasing |
QtGui.QPainter.HighQualityAntialiasing)
self.view.setViewportUpdateMode(QtGui.QGraphicsView.FullViewportUpdate)
self.view.setScene(self.scene)
# set central widget for the application
self.setCentralWidget(self.view)
# add items to the scene
self.addGraphicsItem((0, 0, 250, 250), 8.0, (255, 0, 0), (0, 0, 255), 'My first item')
self.addGraphicsItem((-250, -250, 300, 200), 4.0, (0, 0, 0), (255, 0, 100), 'My 2nd item')
self.addGraphicsItem((200, -200, 200, 200), 10.0, (0, 0, 255), (0, 255, 100), 'My 3rd item')
def addGraphicsItem(self, rect, pw, pc, bc, tooltip):
pen = QtGui.QPen(QtCore.Qt.SolidLine)
pen.setColor(QtGui.QColor(pc[0], pc[1], pc[2], 255))
pen.setWidth(pw)
brush = QtGui.QBrush(QtGui.QColor(bc[0], bc[1], bc[2], 255))
item = GraphicsItem(rect, pen, brush, tooltip, self)
self.scene.addItem(item)
def mousePressEvent(self, event):
#print 'from MainWindow'
pass
def keyPressEvent(self, event):
key = event.key()
if key == QtCore.Qt.Key_Escape:
sys.exit(QtGui.qApp.quit())
else:
super(GraphicsView, self).keyPressEvent(event)
def main():
app = QtGui.QApplication(sys.argv)
form = MyMainWindow()
form.setGeometry(700, 100, 1050, 850)
form.show()
app.exec_()
if __name__ == '__main__':
main()
为PyQt5更新
import sys
from PyQt5 import QtGui, QtCore, QtWidgets
class GraphicsItem(QtWidgets.QGraphicsItem):
"""
From the QT docs:
To write your own graphics item, you first create a subclass
of QGraphicsItem, and then start by implementing its two pure
virtual public functions: boundingRect(), which returns an estimate
of the area painted by the item, and paint(),
which implements the actual painting.
"""
# call constructor of GraphicsItem
def __init__(self, rect, pen, brush, tooltip='No tip here', parent=None):
# call constructor of QGraphicsItem
super(GraphicsItem, self).__init__()
self.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable, True)
self.setFlag(QtWidgets.QGraphicsItem.ItemIsSelectable, True)
self.setFlag(QtWidgets.QGraphicsItem.ItemIsFocusable, True)
self.setAcceptHoverEvents(True)
self.pen = pen
pw = self.pen.widthF()
self.brush = QtGui.QBrush(QtCore.Qt.blue)
self.brush = brush
self.setToolTip(tooltip)
self.parent = parent
self.rect = QtCore.QRectF(rect[0], rect[1], rect[2], rect[3])
self.focusrect = QtCore.QRectF(rect[0]-pw/2, rect[1]-pw/2,
rect[2]+pw, rect[3]+pw)
def mouseMoveEvent(self, event):
# move object
QtWidgets.QGraphicsItem.mouseMoveEvent(self, event)
def mousePressEvent(self, event):
# select object
# set item as topmost in stack
self.setZValue(self.parent.scene.items()[0].zValue() + 1)
self.setSelected(True)
QtWidgets.QGraphicsItem.mousePressEvent(self, event)
def boundingRect(self):
return self.rect
def paint(self, painter, option, widget=None):
painter.setBrush(self.brush)
painter.setPen(self.pen)
painter.drawEllipse(self.rect)
if self.isSelected():
self.drawFocusRect(painter)
def drawFocusRect(self, painter):
self.focusbrush = QtGui.QBrush()
self.focuspen = QtGui.QPen(QtCore.Qt.DotLine)
self.focuspen.setColor(QtCore.Qt.black)
self.focuspen.setWidthF(1.5)
painter.setBrush(self.focusbrush)
painter.setPen(self.focuspen)
painter.drawRect(self.focusrect)
def hoverEnterEvent(self, event):
self.pen.setStyle(QtCore.Qt.DotLine)
QtWidgets.QGraphicsItem.hoverEnterEvent(self, event)
def hoverLeaveEvent(self, event):
self.pen.setStyle(QtCore.Qt.SolidLine)
QtWidgets.QGraphicsItem.hoverLeaveEvent(self, event)
class MyMainWindow(QtWidgets.QMainWindow):
# call constructor of MyMainWindow
def __init__(self, parent=None):
# call constructor of QMainWindow
super(MyMainWindow, self).__init__(parent)
w = 1000
h = 800
self.scene = QtWidgets.QGraphicsScene(-w/2, -h/2, w, h)
self.view = QtWidgets.QGraphicsView()
# set QGraphicsView attributes
self.view.setRenderHints(QtGui.QPainter.Antialiasing |
QtGui.QPainter.HighQualityAntialiasing)
self.view.setViewportUpdateMode(QtWidgets.QGraphicsView.FullViewportUpdate)
self.view.setScene(self.scene)
# set central widget for the application
self.setCentralWidget(self.view)
# add items to the scene
self.addGraphicsItem((0, 0, 250, 250), 8.0, (255, 0, 0), (0, 0, 255), 'My first item')
self.addGraphicsItem((-250, -250, 300, 200), 4.0, (0, 0, 0), (255, 0, 100), 'My 2nd item')
self.addGraphicsItem((200, -200, 200, 200), 10.0, (0, 0, 255), (0, 255, 100), 'My 3rd item')
def addGraphicsItem(self, rect, pw, pc, bc, tooltip):
pen = QtGui.QPen(QtCore.Qt.SolidLine)
pen.setColor(QtGui.QColor(pc[0], pc[1], pc[2], 255))
pen.setWidth(pw)
brush = QtGui.QBrush(QtGui.QColor(bc[0], bc[1], bc[2], 255))
item = GraphicsItem(rect, pen, brush, tooltip, self)
self.scene.addItem(item)
def mousePressEvent(self, event):
#print 'from MainWindow'
pass
def main():
app = QtWidgets.QApplication(sys.argv)
form = MyMainWindow()
form.setGeometry(700, 100, 1050, 850)
form.show()
app.exec_()
if __name__ == '__main__':
main()
为PyQt5更新
import sys
from PyQt5 import QtGui, QtCore, QtWidgets
class GraphicsItem(QtWidgets.QGraphicsItem):
"""
From the QT docs:
To write your own graphics item, you first create a subclass
of QGraphicsItem, and then start by implementing its two pure
virtual public functions: boundingRect(), which returns an estimate
of the area painted by the item, and paint(),
which implements the actual painting.
"""
# call constructor of GraphicsItem
def __init__(self, rect, pen, brush, tooltip='No tip here', parent=None):
# call constructor of QGraphicsItem
super(GraphicsItem, self).__init__()
self.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable, True)
self.setFlag(QtWidgets.QGraphicsItem.ItemIsSelectable, True)
self.setFlag(QtWidgets.QGraphicsItem.ItemIsFocusable, True)
self.setAcceptHoverEvents(True)
self.pen = pen
pw = self.pen.widthF()
self.brush = QtGui.QBrush(QtCore.Qt.blue)
self.brush = brush
self.setToolTip(tooltip)
self.parent = parent
self.rect = QtCore.QRectF(rect[0], rect[1], rect[2], rect[3])
self.focusrect = QtCore.QRectF(rect[0]-pw/2, rect[1]-pw/2,
rect[2]+pw, rect[3]+pw)
def mouseMoveEvent(self, event):
# move object
QtWidgets.QGraphicsItem.mouseMoveEvent(self, event)
def mousePressEvent(self, event):
# select object
# set item as topmost in stack
self.setZValue(self.parent.scene.items()[0].zValue() + 1)
self.setSelected(True)
QtWidgets.QGraphicsItem.mousePressEvent(self, event)
def boundingRect(self):
return self.rect
def paint(self, painter, option, widget=None):
painter.setBrush(self.brush)
painter.setPen(self.pen)
painter.drawEllipse(self.rect)
if self.isSelected():
self.drawFocusRect(painter)
def drawFocusRect(self, painter):
self.focusbrush = QtGui.QBrush()
self.focuspen = QtGui.QPen(QtCore.Qt.DotLine)
self.focuspen.setColor(QtCore.Qt.black)
self.focuspen.setWidthF(1.5)
painter.setBrush(self.focusbrush)
painter.setPen(self.focuspen)
painter.drawRect(self.focusrect)
def hoverEnterEvent(self, event):
self.pen.setStyle(QtCore.Qt.DotLine)
QtWidgets.QGraphicsItem.hoverEnterEvent(self, event)
def hoverLeaveEvent(self, event):
self.pen.setStyle(QtCore.Qt.SolidLine)
QtWidgets.QGraphicsItem.hoverLeaveEvent(self, event)
class MyMainWindow(QtWidgets.QMainWindow):
# call constructor of MyMainWindow
def __init__(self, parent=None):
# call constructor of QMainWindow
super(MyMainWindow, self).__init__(parent)
w = 1000
h = 800
self.scene = QtWidgets.QGraphicsScene(-w/2, -h/2, w, h)
self.view = QtWidgets.QGraphicsView()
# set QGraphicsView attributes
self.view.setRenderHints(QtGui.QPainter.Antialiasing |
QtGui.QPainter.HighQualityAntialiasing)
self.view.setViewportUpdateMode(QtWidgets.QGraphicsView.FullViewportUpdate)
self.view.setScene(self.scene)
# set central widget for the application
self.setCentralWidget(self.view)
# add items to the scene
self.addGraphicsItem((0, 0, 250, 250), 8.0, (255, 0, 0), (0, 0, 255), 'My first item')
self.addGraphicsItem((-250, -250, 300, 200), 4.0, (0, 0, 0), (255, 0, 100), 'My 2nd item')
self.addGraphicsItem((200, -200, 200, 200), 10.0, (0, 0, 255), (0, 255, 100), 'My 3rd item')
def addGraphicsItem(self, rect, pw, pc, bc, tooltip):
pen = QtGui.QPen(QtCore.Qt.SolidLine)
pen.setColor(QtGui.QColor(pc[0], pc[1], pc[2], 255))
pen.setWidth(pw)
brush = QtGui.QBrush(QtGui.QColor(bc[0], bc[1], bc[2], 255))
item = GraphicsItem(rect, pen, brush, tooltip, self)
self.scene.addItem(item)
def mousePressEvent(self, event):
#print 'from MainWindow'
pass
def main():
app = QtWidgets.QApplication(sys.argv)
form = MyMainWindow()
form.setGeometry(700, 100, 1050, 850)
form.show()
app.exec_()
if __name__ == '__main__':
main()
通过这种方式,您可以选择如何对焦,因为您可以使用painter.drawRect或任何您想要的工具。干得好顺便说一句,我意识到boundingRect方法需要给出项目的外部边界,但可能不是绘图。再次感谢。我会把它设为focusrect。这取决于你,self.rect是正确的。例如,您可以在以后的代码中使用boundingRect来对齐对象,这样您就可以决定如何定义它。哦,现在我看到了对我第一条评论的误解:我想说boundingRect方法不是用于绘制选择来回答主要问题,而是可能仅用于边界特征。无论如何。这样你就可以选择如何聚焦,因为你可以使用painter.drawRect或任何你想要的东西。干得好顺便说一句,我意识到boundingRect方法需要给出项目的外部边界,但可能不是绘图。再次感谢。我会把它设为focusrect。这取决于你,self.rect是正确的。例如,您可以在以后的代码中使用boundingRect来对齐对象,这样您就可以决定如何定义它。哦,现在我看到了对我第一条评论的误解:我想说boundingRect方法不是用于绘制选择来回答主要问题,而是可能仅用于边界特征。无论如何。这让我找到了我想要的。