调整 QGraphicsView 中项目的大小,我将代表顶点的子项目放到要移动的项目上(使用在构造函数中建立的父子关系)。就是下图中的四个蓝色圆圈:
但是子顶点没有接收到鼠标事件。只有父项(红色方 block )正在获取鼠标事件。
下面是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;
}
}
最佳答案
您说您的子项没有获得鼠标事件,但它们确实有。您可以通过向 Vertice 添加 void mousePressEvent(QGraphicsSceneMouseEvent * event)
并注意它正在被调用来验证这一点。
您的问题是 Qt 忽略了子 QGraphicsItem 上的 ItemIsMovable
标志。当您询问时,它甚至没有设置标志。
您可以通过更改顶点构造函数来验证这一点:
Vertice::Vertice(QGraphicsItem * parent) :
QGraphicsItem(parent)
{
setFlag(ItemIsMovable);
Q_ASSERT(flags() & ItemIsMovable); // fails
setFlag(ItemIsSelectable);
setFlag(ItemSendsGeometryChanges);
}
为什么会这样呢?正如编程绝地所说:“使用源代码,卢克!”
请注意,设置标志时它所做的其中一件事是它向 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);
...这就给你了。其他说明:
“顶点”的单数 is actually "Vertex"
如果您有这样的案例,请考虑将其从您正在编写的任何特定程序中删减。如果您可以用一个子项和一个父项来证明问题,那么为什么要用一个循环生成四个呢?如果选择不是问题的一部分——并且不需要涉及隐藏和显示顶点的代码——那么为什么要涉及它呢?最好使用您提供的代码来提供所需的虚拟方法,如
boundingRect()
而不是让其他人编写它来测试。参见 Short, Self-Contained, Compilable ExampleQt 源代码可读性强且组织良好,因此请养成查看它的习惯...!
关于c++ - 当设置 ItemIsMovable 标志时,子项在 QGraphicsView 中不可移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21745025/