Принуждение QGraphicsItem оставаться на месте

У меня есть QGraphicsScene, заполненный QGraphicsItems, и пользователь может перемещаться и масштабировать, чтобы проверить все различные QGraphicsItems. Однако я хотел бы, чтобы метка QGraphicsTextItem всегда оставалась в левом верхнем углу экрана. Игнорировать масштабы легко, так как я могу только setFlags(QGraphicsItem::ItemIgnoresTransformations), но мне еще предстоит выяснить, как заставить позицию оставаться в левом верхнем углу. Как лучше всего сделать так, чтобы мой ярлык «плавал» в одном и том же месте?


person rcv    schedule 29.04.2011    source источник
comment
см. также stackoverflow.com/questions/17373210/   -  person Trilarion    schedule 16.07.2014


Ответы (2)


Возможно, вы просто хотите поместить обычный QLabel прямо в представление вместо того, чтобы пытаться сделать так, чтобы часть сцены оставалась в одном месте, как описано в этот вопрос.

Примечание. Как упоминалось в другом ответе, этот трюк часто не работает с представлениями с аппаратным ускорением. В этих случаях вам нужно будет сделать текстовые элементы частью сцены.

person Arnold Spence    schedule 29.04.2011

Я думаю, что единственный (надежный) способ сделать это - пересчитывать позицию для вашего текстового элемента в каждом кадре. Для этого просто создайте подкласс QGraphicsView, переопределите paintEvent и используйте QGraphicsView::mapToScene() для вычисления новой позиции. Что-то типа:

void MyGraphicsView::paintEvent(QPaintEvent*)
{
    QPointF scenePos = mapToScene(0,0); // map viewport's top-left corner to scene
    m_textItem->setPos(scenePos);
}

Я делал это много раз, и это сработало очень хорошо.

Конечно, вы можете просто создать обычный QLabel, как упоминает Арнольд Спенс в своем ответе. Однако во многих ситуациях это не сработает (например, если вы действительно хотите поместить метку поверх графического представления и используете окно просмотра с ускорением OpenGL).

person user544511    schedule 29.04.2011
comment
Я думал об этом, но не вызовет ли вызов setPos обновление, которое вызовет событие paintEvent, которое вызовет setPos и ​​т. д.? - person rcv; 29.04.2011
comment
Нет, не будет. Попробуйте, и вы увидите :). - person user544511; 02.05.2011
comment
Вопрос, это требует от меня повторной реализации всего paintEvent для сцены? Я все еще хотел бы, чтобы все остальное в сцене вело себя как обычно. Вызов QGraphicsView::paintEvent() в начале моего пользовательского paintEvent(), а затем добавление моего дополнительного кода приводит к мерцанию, поскольку исходный paintEvent сначала устанавливает позицию, которую я затем устанавливаю в свою пользовательскую позицию. - person Man of One Way; 27.06.2013
comment
Это решение имеет плохие последствия для производительности и архитектуры. Индекс сцены необходимо обновлять каждый раз, когда вы перемещаете элемент. Вы также нарушаете парадигму модель-представление: представление постоянно взаимодействует с моделью. Хотя он будет работать с несколькими представлениями из-за последовательного характера обработки в потоке графического интерфейса, это просто счастливое совпадение. - person Kuba hasn't forgotten Monica; 26.08.2013