PerfectVector
著者: Claire Yoon2 分で読める

QtでSVGを使う:レンダラーを選び、ファイルを確認する

QtでQSvgWidgetやQSvgRendererを使い、現在の機能対応を確認します。拡大縮小できる元データと、アプリ内の固定ラスター画像を区別します。

目次

Qt WidgetsアプリでSVGを使う場合、画像の表示にはQSvgWidgetから始めます。選んだ対象へ描画する必要がある場合はQSvgRendererを使います。固定サイズのQImageへ1回描くと、その後に表示するのはピクセルです。SVGを保持すれば、別サイズで再描画できます。Qtの描画ガイドは両方を説明しています。

まず方法を選び、その後画像を確認します。ブラウザーのプレビューは意図したデザインを見せますが、Qtがファイルのすべての機能に対応する証明ではありません。

SVGを編集する前に表示方法を選ぶ

作業出発点確認するもの
他のウィジェットの横に静止SVGを表示QSvgWidgetファイル読み込み、描画境界、比率
自分のウィジェットや画像へ描画painterとQSvgRenderer対象サイズと描画時期
個々のベクター点を編集画像エディターや別の編集実装編集可能な元形状と選択動作

QtはQSvgWidgetをSVG表示ウィジェットとして説明し、renderer()でレンダラーを公開します。ウィジェットはSvgWidgetsに属し、CMake依存関係はQt6::SvgWidgetsです。一般のSVGモジュールだけを追加する古い例より、クラスリファレンスが役立ちます。

SVGの表示はイラストエディターを作ることではありません。葉の移動、角の変形、離れた細部の色変更が必要なら、元マスターを別に保持します。

葉の概念画像から、ウィジェット描画と固定ラスター画像の方法へ分かれる図
2つの描画方法の図解です。後の描画や編集用にSVGを保持します。1つのサイズで作るQImageはラスターの結果です。実行したQtアプリの画像ではありません。

イラスト全体の前に小さな元データを試す

独自の描画をleaf.svgとして保存します。塗りの葉、明るい葉脈、離れたコーラルの円を使います。

<svg xmlns="http://www.w3.org/2000/svg" width="160" height="100" viewBox="0 0 160 100">
  <path d="M24 78C20 34 56 18 98 26C90 62 58 86 24 78Z" fill="#176b64"/>
  <path d="M28 74L78 38" fill="none" stroke="#fff6e8" stroke-width="5"/>
  <circle cx="126" cy="26" r="10" fill="#ec785e"/>
</svg>

横長のキャンバスは意図的です。葉が細長くなったなら、曲線を編集する前に縦横比の扱いを調べます。円が消えたなら、表示境界を確認し、読み込んだファイルを元データと比較します。クリッピングや効果に頼らず、分かりやすい細部を持つ小さな例です。

ファイル自体については、SVG形式のガイドが、ベクター形状とビットマップを含むSVGの入れ物を区別します。

最小のQt 6 Widgetsの例

main.cppを作ります。

#include <QApplication>
#include <QSvgRenderer>
#include <QSvgWidget>
 
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    if (argc != 2)
        return 1;
 
    QSvgWidget view;
    view.load(QString::fromLocal8Bit(argv[1]));
    if (!view.renderer()->isValid())
        return 2;
 
    view.renderer()->setAspectRatioMode(Qt::KeepAspectRatio);
    view.resize(400, 240);
    view.show();
    return app.exec();
}

SVGのファイル名をプログラム引数へ渡します。テスト中は絶対パスが適しています。終了コード1は1つのファイル名を受け取らなかった場合、2はレンダラーが有効な文書と報告しなかった場合です。このサンプルの選択で、QtのエラーコードAPIではありません。

isValid()は読み込んだ文書を確認します。見た目の承認テストではありません。明示的なKeepAspectRatioは比率の保持を要求します。QSvgRendererリファレンスが有効性確認と縦横比のモードを説明しています。

ソースの横に次のCMakeLists.txtを使います。

