シーングラフ - ペイント済みアイテム
QPainter に基づくカスタムシーングラフアイテムの実装方法を説明します。
「Painted Item」の例では、QML シーングラフフレームワークを使用して、QPainter を用いたカスタムシーングラフアイテムを実装する方法を示しています。

QQuickPaintedItem クラスは、QPainter インターフェースを使用してカスタムQMLシーングラフアイテムを実装するために、QQuickItem から派生したクラスです。
この例は、アイテムクラスと、そのアイテムを使用するためのQMLファイルで構成されています。TextBalloon クラスは、QQuickPaintedItem を拡張した個々のテキストバルーンを表しており、textballoons.qml ファイルは、TextBalloon QMLタイプを含むモジュールを読み込み、テキストバルーンを表示するために使用されます。
まずはTextBalloon クラスに焦点を当て、その後textballoons.qml ファイルについて説明します。QMLモジュール用のプラグインを実装する方法の例については、「拡張プラグインの作成」を参照してください。
TextBalloonクラスの宣言
TextBalloon クラスはQQuickPaintedItem から派生しています。QQuickPaintedItem は、QMLシーングラフフレームワークにおけるすべてのQPainter ベースのアイテムの基底クラスです。
class TextBalloon : public QQuickPaintedItem
{
Q_OBJECT
Q_PROPERTY(bool rightAligned READ isRightAligned WRITE setRightAligned NOTIFY rightAlignedChanged)
QML_ELEMENT
public:
TextBalloon(QQuickItem *parent = nullptr);
void paint(QPainter *painter) override;
bool isRightAligned() const;
void setRightAligned(bool rightAligned);
private:
bool rightAligned;
signals:
void rightAlignedChanged();
};QQuickPaintedItem を実装するには、QQuickPaintedItemの純粋仮想関数paint()を実装する必要があります。この関数は、そのタイプの描画処理を実装するものです。
TextBalloonクラスの定義
TextBalloon アイテムでは、rightAligned プロパティを必ず初期化する必要があります。
TextBalloon::TextBalloon(QQuickItem *parent)
: QQuickPaintedItem(parent)
, rightAligned(false)
{
}次に、シーングラフフレームワークによって自動的に呼び出され、アイテムの内容を描画するpaint() 関数を実装します。この関数は、ローカル座標系でアイテムを描画します。
void TextBalloon::paint(QPainter *painter)
{
QBrush brush(QColor("#007430"));
painter->setBrush(brush);
painter->setPen(Qt::NoPen);
painter->setRenderHint(QPainter::Antialiasing);
QSizeF itemSize = size();
painter->drawRoundedRect(0, 0, itemSize.width(), itemSize.height() - 10, 10, 10);
if (rightAligned)
{
const QPointF points[3] = {
QPointF(itemSize.width() - 10.0, itemSize.height() - 10.0),
QPointF(itemSize.width() - 20.0, itemSize.height()),
QPointF(itemSize.width() - 30.0, itemSize.height() - 10.0),
};
painter->drawConvexPolygon(points, 3);
}
else
{
const QPointF points[3] = {
QPointF(10.0, itemSize.height() - 10.0),
QPointF(20.0, itemSize.height()),
QPointF(30.0, itemSize.height() - 10.0),
};
painter->drawConvexPolygon(points, 3);
}
}まず、アイテムの外観を定義するために、アイテムのペンとブラシを設定します。その後、描画を開始します。なお、contentsBoundingRect() 関数は、アイテムのサイズに応じて描画を行うために呼び出されます。contentsBoundingRect() 関数が返す矩形は、QML ファイルで定義されたアイテムのサイズです。
textballoons.qml ファイル
インターフェースは、主に2つの部分で構成されています。テキストバルーンが表示されるスクロール可能な領域と、新しいバルーンを追加するためのコントロールボタンです。
BalloonView
ListModel {
id: balloonModel
ListElement {
balloonWidth: 200
}
ListElement {
balloonWidth: 120
}
}
ListView {
id: balloonView
anchors.bottom: controls.top
anchors.bottomMargin: 2
anchors.top: parent.top
delegate: TextBalloon {
anchors.right: index % 2 !== 0 ? parent?.right : undefined
height: 60
rightAligned: index % 2 !== 0
width: balloonWidth
}
model: balloonModel
spacing: 5
width: parent.width
}balloonModel には、アプリケーション起動時に balloonView によって表示される 2 種類のアイテムが含まれています。balloonView は、TextBalloon デリゲートアイテムの配置を左揃えと右揃えの間で交互に切り替えます。
コントロール
Rectangle {
id: controls
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.margins: 1
anchors.right: parent.right
border.width: 2
color: "white"
height: parent.height * 0.15
Text {
anchors.centerIn: parent
text: qsTr("Add another balloon")
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
onClicked: {
balloonModel.append({"balloonWidth": Math.floor(Math.random() * 200 + 100)})
balloonView.positionViewAtIndex(balloonView.count -1, ListView.End)
}
onEntered: {
parent.color = "#8ac953"
}
onExited: {
parent.color = "white"
}
}
}UIのコントロール部分には、マウスをホバーさせると色が変わるMouseArea を持つ矩形が含まれています。この「ボタン」と呼ばれるコントロールは、ランダムな幅を持つ新しいオブジェクトをモデルの末尾に追加します。
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.