ラスターウィンドウの例

この例では、レンダリングにQPainter を使用して、最小限のQWindow ベースのアプリケーションを作成する方法を示します。

アプリケーションのエントリーポイント

int main(int argc, char **argv)
{
    QGuiApplication app(argc, argv);

    RasterWindow window;
    window.show();

    return app.exec();
}

QWindow ベースのアプリケーションのエントリー・ポイントはQGuiApplication クラスです。このクラスはGUIアプリケーションの制御フローとメイン設定を管理します。コマンドライン引数を渡すことで、システム全体のオプションを指定することができます。

そこから、ウィンドウ・インスタンスを作成し、QWindow::show ()関数を呼び出して、ウィンドウ・システムにこのウィンドウを画面に表示するように指示します。

これが完了したら、アプリケーションのイベント・ループに入り、アプリケーションを実行できるようにします。

RasterWindowの宣言

#include <QtGui>
#include <QScopedPointer>

class RasterWindow : public QWindow
{
    Q_OBJECT
public:
    explicit RasterWindow(QWindow *parent = nullptr);

    virtual void render(QPainter *painter);

public slots:
    void renderLater();
    void renderNow();

protected:
    bool event(QEvent *event) override;

    void resizeEvent(QResizeEvent *event) override;
    void exposeEvent(QExposeEvent *event) override;

private:
    QScopedPointer<QBackingStore> m_backingStore;
};

まず、<QtGui> ヘッダーをインクルードします。これは、Qt GUIモジュールのすべてのクラスを使用できることを意味します。クラスは個別に含めることもできます。

RasterWindow クラスはQWindow を直接サブクラス化し、コンストラクタを提供して、ウィンドウを別のQWindow のサブウィンドウにすることができます。親を持たないQWindowはトップレベル・ウィンドウとしてウィンドウ・システムに表示されます。

このクラスはQBackingStore を宣言しています。これはQPainter ベースのグラフィックスのためにウィンドウのバック・バッファを管理するために使うものです。

ラスターウィンドウは他のいくつかの例でも再利用され、renderLater()のようないくつかのヘルパー関数が追加されています。

ラスターウィンドウの実装

RasterWindow::RasterWindow(QWindow *parent)
    : QWindow(parent)
    , m_backingStore(new QBackingStore(this))
{
    setGeometry(100, 100, 300, 200);
}

コンストラクタでバッキングストアを作成し、管理するウィンドウ・インスタンスを渡します。また、ウィンドウの初期ジオメトリを設定する。

void RasterWindow::exposeEvent(QExposeEvent *)
{
    if (isExposed())
        renderNow();
}

作成されたウィンドウでQWindow::show() を呼び出した直後に、仮想関数QWindow::exposeEvent() が呼び出され、ウィンドウ システムでのウィンドウの露出が変更されたことが通知されます。このイベントには露出されたサブ領域が含まれますが、ウィンドウ全体を毎回描画するため、このイベントは利用しません。

関数QWindow::isExposed()は、ウィンドウが表示されているかどうかを教えてくれる。ウィンドウ・システムでウィンドウが見えなくなったときにもexposeEventが呼び出されるので、これが必要です。ウィンドウが表示されている場合は、すぐにウィンドウを描画するために renderNow() を呼び出します。すぐに描画したいので、システムに視覚的なコンテンツを表示できます。

void RasterWindow::resizeEvent(QResizeEvent *resizeEvent)
{
    m_backingStore->resize(resizeEvent->size());
}

resizeイベントは、ウィンドウが画面に表示される前に呼び出されることが保証されており、画面上でウィンドウのサイズが変更されるたびに呼び出されます。これを使用してバックバッファのサイズを変更し、レンダリングを対応/後続のexposeイベントに延期します。

void RasterWindow::renderNow()
{
    if (!isExposed())
        return;

    QRect rect(0, 0, width(), height());
    m_backingStore->beginPaint(rect);

    QPaintDevice *device = m_backingStore->paintDevice();
    QPainter painter(device);

    painter.fillRect(0, 0, width(), height(), QGradient::NightFade);
    render(&painter);
    painter.end();

    m_backingStore->endPaint();
    m_backingStore->flush(rect);
}

renderNow関数は、QPainter を使用してQWindow のコンテンツをレンダリングするために必要なものを設定します。隠蔽されたウィンドウは表示されないので、ウィンドウがウィンドウシステムで公開されていない場合は中止します。例えば、他のウィンドウがこのウィンドウを完全に隠してしまうような場合です。

描画を開始するには、描画したい領域でQBackingStore::beginPaint() を呼び出します。次に、バック・バッファのQPaintDevice を取得し、QPainter を作成して、そのペイント・デバイスにレンダリングします。

前のレンダリングの痕跡を残さず、きれいなバッファから始めるために、バッファ全体を白で塗りつぶします。次に、このウィンドウの実際の描画を行う仮想 render() 関数を呼び出します。

描画が完了したら、endPaint()を呼び出してレンダリングが終了したことを知らせ、QBackingStore::flush()を使用してバック・バッファの内容を表示します。

void RasterWindow::render(QPainter *painter)
{
    painter->drawText(QRectF(0, 0, width(), height()), Qt::AlignCenter, QStringLiteral("QWindow"));
}

render関数にはウィンドウの描画コードが含まれています。この例では、中央に文字列 "QWindow" を描画しています。

非同期レンダリング

void RasterWindow::renderLater()
{
    requestUpdate();
}

ウィンドウをすぐに再描画する必要がある場所をいくつか見てきました。これは望ましくないケースもありますが、アプリケーションをイベントループに戻し、再描画を後で行うようにスケジュールします。QWindow::requestUpdate ()を使用して更新を要求し、システムが再描画の準備ができたときに配信することで、これを実現します。

bool RasterWindow::event(QEvent *event)
{
    if (event->type() == QEvent::UpdateRequest) {
        renderNow();
        return true;
    }
    return QWindow::event(event);
}

更新イベントを処理するために、仮想QObject::event ()関数を再実装します。イベントが来たら、すぐにウィンドウをレンダリングするために renderNow() を呼び出します。

プロジェクト例 @ code.qt.io

©2024 The Qt Company Ltd. 本書に含まれるドキュメントの著作権は、それぞれの所有者に帰属します。 ここで提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。