【Qt Widgets】QGraphicsDropShadowEffect::xOffsetで影を自在に操る


QGraphicsDropShadowEffect::xOffset は、Qt Widgetsライブラリで影効果を作成するために使用されるクラス QGraphicsDropShadowEffect のプロパティです。このプロパティは、影の水平方向オフセットをピクセル単位で設定します。デフォルト値は8ピクセルで、影は右下にオフセットされます。

使い方

xOffset プロパティを設定するには、以下のコードを使用します。

QGraphicsDropShadowEffect *effect = new QGraphicsDropShadowEffect(this);
effect->setXOffset(10); // 影を10ピクセル右にオフセットします

以下のコードは、影付きの四角形を描画する例です。

QGraphicsScene scene;
QGraphicsItem *item = new QGraphicsRectItem(QRectF(0, 0, 100, 100));

QGraphicsDropShadowEffect *effect = new QGraphicsDropShadowEffect(this);
effect->setColor(QColor(0, 0, 0, 128)); // 影の色を黒に設定します
effect->setBlurRadius(5); // 影のぼかし半径を5ピクセルに設定します
effect->setXOffset(10); // 影を10ピクセル右にオフセットします

item->setGraphicsEffect(effect);
scene->addItem(item);

QGraphicsView view(&scene);
view.show();

このコードを実行すると、黒い影付きの四角形がウィンドウに表示されます。影は四角形より10ピクセル右にオフセットされています。

  • offset プロパティを使用して、影のオフセットを QPointF オブジェクトで設定することもできます。
  • color プロパティを使用して、影の色を設定できます。
  • blurRadius プロパティを使用して、影のぼかし半径を設定できます。
  • yOffset プロパティを使用して、影の垂直方向オフセットを設定することもできます。
  • この説明は、Qt Widgets 6.7.2 を使用しています。他のバージョンでは、プロパティ名やメソッド名が異なる場合があります。


#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsItem>
#include <QGraphicsDropShadowEffect>

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

  // シーンを作成
  QGraphicsScene scene;

  // 四角形アイテムを作成
  QGraphicsItem *item = new QGraphicsRectItem(QRectF(0, 0, 100, 100));

  // 影効果を作成
  QGraphicsDropShadowEffect *effect = new QGraphicsDropShadowEffect();
  effect->setColor(QColor(0, 0, 0, 128)); // 影の色を黒に設定
  effect->setBlurRadius(5); // 影のぼかし半径を5ピクセルに設定
  effect->setXOffset(10); // 影を10ピクセル右にオフセット

  // アイテムに影効果を設定
  item->setGraphicsEffect(effect);

  // シーンにアイテムを追加
  scene.addItem(item);

  // ビューを作成
  QGraphicsView view(&scene);
  view.show();

  return app.exec();
}

影付きテキストを描画

この例では、影付きのテキストを描画します。

#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsItem>
#include <QGraphicsTextItem>
#include <QGraphicsDropShadowEffect>

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

  // シーンを作成
  QGraphicsScene scene;

  // テキストアイテムを作成
  QGraphicsTextItem *item = new QGraphicsTextItem("Qt Widgets");

  // 影効果を作成
  QGraphicsDropShadowEffect *effect = new QGraphicsDropShadowEffect();
  effect->setColor(QColor(0, 0, 0, 128)); // 影の色を黒に設定
  effect->setBlurRadius(5); // 影のぼかし半径を5ピクセルに設定
  effect->setXOffset(10); // 影を10ピクセル右にオフセット

  // アイテムに影効果を設定
  item->setGraphicsEffect(effect);

  // シーンにアイテムを追加
  scene.addItem(item);

  // ビューを作成
  QGraphicsView view(&scene);
  view.show();

  return app.exec();
}

影のオフセットを動的に変更

この例では、影のオフセットをタイマーを使用して動的に変更します。

