我正在尝试创建一个可调整大小的QGraphicsRectItem,并带有一个选择不同绘制样式的选项。
如果我仅创建具有调整大小功能的简单矩形,那么它将按预期工作:
position: relative
当我尝试对其进行修改以更改笔的样式和颜色(如果处于活动状态)时,它将变得无法选择且无法聚焦。不仅如此,边界矩形意外消失。这是修改后的版本:
class Rectangle(QtWidgets.QGraphicsRectItem):
def __init__(self, x, y, w, h):
super(Rectangle, self).__init__(0, 0, w, h)
self.setPen(QtGui.QPen(QtCore.Qt.red, 2))
self.setFlags(QtWidgets.QGraphicsItem.ItemIsSelectable
| QtWidgets.QGraphicsItem.ItemIsMovable
| QtWidgets.QGraphicsItem.ItemIsFocusable
| QtWidgets.QGraphicsItem.ItemSendsGeometryChanges
| QtWidgets.QGraphicsItem.ItemSendsScenePositionChanges)
self.setPos(QtCore.QPointF(x, y))
self.rect = rect = QtCore.QRectF(0, 0, 200, 200)
def boundingRect(self):
return self.rect.adjusted(-10, -10, 10, 10)
def mouseMoveEvent(self, event):
if event.buttons() & QtCore.Qt.LeftButton:
super(Rectangle, self).mouseMoveEvent(event)
if event.buttons() & QtCore.Qt.RightButton:
self.rect = QtCore.QRectF(QtCore.QPoint(), event.pos()).normalized()
self.prepareGeometryChange()
self.setRect(self.rect)
我想主要问题在于重新实现的 paint()函数,但我仍然没有想出 其中 的任何想法...
有人可以解释我在做什么错吗? 哪里有错误以及如何使此功能正常运行?
答案 0 :(得分:2)
我的触摸板上没有中间按钮,因此我已经使用右键实现了逻辑,但是我给了10px的小边缘,您可以在其中更改矩形的大小。
要更改样式,只需更改QGraphicsItem的QPen。
import functools
from PyQt5 import QtCore, QtGui, QtWidgets
class Rectangle(QtWidgets.QGraphicsRectItem):
def __init__(self, x, y, w, h):
super(Rectangle, self).__init__(0, 0, w, h)
self.setPen(QtGui.QPen(QtCore.Qt.red, 2))
self.setFlags(QtWidgets.QGraphicsItem.ItemIsSelectable
| QtWidgets.QGraphicsItem.ItemIsMovable
| QtWidgets.QGraphicsItem.ItemIsFocusable
| QtWidgets.QGraphicsItem.ItemSendsGeometryChanges
| QtWidgets.QGraphicsItem.ItemSendsScenePositionChanges)
self.setPos(QtCore.QPointF(x, y))
def mouseMoveEvent(self, event):
if event.buttons() & QtCore.Qt.LeftButton:
super(Rectangle, self).mouseMoveEvent(event)
if event.buttons() & QtCore.Qt.RightButton:
rect = QtCore.QRectF(QtCore.QPoint(), event.pos()).normalized()
self.prepareGeometryChange()
self.setRect(rect)
def contextMenuEvent(self, event):
super(Rectangle, self).contextMenuEvent(event)
delta = 10
r = self.boundingRect()
r.adjust(delta, delta, -delta, -delta)
if not r.contains(event.pos()):
return
self.setSelected(True)
wrapped = []
menu = QtWidgets.QMenu(self.parentWidget())
for text, param in (("&Solid", QtCore.Qt.SolidLine),
("&Dashed", QtCore.Qt.DashLine),
("D&otted", QtCore.Qt.DotLine),
("D&ashDotted", QtCore.Qt.DashDotLine),
("DashDo&tDotten", QtCore.Qt.DashDotDotLine)):
wrapper = functools.partial(self.setStyle, param)
wrapped.append(wrapper)
menu.addAction(text, wrapper)
menu.exec_(event.screenPos())
def paint(self, painter, option, widget):
painter.setPen(self.pen())
painter.setBrush(self.brush())
if option.state & QtWidgets.QStyle.State_Selected:
pen = self.pen()
pen.setColor(QtCore.Qt.blue)
painter.setPen(pen)
painter.setBrush(QtCore.Qt.NoBrush)
painter.drawRect(self.boundingRect())
def setStyle(self, style):
pen = self.pen()
pen.setStyle(style)
self.setPen(pen)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
scene = QtWidgets.QGraphicsScene(-400, -400, 800, 800)
w = QtWidgets.QGraphicsView(scene)
scene.addItem(Rectangle(100, 100, 100, 100))
w.show()
sys.exit(app.exec_())