У меня есть QGraphicsTextItem
объектов на QGraphicsScene
. Пользователь может масштабировать объекты QGraphicsTextItem
, перетаскивая углы. (Для этого я использую специальный «редактор преобразований».) Пользователь также может изменить размер QGraphicsTextItem
, изменив размер шрифта с панели свойств. То, что я хотел бы сделать, это унифицировать их так, что когда пользователь масштабирует объект, перетаскивая угол с помощью мыши, за кулисами он фактически вычисляет «Какой размер шрифта необходим, чтобы результирующий объект соответствовал целевому размеру и сохранял масштабный коэффициент при 1,0? "Рассчитать размер шрифта QGraphicsTextItem на основе шкалы
Что я делаю сейчас выпускающая масштаб объекта в обычном режиме с использованием QGraphicsItem::mouseMoveEvent
, а затем вызвав метод FinalizeMapScale
в QGraphicsItem::mouseReleaseEvent
когда масштаб мыши завершен. Затем этот метод должен изменить шрифт на соответствующий размер и установить масштаб на 1,0.
У меня есть решение, которое работает, но я не сумасшедший. Я относительно новичок в Qt и C++, поэтому буду благодарен за любые комментарии или исправления.
- Есть ли лучший способ архитектовать все это?
- Есть ли методы Qt, которые уже делают это?
- Является ли мой метод на правильном пути, но имеет некоторые ошибки Qt или C++?
Не стесняйтесь прокомментировать мой ответ ниже, представив свое собственное предпочтительное решение. Благодаря!
[EDIT] В соответствии с запросом в комментарии, здесь приведены основы масштабирующего кода. Мы фактически пошли в другом направлении, так что этот код (и код ниже) больше не используется. Этот код находится в методе mouseMoveEvent
, предварительно установив флаг «scaling_» в значение true в mousePressEvent
, если щелкнуть мышью в нижней правой «горячей точке». Обратите внимание, что этот код находится в декораторе QGraphicsItem, который содержит указатель на целевое масштабирование. Эта абстракция была необходима для нашего проекта, но, вероятно, это слишком много для большинства целей. не
void TransformDecorator::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
...
if (scaling_) {
QGraphicsItem *target_item = target_->AsQGraphicsItem();
target_item->setTransformOriginPoint(0.0, 0.0);
QPointF origin_scene = mapToScene(target_item->transformOriginPoint());
QPointF scale_position_scene = mapToScene(event->pos());
qreal unscaled_width = target_item->boundingRect().width();
qreal scale_x = (scale_position_scene.x() - origin_scene.x())/unscaled_width;
if (scale_x * unscaled_width < kMinimumSize) {
scale_x = kMinimumSize/unscaled_width;
}
target_item->setScale(scale_x);
} else {
QGraphicsObject::mouseMoveEvent(event);
}
}
Я думаю, вам может быть лучше с алгоритмом bisecting, который имеет нижнюю границу вашего текущего размера шрифта и как верхнюю границу что-то разумное. Тогда у вас должно быть решение O (log N) для некоторого N, зависящего от ваших данных. –
s/'while (true)'/'forever' / – leemes