#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsItem>
#include <QGraphicsRectItem>
#include <QGraphicsDropShadowEffect>
#include <QTimer>

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

  // シーンを作成
  QGraphicsScene scene;

  // 四角形アイテムを作成
  QGraphicsRectItem *item = new QGraphicsRectItem(QRectF(0, 0, 100, 100));

  // 影効果を作成
  QGraphicsDropShadowEffect *effect = new QGraphicsDropShadowEffect();
  effect->setColor(QColor(0, 0, 0, 128));
  effect->setBlurRadius(5);
  item->setGraphicsEffect(effect);

  // シーンにアイテムを追加
  scene.addItem(item);

  // ビューを作成
  QGraphicsView view(&scene);
  view.show();

  // タイマーを作成
  QTimer timer;
  timer.setInterval(100); // 100ミリ秒ごとにオフセットを更新

  int offset = 0;
  connect(&timer, &QTimer::timeout, [&] {
    // オフセットを更新
    effect->setXOffset(offset);

    // オフセットを反転
    offset = (offset + 1) % 20; // 0から19までの範囲でオフセットをループ
  });

  // タイマーを開始
  timer.start();

  return app.exec();
}


QTransform を使用する

QGraphicsItemQTransform を適用することで、影だけでなくアイテム自体をオフセットできます。これは、影をアイテムの中心からオフセットしたい場合や、影の方向を自由に変更したい場合に便利です。

QGraphicsItem *item = new QGraphicsRectItem(QRectF(0, 0, 100, 100));

QGraphicsDropShadowEffect *effect = new QGraphicsDropShadowEffect();
effect->setColor(QColor(0, 0, 0, 128));
effect->setBlurRadius(5);

QTransform transform;
transform.translate(10, 10); // アイテムを10ピクセル右下へオフセット
item->setGraphicsEffect(effect);
item->setTransform(transform);

カスタムシェーダーを使用する

より高度な制御が必要な場合は、カスタムシェーダーを使用して影をレンダリングできます。これは、複雑な形状の影を作成したり、影の色や不透明度をアニメーション化したりする場合に便利です。

QGraphicsShaderEffect *effect = new QGraphicsShaderEffect();

// シェーダープログラムを作成
QString fragmentShader = "precision highp float;\n"
                        "varying vec2 fragCoord;\n"
                        "uniform vec4 shadowColor;\n"
                        "uniform float blurRadius;\n"
                        "uniform float offsetX;\n"
                        "void main() {\n"
                        "    vec2 uv = fragCoord / vec2(textureSize(texture0));\n"
                        "    float distance = length(uv - vec2(0.5, 0.5) + vec2(offsetX, 0.0));\n"
                        "    float alpha = clamp(1.0 - distance / blurRadius, 0.0, 1.0);\n"
                        "    gl_FragColor = shadowColor * vec4(alpha);\n"
                        "}";

effect->setFragmentShader(fragmentShader);

// シェーダーパラメータを設定
effect->setUniform("shadowColor", QColor(0, 0, 0, 128));
effect->setUniform("blurRadius", 5.0f);
effect->setUniform("offsetX", 10.0f);

item->setGraphicsEffect(effect);

QPainter を使用する

QPainter を使用してカスタム描画コードを書くことで、影を直接描画することもできます。これは、より細かい制御が必要な場合や、影を他のグラフィック要素と組み合わせたい場合に便利です。

void paint(QPainter *painter, const QStyleOptionGraphics *option, QWidget *widget) {
  // 四角形を描画
  painter->drawRect(QRectF(0, 0, 100, 100));

  // 影を描画
  painter->save();
  painter->translate(10, 10); // 影を10ピクセル右下へオフセット
  painter->setOpacity(0.5);
  painter->fillRect(QRectF(0, 0, 100, 100), QColor(0, 0, 0));
  painter->restore();
}

別の影効果を使用する

QGraphicsDropShadowEffect 以外にも、影を作成するための効果がいくつかあります。これらの効果は、さまざまな形状やスタイルの影を作成するために使用できます。

  • QGraphicsCustomEffect:カスタムシェーダーを使用して影を作成します。
  • QGraphicsColorizeEffect:影の色を変更します。
  • QGraphicsBlurEffect:ぼかし効果を作成します。
  • さまざまな形状やスタイルの影が必要な場合は、別の影効果を使用する必要があります。
  • 影をより細かく制御したい場合は、QTransform、カスタムシェーダー、または QPainter を使用する必要があります。
  • 簡単でシンプルな方法が必要な場合は、QGraphicsDropShadowEffect::xOffset を使用するのが最善です。
  • [Qt 4.8: Q