Moving the Viewport in Qt: Alternatives to QGraphicsView::translate()


What it Does

  • In simpler terms, it allows you to move the displayed content within the view itself.
  • QGraphicsView::translate() is a function used to apply a translation transformation to the viewport of a QGraphicsView object.

How it Works

  • It takes two arguments, both floating-point numbers representing the horizontal and vertical distances to translate the view.
    • Positive values move the content to the right (for x) and down (for y).
    • Negative values move it to the left and up, respectively.

Points to Consider

  • Overriding Behavior
    To achieve a true translation effect, you can set the transformation anchor mode of the view to QGraphicsView::NoAnchor using setTransformationAnchor(QGraphicsView::NoAnchor). This prevents the view from automatically adjusting the center.
  • Default Behavior
    By default, QGraphicsView tries to maintain the center of the view during transformations. This might lead to the content not appearing to move as expected.

Alternative Approach

QGraphicsView* myView;
QPointF translation(10.0, 5.0); // Move 10 units right and 5 units down

QRectF oldSceneRect = myView->sceneRect();
QRectF newSceneRect = oldSceneRect.translated(-translation);

myView->setSceneRect(newSceneRect);

This approach translates the scene in the opposite direction, effectively achieving the desired view translation.



Example 1: Simple Translation with Anchor Mode Change (C++)

This code shows how to translate the view 20 pixels to the right and 10 pixels down, while also setting the anchor mode to NoAnchor to avoid unexpected behavior:

#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsRectItem>

int main(int argc, char *argv[]) {
  QApplication app(argc, argv);

  // Create scene and rectangle item
  QGraphicsScene scene;
  QGraphicsRectItem* rect = new QGraphicsRectItem(0, 0, 100, 50);
  scene.addItem(rect);

  // Create view and set scene
  QGraphicsView* view = new QGraphicsView;
  view->setScene(&scene);

  // Set transformation anchor to NoAnchor
  view->setTransformationAnchor(QGraphicsView::NoAnchor);

  // Translate the view
  view->translate(20.0, 10.0);

  view->show();

  return app.exec();
}

Example 2: Translating the Scene Rectangle (C++)

This code demonstrates translating the scene rectangle instead of using translate(). It achieves the same result without modifying the anchor mode:

#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsRectItem>

int main(int argc, char *argv[]) {
  QApplication app(argc, argv);

  // Create scene and rectangle item
  QGraphicsScene scene;
  QGraphicsRectItem* rect = new QGraphicsRectItem(0, 0, 100, 50);
  scene.addItem(rect);

  // Create view and set scene
  QGraphicsView* view = new QGraphicsView;
  view->setScene(&scene);

  // Get current scene rectangle
  QRectF sceneRect = view->sceneRect();

  // Translate the scene rectangle
  QRectF newSceneRect = sceneRect.translated(-15.0, -7.0); // Negative values for left/up movement

  // Set the new scene rectangle
  view->setSceneRect(newSceneRect);

  view->show();

  return app.exec();
}


Manipulating Scrollbars

  • Set their values by adding the desired translation amount to their current positions.
  • Access the horizontal and vertical scrollbars using horizontalScrollBar() and verticalScrollBar().
  • You can directly control the scrollbars of the QGraphicsView to achieve a similar effect as translation.
QGraphicsView* myView;
float translateX = 20.0; // Move 20 units right

// Get current scrollbar value
int currentScrollX = myView->horizontalScrollBar()->value();

// Update scrollbar value with translation
myView->horizontalScrollBar()->setValue(currentScrollX + translateX);

Using QGraphicsView::centerOn()

  • By repeatedly calling centerOn() with different positions, you can simulate a panning effect.
  • This function allows you to center the viewport on a specific item or point within the scene.
QGraphicsView* myView;
QGraphicsItem* targetItem;

// Move view to center on the target item
myView->centerOn(targetItem);

// Move view 10 units right by centering on a point 10 units to the right
myView->centerOn(targetItem->pos() + QPointF(10.0, 0));

Custom Transformations with QTransform

  • Create a QTransform object, set the translation using translate(), and apply it to the view with setTransform().
  • QTransform offers a more flexible approach for applying various transformations, including translation.
QGraphicsView* myView;
QTransform transform;

// Translate by 30 units right and 15 units down
transform.translate(30.0, 15.0);

// Apply the transformation to the view
myView->setTransform(transform);
  • Remember to adjust your approach based on the desired behavior and the complexity of your scene manipulation.
  • If you need more control over the transformation or require additional effects like scaling or rotation, consider using QTransform.
  • For simple translations, manipulating scrollbars or centerOn() might be sufficient.