cmake_minimum_required(VERSION 3.16)
project(LeafPreview LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
 
find_package(Qt6 REQUIRED COMPONENTS Widgets Svg SvgWidgets)
add_executable(leaf_preview main.cpp)
target_link_libraries(leaf_preview PRIVATE Qt6::Widgets Qt6::Svg Qt6::SvgWidgets)

例は、アプリ用Widgets、表示ウィジェット用SvgWidgets、レンダラー呼び出し用Svgをリンクします。QtはレンダラーのSvgコンポーネントとSvgWidgetsコンポーネントを別々に示しています。

インストール済みのQt 6開発キットで設定・ビルドし、leaf.svgへのパスを指定してleaf_previewを実行します。これはドキュメントに基づくソース例です。ネイティブのQt環境でコンパイル・実行していません。採用前に対象システムで実際のビルドと画像を試してください。

ブラウザーと同じと想定せず、現在の対応を確認する

現在のQt SVGは、静的なSVG Tinyだけに制限されません。Qt 6.7から追加した要素は既定で解析し、Tiny機能だけに制限するオプションもあると説明しています。拡張機能リファレンスに対応する追加機能と制限があります。

具体的な境界の1つはclipPathで、同じページでは非対応としています。クリッピングに依存するファイルは、ブラウザーで正しくても元データを調べる必要があります。一部のマスクやフィルターには対応が記載されていますが、すべての効果や出力設定への対応を証明するものではありません。

単純な葉は正しく表示されるのに大きなイラストが違うなら、コピーを作り、疑わしい機能を1つずつ削除します。切り抜き画像は、クリッピング処理に依存せず、エディターで意図した可視形状を作る方法を検討します。マスターを置き換える前に、結果の輪郭を元と比較します。

文字には別の確認が必要です。文字が変わる場合は、SVGフォントの問題を調べるガイドを使います。文字を形状にするのはデザイン上の判断で、誤ったファイル名や不足モジュールの最初の修復にはしません。

SVGがピクセルになる段階を把握する

葉を小さなQImageへ1回描画し、そこからpixmapを作って、後で拡大するコードを考えます。拡大するのはラスター結果です。SVGは失われていなくても、その表示操作では新しい描画を要求していません。

Qtの描画ガイドは、画像への描画とウィジェットのpaintイベントでの描画を区別します。表示サイズが変わるなら、どこでSVGを再描画するか決めます。キャッシュしたビットマップを、元データが拡大縮小できない証拠としないでください。

SVGアイコン一式の準備でも同じ区別が重要です。元画像の描画境界をそろえ、実際の使用サイズで各アイコンを判断します。大きく見れば分かる葉でも、小さい表示では葉脈や離れた円が失われる場合があります。

すべてを簡略化する前に結果を確認する

似た名前の別出力ではなく、実際に読み込むファイルから始めます。単純な例が現れることを確認し、実際の画像を意図したサイズとリサイズ後で比較します。

葉では、円が分離し、葉脈が見え、横長のキャンバスで画像が伸びないか確認します。自分の実行の承認項目であり、こちらで報告した実行結果ではありません。全体が空なら、空白SVGの確認事項で、不可視画像や描画境界とアプリ設定を分けられます。

デザインに合う写真やテクスチャのイラストは、ラスター素材として保持します。SVGの選択は画像要件を解決するためのもので、ファイルの縮小、高速描画、エンジン間の同一出力を保証しません。

ラスターしかない場合は元マスターを復元する

アイコンがPNGやJPGだけなら、PerfectVectorの画像をベクターに変換する手順でQtへ渡す前に編集可能なSVGを準備できます。変換後の輪郭、隙間、離れた細部を確認し、選んだQtの方法で試します。ベクター化は形状を準備しますが、レンダラー機能を追加したり、表示ウィジェットをパスエディターにしたりはしません。

きれいなベクターマスターがあれば直接調整します。特定機能や小さいサイズの細部に必要な場合だけコピーを簡略化し、将来の編集用に詳細な元データを保持します。

よくある質問

QSvgWidgetとQSvgRendererのどちらを使うべきですか? WidgetsのUIで表示するにはQSvgWidgetを使います。カスタムウィジェットや画像など、選んだ対象への描画を制御するにはQSvgRendererを使います。

現在のQtはSVG Tinyだけに対応しますか? 静的なSVG Tinyに加え、Qt 6.7で導入した一部拡張を説明しています。Tinyだけ、あるいはブラウザーと同等と想定せず、現在の機能参照と設定を確認します。

pixmapへ入れるとSVGがぼやけるのはなぜですか? 先に固定サイズのラスターへ描画した場合、拡大するのはピクセルです。描画対象と、必要サイズでSVGを再描画するかを見直します。

有効なSVGの読み込みは、すべての細部が正しい証拠ですか? いいえ。有効性確認は目視確認の代わりではありません。実際の対象アプリで境界、比率、細部、対応機能を比較します。

参考資料

  1. Qt — SVGファイルの描画 — 表示ウィジェット、painter対象、ウィジェット描画とラスター中間物の区別。
  2. Qt — QSvgWidgetクラス — 表示ウィジェット、レンダラーアクセス、SvgWidgets依存関係。
  3. Qt — QSvgRendererクラス — Svg依存関係、文書有効性、縦横比設定。
  4. Qt — 拡張機能 — 現代の拡張と、非対応のクリッピングパスなどの制限。

小さなファイルを1つ使い、選んだQtの方法で確認します。ラスター復元が必要なら、編集可能なSVG候補を準備し、元データと形状を比較して、素材を置き換える前にアプリの確認を繰り返します。

ブログのその他の記事

編集しやすい
よりきれいなSVGから始めましょう