我有一个 GraphicsBoxItem
,其中包含 GraphicsImageItem
列表(框周围的某种 float 按钮)。我在 focusInEvent()
中动态创建它们,并在 focusOutEvent()
中销毁它们。
一些 GraphicsImageItem
在单击时应随父项移动,其中一些应在单击时保持在同一位置,直到通过单击任何图形项外部而使框获得 focusOut。
有没有办法防止子 QGraphicsItem 与父级一起移动?
class GraphicsBoxItem : public QObject, public QGraphicsItem
{
Q_OBJECT
private:
QColor mColor;
QVector<GraphicsImageItem*> mItemList;
public:
GraphicsBoxItem(QGraphicsItem *parent = NULL)
:QGraphicsItem(parent)
{
mColor = Qt::lightGray;
setFlag(QGraphicsItem::ItemIsSelectable);
setFlag(QGraphicsItem::ItemIsFocusable);
}
QRectF boundingRect() const { return QRectF(50, 20, 100, 60); }
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
painter->setBrush(mColor);
painter->drawRect(boundingRect());
}
virtual void focusOutEvent(QFocusEvent * event)
{
foreach(GraphicsImageItem *item1, mItemList)
{
item1->deleteLater();
item1 = NULL;
}
mItemList.clear();
mColor = Qt::lightGray;
QGraphicsItem::focusOutEvent(event);
}
virtual void focusInEvent(QFocusEvent * event)
{
GraphicsImageItem *movableItem = new GraphicsImageItem(this);
movableItem->setPos(150, 20);
mItemList.push_back(movableItem);
movableItem->installSceneEventFilter(this);
connect(movableItem, SIGNAL(SignalClicked()), this, SLOT(SlotButtonClicked()));
GraphicsImageItem *nonMovableItem = new GraphicsImageItem(this);
nonMovableItem->setPos(20, 20);
mItemList.push_back(nonMovableItem);
nonMovableItem->installSceneEventFilter(this);
connect(nonMovableItem, SIGNAL(SignalClicked()), this, SLOT(SlotButtonClicked()));
mColor = Qt::blue;
QGraphicsItem::focusInEvent(event);
}
bool sceneEventFilter(QGraphicsItem* target, QEvent* event)
{
if(event->type() == QEvent::GraphicsSceneMousePress || event->type() == QEvent::GraphicsSceneMouseDoubleClick)
{
GraphicsImageItem* item = dynamic_cast<GraphicsImageItem*>(target);
if(item)
{
item->SignalClicked();
qDebug() << "image button was clicked: Need to set the focus back to the box";
setFocus();
return true;
}
}
return QGraphicsItem::sceneEventFilter(target, event);
}
public slots:
void SlotButtonClicked()
{
setPos(pos().x() + 10, pos().y()+10);
}
};
SignalClicked()
将 GraphicsBoxItem
移动 10 个像素。一些 GraphicsImageItem
保持原样,一些随 GraphicsBoxItem
移动:
class GraphicsImageItem : public QGraphicsSvgItem
{
Q_OBJECT
public:
GraphicsImageItem::GraphicsImageItem(QGraphicsItem *parent = NULL)
: QGraphicsSvgItem(QString(":/images/icon.svg"), parent)
{
setFlag(QGraphicsItem::ItemIsSelectable);
}
QRectF boundingRect() const { return QRectF(0, 0, 30, 30); }
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
painter->setBrush(Qt::lightGray);
painter->drawRect(boundingRect());
renderer()->render(painter, boundingRect().adjusted(3, 3, -3, -3));
}
Q_SIGNALS:
void SignalClicked();
};
最佳答案
子级的位置始终相对于其父级,如果父级移动,则子级的绝对位置也会发生变化。
如果您想制造这种情况不会发生的错觉,则必须手动将子项向相反方向移动,以便它可以保持在相同的绝对位置。
另一种选择是首先不将这些项目作为子项。
也许您应该创建一个不可见的项目,然后将可移动项目及其不可移动子项目作为其父级,并将可移动子项目设置为可移动项目的父级。然后,您只需移动可移动的项目 - 它的子项目移动,其兄弟项目保持在相同位置,因为它们的父项目不移动。
关于c++ - 如何防止子 QGraphicsItem 与父级一起移动?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49239168/