问题
To resize items in a QGraphicsView, I'm putting child items representing vertices onto the item to be moved (using the parent-child relationship established in the constructor). Those are the four blue circles in the picture below:
But the child vertices are not receiving mouse events. Only the parent item (red square) is getting mouse events.
Here is the definition for 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);
}
}
}
While here is the definition for 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;
}
}
回答1:
You say that your child items aren't getting mouse events, but they are. You can verify this by adding a void mousePressEvent(QGraphicsSceneMouseEvent * event)
to Vertice and noticing that it is getting called.
Your problem is that Qt is ignoring the ItemIsMovable
flag on a child QGraphicsItem. It's not even setting the flag when you ask.
You can verify this by changing your Vertice constructor:
Vertice::Vertice(QGraphicsItem * parent) :
QGraphicsItem(parent)
{
setFlag(ItemIsMovable);
Q_ASSERT(flags() & ItemIsMovable); // fails
setFlag(ItemIsSelectable);
setFlag(ItemSendsGeometryChanges);
}
Now why would that be? As the programming Jedi say: "use the source, Luke!"
https://qt.gitorious.org/qt/qtbase/source/7df3321f934e5bd618e2ad00bf801f2b7edd31df:src/widgets/graphicsview/qgraphicsitem.cpp#L1789
Notice that one of the things it does when flags are set is it offers that to itemChange
to inspect with an ItemFlagsChange
notification. Not only that, but it allows the flags to be overwritten by the result of that call. But look at your implementation of itemChange() on Vertice:
QVariant Vertice::itemChange(GraphicsItemChange change, const QVariant & value)
{
switch(change) {
case QGraphicsItem::ItemSelectedHasChanged:
qWarning() << "vertex: " + value.toString(); // never happened
break;
default:
break;
}
}
Uh-oh. No return result! Add this line to the end, as you have in your Item:
return QGraphicsItem::itemChange(change, value);
...and there you have it. Other notes:
Singular of "Vertices" is actually "Vertex"
If you have a case like this, think about paring it down from whatever specific program you are writing. If you can demonstrate the problem with one child item and one parent item, then why have a loop making four? If selection isn't part of the problem--and code for hiding and showing vertices need not be involved--then why involve it? It would be much better to use the code you provide to give required virtual methods like
boundingRect()
rather than make others write it to test. See Short, Self-Contained, Compilable ExampleQt source is fairly readable and well-organized, so do get into the habit of looking at it...!
来源:https://stackoverflow.com/questions/21745025/child-items-not-movable-in-qgraphicsview-when-itemismovable-flag-is-set