要调整QGraphicsView中项目的大小,我将表示顶点的子项放在要移动的项上(使用构造函数中建立的父子关系)。这些是下图中的四个蓝色圆圈:
但是子顶点没有接收鼠标事件。只有父项(红色方块)才能获得鼠标事件。
以下是Item
的定义:
Item::Item(QGraphicsItem * parent) :
QGraphicsItem(parent)
{
setFlag(ItemIsMovable);
setFlag(ItemIsSelectable);
setFlag(ItemSendsGeometryChanges);
setCacheMode(DeviceCoordinateCache);
}
void Item::paint(
QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
painter->fillRect(option->rect,Qt::red);
}
QVariant Item::itemChange(GraphicsItemChange change, const QVariant & value)
{
switch(change)
{
case QGraphicsItem::ItemSelectedHasChanged:
qWarning() << "item: " + value.toString();
updateVertices(value.toBool());
break;
default:
break;
}
return QGraphicsItem::itemChange(change, value);
}
void Item::updateVertices(bool visible) {
if(visible) {
if(vertices.length() == 0) {
for(int i = 0; i < 4; i++)
vertices.append(new Vertice(this));
} else
for(int i = 0; i < 4; i++)
vertices[i]->setVisible(true);
QRectF rect = boundingRect();
vertices[0]->setPos(rect.topLeft());
vertices[1]->setPos(rect.topRight());
vertices[2]->setPos(rect.bottomLeft());
vertices[3]->setPos(rect.bottomRight());
} else {
for(int i = 0; i < 4; i++) {
p_vertices[i]->setVisible(false);
}
}
}
虽然这里是Vertice
的定义:
Vertice::Vertice(QGraphicsItem * parent) :
QGraphicsItem(parent)
{
setFlag(ItemIsMovable);
setFlag(ItemIsSelectable);
setFlag(ItemSendsGeometryChanges);
}
void Vertice::paint(
QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
painter->setBrush(Qt::blue);
painter->setPen(Qt::darkGray);
painter->drawEllipse(-5,-5,10,10);
}
QVariant Vertice::itemChange(GraphicsItemChange change, const QVariant & value)
{
switch(change) {
case QGraphicsItem::ItemSelectedHasChanged:
qWarning() << "vertex: " + value.toString(); // never happened
break;
default:
break;
}
}
答案 0 :(得分:4)
你说你的孩子没有得到鼠标事件,但他们是。您可以通过向Vertice添加void mousePressEvent(QGraphicsSceneMouseEvent * event)
并注意到它已被调用来验证这一点。
你的问题是Qt忽略了孩子QGraphicsItem上的ItemIsMovable
标志。你问的时候甚至没有设置旗帜。
您可以通过更改Vertice构造函数来验证这一点:
Vertice::Vertice(QGraphicsItem * parent) :
QGraphicsItem(parent)
{
setFlag(ItemIsMovable);
Q_ASSERT(flags() & ItemIsMovable); // fails
setFlag(ItemIsSelectable);
setFlag(ItemSendsGeometryChanges);
}
现在为什么会这样?正如编程Jedi所说:&#34;使用来源,Luke!&#34;
请注意,设置标志时它所执行的操作之一就是itemChange
通过ItemFlagsChange
通知进行检查。不仅如此,它还允许标志被该调用的结果覆盖。但是看看你在Vertice上的itemChange()的实现:
QVariant Vertice::itemChange(GraphicsItemChange change, const QVariant & value)
{
switch(change) {
case QGraphicsItem::ItemSelectedHasChanged:
qWarning() << "vertex: " + value.toString(); // never happened
break;
default:
break;
}
}
糟糕,没有退货结果!将此行添加到最后,就像在项目中一样:
return QGraphicsItem::itemChange(change, value);
......你有它。其他说明:
Singular of&#34; Vertices&#34; is actually "Vertex"
如果您有这样的案例,请考虑从您正在编写的任何特定程序中删除它。如果您可以使用一个子项和一个父项来演示问题,那么为什么要创建四个循环呢?如果选择不是问题的一部分 - 并且不需要涉及隐藏和显示顶点的代码 - 那么为什么要涉及呢?使用您提供的代码来提供所需的虚拟方法(如boundingRect()
)而不是让其他人编写它来进行测试会好得多。请参阅Short, Self-Contained, Compilable Example
Qt源码具有相当的可读性和组织性,所以要养成查看它的习惯......!