Qt Widgetsでアイテムを特定の点を中心に回転させる:QGraphicsRotation::originの使い方とサンプルコード


QGraphicsRotation クラスは、Qt Widgets モジュールにおいて、2D グラフィックスアイテムを指定された軸を中心に回転させるための機能を提供します。origin プロパティは、回転の中心となる点を定義します。

origin プロパティ

origin プロパティは、QPointF 型の値で、回転の中心となる点の X 座標と Y 座標を指定します。デフォルト値は (0, 0) で、これはアイテムの左上角になります。

origin プロパティを設定する例

QGraphicsRotation rotation;
rotation.setOrigin(QPointF(50, 25));

上記のコードは、回転の中心点をアイテムの左上から (50, 25) に変更します。

origin プロパティの影響

origin プロパティを設定すると、アイテムの回転動作が以下のように変化します。

  • アイテムの形状とサイズが回転の影響を受けません。例えば、正方形のアイテムを origin を中心に回転しても、回転後も正方形のままです。
  • 回転の中心となる点が固定されます。つまり、アイテム全体が回転しても、origin で指定された点は常に同じ位置に留まります。

origin プロパティの活用例

origin プロパティは、アイテムを特定の点を中心に回転させたい場合に役立ちます。例えば、以下の例では、アイテムをボタンの中心を中心に回転させています。

QPushButton* button = new QPushButton("Rotate");
QGraphicsItem* item = new QGraphicsPixmapItem(QPixmap("image.png"));

item->setParentItem(scene);
item->setPos(button->pos());

QGraphicsRotation rotation;
rotation.setOrigin(button->center());
item->setTransform(rotation);

上記のコードでは、ボタンがクリックされたときに、itemorigin を中心に 90 度回転するように設定されています。

QGraphicsRotation::origin プロパティは、Qt Widgets モジュールにおいて、2D グラフィックスアイテムの回転動作を制御するための重要な要素です。origin プロパティを設定することで、アイテムを特定の点を中心に回転させたり、回転の影響を受けない部分を固定したりすることができます。



例1:ボタンの中心を中心にアイテムを回転させる

#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QPushButton>
#include <QGraphicsPixmapItem>
#include <QGraphicsRotation>

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

  // シーンとビューを作成
  QGraphicsScene scene;
  QGraphicsView view(&scene);
  view.resize(400, 300);

  // ボタンとアイテムを作成
  QPushButton* button = new QPushButton("Rotate");
  QGraphicsPixmapItem* item = new QGraphicsPixmapItem(QPixmap("image.png"));

  // アイテムをシーンに追加
  item->setParentItem(scene);
  item->setPos(button->pos());

  // 回転オブジェクトを作成
  QGraphicsRotation rotation;

  // 回転の中心点をボタンの中心に設定
  rotation.setOrigin(button->center());

  // アイテムを回転
  item->setTransform(rotation);

  // ボタンをクリックしたときにアイテムを回転させる
  QObject::connect(button, &QPushButton::clicked, [&]() {
    rotation.setAngle(rotation.angle() + 90);
    item->setTransform(rotation);
  });

  // ビューを表示
  view.show();

  return app.exec();
}

例2:アイテムを固定点を中心に回転させる

#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsPixmapItem>
#include <QGraphicsRotation>

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

  // シーンとビューを作成
  QGraphicsScene scene;
  QGraphicsView view(&scene);
  view.resize(400, 300);

  // アイテムを作成
  QGraphicsPixmapItem* item = new QGraphicsPixmapItem(QPixmap("image.png"));

  // アイテムをシーンに追加
  item->setParentItem(scene);
  item->setPos(100, 100);

  // 回転オブジェクトを作成
  QGraphicsRotation rotation;

  // 回転の中心点を固定点に設定
  rotation.setOrigin(QPointF(200, 150));

  // アイテムを回転
  item->setTransform(rotation);

  // 回転角度をアニメーションで変化させる
  QPropertyAnimation* animation = new QPropertyAnimation(rotation, "angle");
  animation->setDuration(2000);
  animation->setStartValue(0);
  animation->setEndValue(360);
  animation->setLoopCount(-1); // 無限ループ
  animation->start();

  // ビューを表示
  view.show();

  return app.exec();
}

上記はあくまで基本的な例です。実際のアプリケーションでは、必要に応じてコードを修正・拡張する必要があります。

  • アイテムのサイズや位置は、必要に応じて調整してください。


QTransform を直接使用する

QGraphicsRotation クラスは内部的に QTransform クラスを使用して回転処理を行っていますが、QTransform クラスを直接使用することで、より柔軟な回転制御が可能になります。

利点

  • 回転軸を任意の方向に設定できます。
  • 回転の中心点を任意の座標に設定できます。
  • 回転だけでなく、スケーリングや移動などの他の変換操作を組み合わせることができます。

欠点

  • アイテムをシーンに追加する前に、QTransform を設定する必要があります。
  • QGraphicsRotation クラスよりも複雑なコードが必要になります。

QTransform transform;
transform.rotate(45, Qt::YAxis);
transform.translate(-50, -25); // 回転の中心点を (50, 25) に設定

QGraphicsPixmapItem* item = new QGraphicsPixmapItem(QPixmap("image.png"));
item->setTransform(transform);

QGraphicsItem::setTransformOrigin() を使用する

QGraphicsItem::setTransformOrigin() メソッドは、アイテムの変換原点を設定します。変換原点は、アイテムが回転、スケーリング、移動されるときに基準となる点です。

利点

  • アイテムをシーンに追加した後でも、変換原点を設定できます。
  • QGraphicsRotation クラスよりもシンプルなコードで済みます。

欠点

  • 回転の中心点はアイテムの中心になります。
  • 回転軸は Y 軸に固定されます。

QGraphicsPixmapItem* item = new QGraphicsPixmapItem(QPixmap("image.png"));
item->setTransformOrigin(QPointF(-50, -25)); // 回転の中心点を (50, 25) に設定
item->rotate(45);

カスタムアイテムを作成する

回転処理を完全に制御したい場合は、カスタムアイテムを作成することができます。カスタムアイテムでは、独自の描画ルーチンと変換処理を実装することができます。

利点

  • 複雑な回転アニメーションを作成することができます。
  • 回転処理を完全に制御できます。

欠点

  • パフォーマンスが低下する可能性があります。
  • 複雑なプログラミングが必要になります。

class MyItem : public QGraphicsItem {
public:
  void paint(QPainter* painter, const QStyleOptionGraphics* option, QWidget* widget) override {
    // 描画処理
  }

  void transformEvent(QGraphicsItem* parentItem, QTransform* transform) override {
    // 回転処理
    transform->rotate(45, Qt::YAxis);
    transform->translate(-50, -25); // 回転の中心点を (50, 25) に設定
  }
};

最適な代替方法の選択

どの代替方法が最適かは、要件によって異なります。以下の点を考慮して選択してください。

  • パフォーマンス
  • コードの複雑さ
  • 回転制御の柔軟性