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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Масштабирование QGraphicsItem'ов  (Прочитано 6087 раз)
INZER
Гость
« : Март 11, 2015, 12:37 »

Есть вью с переопределнным событием вращения колесика мыши
Код:
void MapGraphicView::wheelEvent(QWheelEvent *event)
{
     if (event->delta() > 0)
        scale (1.1,1.1);
     else
        scale (1/1.1,1/1.1);
    event->accept();
}

На сцену добавляются элементы (QGraphicsPixmapItem, QGraphicsEllipseItem и др.)

Вопросы:
1) Как сделать так, чтобы QGraphicsPixmapItem не изменял свой масштаб?
2) Какие методы необходимо использовать, чтобы при крупном масштабе, когда появляются полосы прокрутки, прокручивать сцену, используя например перемещение мыши при зажатой левой кнопке

« Последнее редактирование: Март 11, 2015, 14:54 от INZER » Записан
INZER
Гость
« Ответ #1 : Март 11, 2015, 14:28 »

Вопрос с отменой масштабирования для избранных итемов открыт, направьте в нужную сторону.


Немного модифицировал масштабирование (изображение центрируется в точке нахождения указателя мыши).
Добавил прокрутку, при нажатии кнопки мыши.
Вдруг кому пригодится код ниже.

Код:
#include <QGraphicsView>

class MapGraphicView: public QGraphicsView
{
    Q_OBJECT
public:
    MapGraphicView(QWidget * pWgt = 0);
    MapGraphicView(QGraphicsScene * pScene, QWidget * pWgt = 0);
protected:
    QPointF center;                                 // The center of visible area
    QPointF fixedPoint;                             // Fixation point (for scrolling)
    void setCenter (const QPointF& centerPoint);
    QPointF getCenter ();
    virtual void mousePressEvent(QMouseEvent *event);
    virtual void mouseReleaseEvent(QMouseEvent *event);
    virtual void mouseMoveEvent(QMouseEvent *event);
    virtual void wheelEvent(QWheelEvent *event);
    virtual void resizeEvent (QResizeEvent *event);
};

MapGraphicView::MapGraphicView(QWidget * pWgt):
    QGraphicsView (pWgt)
{
    fixedPoint = QPoint ();
}


MapGraphicView::MapGraphicView(QGraphicsScene * pScene, QWidget * pWgt):
    QGraphicsView (pScene, pWgt)
{
    fixedPoint = QPoint ();
}

void MapGraphicView::setCenter(const QPointF &centerPoint)
{
    QRectF visibleArea = mapToScene(rect()).boundingRect();        
    QRectF sceneBounds = sceneRect();                              
    double boundX = visibleArea.width()/2.0;
    double boundY = visibleArea.height()/2.0;
    double boundWidth = sceneBounds.width() - visibleArea.width();
    double boundHeight = sceneBounds.height() - visibleArea.height();
    QRectF bounds (boundX, boundY, boundWidth, boundHeight);
    center = centerPoint;

    if (!bounds.contains(centerPoint))
    {
        if (visibleArea.contains(sceneBounds))
        {
            center = sceneBounds.center();
        }
        else
        {
            if (centerPoint.x() > bounds.x() + bounds.width())
                center.setX(bounds.x() + bounds.width());
            else if (center.x() < bounds.x())
                center.setX(bounds.x());

            if (centerPoint.y() > bounds.y() + bounds.height())
                center.setY(bounds.y() + bounds.height());
            else if (centerPoint.y() < bounds.y())
                center.setY(bounds.y());
        }
        centerOn(center);
    }
}

QPointF MapGraphicView::getCenter()
{
    return center;
}

void MapGraphicView::mousePressEvent(QMouseEvent *event)
{
    fixedPoint = event->pos();
}

void MapGraphicView::mouseReleaseEvent(QMouseEvent *event)
{
    fixedPoint = QPoint ();
}

void MapGraphicView::mouseMoveEvent(QMouseEvent *event)
{
    if (!fixedPoint.isNull())
    {
        QPointF offset = mapToScene(fixedPoint.toPoint()) - mapToScene(event->pos());
        fixedPoint = event->pos();
        setCenter(getCenter() + offset);
    }
}

void MapGraphicView::wheelEvent(QWheelEvent *event)
{
    QPointF pointBeforeScale (mapToScene(event->pos()));
    QPointF visibleCenter = getCenter();
    double scaleFactor = 1.2;
    if (event->delta() > 0)
        scale(scaleFactor, scaleFactor);
    else
        scale(1.0/scaleFactor, 1.0/scaleFactor);
    QPointF pointAfterScale(mapToScene(event->pos()));
    QPointF offset = pointBeforeScale - pointAfterScale;
    QPointF newCenter = visibleCenter+offset;
    setCenter(newCenter);
    event->accept();
}

void MapGraphicView::resizeEvent(QResizeEvent *event)
{
    QRectF visibleArea = mapToScene(rect()).boundingRect();
    setCenter(visibleArea.center());
    QGraphicsView::resizeEvent(event);
}


« Последнее редактирование: Март 11, 2015, 14:32 от INZER » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Март 11, 2015, 14:39 »

Никогда не пользовался QGraphicsScene (может там уже это давно решено), но рисовать приходилось немало, поэтому присоединяюсь к вопросу: а как быть с "немасштабируемыми" айтемами, такие найдутся (стрелочки координатных осей, надписи и.т.п.)?
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #3 : Март 11, 2015, 15:05 »

Код
C++ (Qt)
QGraphicsItem::setFrag( QGraphicsItem::ItemIgnoresTransformations );
Записан

Qt 5.11/4.8.7 (X11/Win)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Март 11, 2015, 15:21 »

Код
C++ (Qt)
QGraphicsItem::setFrag( QGraphicsItem::ItemIgnoresTransformations );
Вот он, идеальный ответ! (выжимка из букваря Улыбающийся) Однако
Цитировать
The item ignores inherited transformations (i.e., its position is still anchored to its parent, but the parent or view rotation, zoom or shear transformations are ignored). This flag is useful for keeping text label items horizontal and unscaled, so they will still be readable if the view is transformed. When set, the item's view geometry and scene geometry will be maintained separately. You must call deviceTransform() to map coordinates and detect collisions in the view. By default, this flag is disabled. This flag was introduced in Qt 4.3.
А как же с вращением? Напр стрелочки (аттач) поворачиваться должны
Записан
INZER
Гость
« Ответ #5 : Март 11, 2015, 15:27 »

Да, итем остается неизменным при масштабировании, однако, при изменении масштаба, он меняет свое положение относительно других итемов.
Видимо, нужно уменьшить/увеличить его координаты на величину скороллинга и, соответственно, сообщить ему, что координаты нужно пересчитать ...... буду курить тему дальше.
Спасибо за направление в нужную сторону!
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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