基本的なグラフィックレイアウトの例
基本的なグラフィックス・レイアウトの作成方法を示します。
基本的なグラフィック・レイアウトの例では、QGraphicsView のレイアウト・クラスの使い方を示しています :QGraphicsLinearLayout とQGraphicsGridLayout 。 それに加えて、独自のカスタム・レイアウト・アイテムの書き方も示しています。
ウィンドウ・クラスの定義
Window
クラスはQGraphicsWidget のサブクラスです。QGraphicsWidget parent をパラメータとするコンストラクタを持ちます。
class Window : public QGraphicsWidget { Q_OBJECT public: Window(QGraphicsWidget *parent = nullptr); };
ウィンドウ・クラスの実装
Window
のコンストラクタは、縦向きのQGraphicsLinearLayout オブジェクトwindowLayout
をインスタンス化します。windowLayout
を親とする別のQGraphicsLinearLayout オブジェクトlinear
をインスタンス化します。次に、LayoutItem
オブジェクトitem
を作成し、addItem() 関数でlinear
に追加します。また、item
にstretchFactor を追加します。
QGraphicsLinearLayout *windowLayout = new QGraphicsLinearLayout(Qt::Vertical); QGraphicsLinearLayout *linear = new QGraphicsLinearLayout(windowLayout); LayoutItem *item = new LayoutItem; linear->addItem(item); linear->setStretchFactor(item, 1);
このプロセスを繰り返す:
- 新しい
LayoutItem
を作成する、 linear
を追加します。- ストレッチ・ファクターを提供する。
item = new LayoutItem; linear->addItem(item); linear->setStretchFactor(item, 3); windowLayout->addItem(linear);
次に、linear
をwindowLayout
に追加し、2つのQGraphicsLinearLayout オブジェクトを入れ子にします。QGraphicsLinearLayout とは別に、QGraphicsGridLayout オブジェクト、grid
も使います。これは4x3のグリッドで、いくつかのセルは他の行にまたがっています。
以下のコード・スニペットに示すように、LayoutItem
オブジェクトを7つ作成し、addItem() 関数を使用してgrid
に配置します:
QGraphicsGridLayout *grid = new QGraphicsGridLayout(windowLayout); item = new LayoutItem; grid->addItem(item, 0, 0, 4, 1); item = new LayoutItem; item->setMaximumHeight(item->minimumHeight()); grid->addItem(item, 0, 1, 2, 1, Qt::AlignVCenter); item = new LayoutItem; item->setMaximumHeight(item->minimumHeight()); grid->addItem(item, 2, 1, 2, 1, Qt::AlignVCenter); item = new LayoutItem; grid->addItem(item, 0, 2); item = new LayoutItem; grid->addItem(item, 1, 2); item = new LayoutItem; grid->addItem(item, 2, 2); item = new LayoutItem; grid->addItem(item, 3, 2); windowLayout->addItem(grid);
grid
に追加した最初の項目は、左上のセルに配置され、4行にまたがる。次の2つの項目は2列目に配置され、2行にわたります。各項目のmaximumHeight() とminimumHeight() は、縦に展開しないように等しく設定されています。その結果、これらの項目はセルに垂直に収まりません。そこで、Qt::AlignVCenter を使って、セルの中央に縦に並ぶように指定する。
最後に、grid
自身がwindowLayout
に追加される。QGridLayout::addItem() と異なり、QGraphicsGridLayout::addItem() は引数に行と列を必要とし、どのセルにアイテムを配置するかを指定する。また、rowSpan
とcolumnSpan
の引数が省略された場合、デフォルトで1になります。
これらのアイテムはすべてwindowLayout
に追加されるため、作成するLayoutItem
それぞれに親を指定しないことに注意してください。アイテムをレイアウトに追加すると、レイアウトがインストールされているウィジェットに自動的にリペアレントされます。
setLayout(windowLayout);
setWindowTitle(tr("Basic Graphics Layouts Example"));
grid
を設定し、windowLayout
に追加したので、QGraphicsWidget::setLayout() を使用してwindowLayout
をウィンドウ・オブジェクトにインストールし、ウィンドウ・タイトルを設定します。
LayoutItemクラスの定義
LayoutItem
クラスはQGraphicsLayoutItem とQGraphicsItem のサブクラスです。 コンストラクタ、デストラクタ、および必要な再実装があります。QGraphicsLayoutItem を継承しているので、 {QGraphicsLayoutItem::setGeometry()}{setGeometry()} と {QGraphicsLayoutItem::sizeHint()}{sizeHint()} を再実装しなければなりません。さらに、QGraphicsItem を継承しているので、{QGraphicsItem::boundingRect()}{boundingRect()}と{QGraphicsItem::paint()}{paint()}を再実装しなければなりません。
class LayoutItem : public QGraphicsLayoutItem, public QGraphicsItem { public: LayoutItem(QGraphicsItem *parent = nullptr); // Inherited from QGraphicsLayoutItem void setGeometry(const QRectF &geom) override; QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const override; // Inherited from QGraphicsItem QRectF boundingRect() const override; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override; private: QPixmap m_pix; };
また、LayoutItem
クラスは、QPixmap のプライベート・インスタンスm_pix
を持っています。
LayoutItem クラスの実装
LayoutItem
のコンストラクタでは、m_pix
がインスタンス化され、block.png
画像がロードされます。
LayoutItem::LayoutItem(QGraphicsItem *parent) : QGraphicsLayoutItem(), QGraphicsItem(parent), m_pix(QPixmap(QLatin1String(":/images/block.png"))) { setGraphicsItem(this); }
Q_UNUSED ()マクロを使用することで、コンパイラが未使用のパラメータに関する警告を出さないようにしています。
void LayoutItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { Q_UNUSED(widget); Q_UNUSED(option); QRectF frame(QPointF(0, 0), geometry().size()); const QSize pmSize = m_pix.size(); QGradientStops stops;
paint()
関数の背後にある考え方は、背景の矩形を描画し、その後、pixmap の周囲に矩形を描画することです。
// paint a background rect (with gradient) QLinearGradient gradient(frame.topLeft(), frame.topLeft() + QPointF(200,200)); stops << QGradientStop(0.0, QColor(60, 60, 60)); stops << QGradientStop(frame.height() / 2 / frame.height(), QColor(102, 176, 54)); //stops << QGradientStop(((frame.height() + h)/2 )/frame.height(), QColor(157, 195, 55)); stops << QGradientStop(1.0, QColor(215, 215, 215)); gradient.setStops(stops); painter->setBrush(QBrush(gradient)); painter->drawRoundedRect(frame, 10.0, 10.0); // paint a rect around the pixmap (with gradient) QPointF pixpos = frame.center() - (QPointF(pmSize.width(), pmSize.height()) / 2); QRectF innerFrame(pixpos, pmSize); innerFrame.adjust(-4, -4, 4, 4); gradient.setStart(innerFrame.topLeft()); gradient.setFinalStop(innerFrame.bottomRight()); stops.clear(); stops << QGradientStop(0.0, QColor(215, 255, 200)); stops << QGradientStop(0.5, QColor(102, 176, 54)); stops << QGradientStop(1.0, QColor(0, 0, 0)); gradient.setStops(stops); painter->setBrush(QBrush(gradient)); painter->drawRoundedRect(innerFrame, 10.0, 10.0); painter->drawPixmap(pixpos, m_pix); }
boundingRect() を再実装すると、左上隅が (0,0) に設定され、そのサイズはレイアウト項目geometry() のサイズになります。これがペイントする領域です。
setGeometry()の再実装は、単にベースクラスの実装を呼び出すだけです。ただし、これによってboundingRectが変更されるので、prepareGeometryChange ()も呼び出す必要があります。最後に、geom.topLeft()
に従ってアイテムを移動します。
void LayoutItem::setGeometry(const QRectF &geom) { prepareGeometryChange(); QGraphicsLayoutItem::setGeometry(geom); setPos(geom.topLeft()); }
アイテムのサイズをpixmapより小さくしたくないので、m_pix
より大きいサイズヒントを返すようにします。また、アイテムがpixmapより小さくならないように、pixmapを拡大縮小することもできます。好ましいサイズは最小サイズのヒントと同じですが、最大サイズは大きな値に設定します。
QSizeF LayoutItem::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const { switch (which) { case Qt::MinimumSize: case Qt::PreferredSize: // Do not allow a size smaller than the pixmap with two frames around it. return m_pix.size() + QSize(12, 12); case Qt::MaximumSize: return QSizeF(1000,1000); default: break; } return constraint; }
©2024 The Qt Company Ltd. 本文書に含まれる文書の著作権は、それぞれの所有者に帰属します。 ここで提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。