Russian Qt Forum
Ноябрь 02, 2024, 06:39 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: QGraphicsItem который бы не менял угол поворота при вызове QGraphicsView::rotate  (Прочитано 3749 раз)
vintik
Гость
« : Март 25, 2011, 00:41 »

Всем привет!
Вопрос к знатокам и любителям)
Задача - создание графического элемента(ГЭ) в виде прямоугольника, который бы при вращении на произвольный угол методом rotate класса QGraphicsView сохранял ориентацию в виджете-просмоторщике унаследованном от QGraphicsView.

Т.е. схема примерно следующая: создаю сцену, в ней размещаю этот самый графический элемент (горизонтально:длинной стороной вдоль нижней части экрана). Затем создаю виджет просмоторщик, у которого есть методы для масштабирования и поворота сцены на 5 градусов (QGraphicsView::rotate(5)). Вызов методов вешаю на кнопки . Назначаю этому просмоторщику ранее созданную сцену. Далее, жму кнопку масштабирования - ГЭ масштабируется, жму кнопку поворота, сцена поворачивается, вместе с ней ГЭ, но при этом он сохраняет свою горизонтальную ориентацию.

Такой ГЭ на базе QGraphicsRectItem и QObject сделать-таки удалось, работает исправно, но я уверен, что есть более элегантные решения. Реализовал примерно так:
1. В классе ГЭ есть слот для поворота вокруг центра прямоугольника на заданный угол
2. При нажатии кнопки поворота просмоторщика высылается сигнал для ГЭ со значением угла поворота (5)
3. Соответствующий слот ГЭ делает поворот на -5 градусов

Может быть не нужен огород со слотами и сигналами, а в QGraphicsItem есть метод, который бы вызывался каждый раз при QGraphicsView::rotate и при этом в таком методе можно было бы получить значение угла поворота из вида.
Или имеет смысл вообще свой итем замутить?
                                                                                    Спасибо

=====================================================================================================
вот такое решение получилось
Код:
class MyItem : public QAbstractGraphicsShapeItem {
  public:
    MyItem(QGraphicsItem *parent = 0);
    ~MyItem();
    virtual QRectF boundingRect() const;
    virtual void paint(QPainter* ppainter, const QStyleOptionGraphicsItem*, QWidget*);
private:
    QLineF line_prev;
    qreal angle;
};
// реализация
//--------------------------------------------------------------------------------
MyItem::MyItem(QGraphicsItem *parent) : QAbstractGraphicsShapeItem(parent) {
  angle = 0;
}
//--------------------------------------------------------------------------------
void MyItem::paint(QPainter* ppainter, const QStyleOptionGraphicsItem*, QWidget*) {
  ppainter->save();
  QTransform trans = ppainter->transform();
  QLineF line_cur = trans.map(QLineF(QPointF(0,0), QPointF(10,0)));
  qreal curAngle = line_prev.angleTo(line_cur);

  if(fabs(curAngle-360) < 1e-8 || fabs(curAngle) < 1e-8)
  {
    qDebug() << "ZOOM";
    ppainter->setTransform(trans.rotate(angle));
  }
  else
  {
    qDebug() << "ROTATE";
    angle = fmod(angle + curAngle, 360);
    ppainter->setTransform(trans.rotate(angle));
  }
  line_prev = line_cur;
 
  ppainter->setPen(QPen(Qt::green, 1));
  ppainter->drawLine(0,0,50,0);
  ppainter->setPen(QPen(Qt::red, 1));
  ppainter->drawLine(0,0,0,50);
  ppainter->restore();
}

и не большой коммент.
Для прорисовки итема используется метод paint. У него на входе есть указатель на объект класса рисовальщика QPainter.
По этому указателю можно получить матрицу текущего преобразования (ppainter->transform()Подмигивающий. С помощию неё можно получить точки в СК виджета-просмоторщика. Пусть линия имеет координаты (10,0) в СК итема. Переводим её в СК просмоторщика и сохраняем в line_prev. При очередном попадании в paint() переводим линию с координатами (10,0) в СК просмоторщика и сохраняем её в line_cur. Потом считаем угол между 2 линиями line_prev и line_cur(т.е. угол между линией до поворота и после). Далее используем полученный угол для "выравнивания" итема.
« Последнее редактирование: Апрель 01, 2011, 16:04 от vintik » Записан
Swa
Самовар
**
Offline Offline

Сообщений: 170


Просмотр профиля
« Ответ #1 : Март 25, 2011, 16:01 »

Попробуйте QGraphicsItem::setFlags(QGraphicsItem::ItemIgnoresTransformations)
Записан
vintik
Гость
« Ответ #2 : Март 25, 2011, 21:40 »

Попробуйте QGraphicsItem::setFlags(QGraphicsItem::ItemIgnoresTransformations)
Смотрел в сторону этого флага. Про него так написано:
Элемент игнорирует наследуемые преобразования (т.е. его позиция всё ещё связана с его родителем, но поворот, масштабирование или обрезание родителя или вида игнорируются). Этот флаг полезен для сохранения текстовой метки горизонтальной и немасштабированной, поэтому она будет читаема если вид преобразован. Если этот флаг установлен, геометрия вида элемента и сцены обрабатываются раздельно.

Т.е. масштабированию он не подвергается, а хотелось бы чтобы он масштабировался как и сцена(или родитель)
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.143 секунд. Запросов: 23.