Qt Widgetsにおけるスタイル要素描画の極意:QStyle::subElementRect()を駆使してワンランク上のUIを構築


QStyle::subElementRect()は、Qt Widgetsにおけるスタイル要素の矩形を取得するための関数です。スタイル要素とは、プッシュボタンのベベル、ウィンドウフレーム、スクロールバーなどのウィジェットの一部を指します。この関数は、スタイル要素の種類とスタイルオプションに基づいて、スタイル要素の矩形を画面座標で返します。

構文

QRect QStyle::subElementRect(SubElement element,
                             const QStyleOption *option,
                             const QWidget *widget = Q_NULLPTR) const;

引数

  • widget: スタイル要素の所属するウィジェット。省略可能
  • option: スタイル要素を描画する方法と場所を指定するQStyleOption型のポインタ
  • element: 取得したいスタイル要素の種類を表すQStyle::SubElement

戻り値

スタイル要素の矩形を表すQRect

// プッシュボタンのベベルを描画する
QRect bevelRect = style()->subElementRect(SE_PushButtonBevel, option, button);
painter->drawBevel(bevelRect, option->palette.window(), option->state());
  • QStyle::ControlElementは、コントロール要素を表す列挙型です。
  • QStyleOption::directionは、アイテムを描画する方向を示します。
  • subControlRect()subElementRect()は、どちらもスタイル要素の矩形を画面座標で返します。


class MyButton : public QPushButton {
public:
    MyButton(QWidget *parent = nullptr) : QPushButton(parent) {}

protected:
    void paintEvent(QPaintEvent *event) override {
        QPainter painter(this);
        QStyleOption option = styleOption(event);

        // プッシュボタンのベベルを描画する
        QRect bevelRect = style()->subElementRect(SE_PushButtonBevel, &option, this);
        painter.drawBevel(bevelRect, option.palette.window(), option.state());

        // ボタンのテキストを描画する
        QRect textRect = style()->subElementRect(SE_PushButtonText, &option, this);
        painter.drawText(textRect, Qt::AlignCenter, text());
    }
};

例2:ウィンドウフレームを描画する

class MyWindow : public QWidget {
public:
    MyWindow(QWidget *parent = nullptr) : QWidget(parent) {}

protected:
    void paintEvent(QPaintEvent *event) override {
        QPainter painter(this);
        QStyleOption option = styleOption(event);

        // ウィンドウフレームを描画する
        QRect frameRect = style()->subElementRect(SE_WindowFrame, &option, this);
        painter.setPen(Qt::black);
        painter.drawRect(frameRect);
    }
};

例3:スクロールバーのサムを描画する

class MyScrollBar : public QScrollBar {
public:
    MyScrollBar(Qt::Orientation orientation, QWidget *parent = nullptr)
        : QScrollBar(orientation, parent) {}

protected:
    void paintEvent(QPaintEvent *event) override {
        QPainter painter(this);
        QStyleOption option = styleOption(event);

        // スクロールバーのサムを描画する
        QRect thumbRect = style()->subElementRect(SE_ScrollBarThumb, &option, this);
        painter.fillRect(thumbRect, option.palette.highlight());
    }
};


QPainter::drawControl()

QPainter::drawControl()は、コントロール要素を描画するための関数です。スタイル要素の種類とスタイルオプションを指定して、コントロール要素を描画できます。

QRect bevelRect = style()->subElementRect(SE_PushButtonBevel, option, button);
painter->drawControl(SE_PushButtonBevel, option, button);

QStyle::drawControl()

QStyle::drawControl()は、コントロール要素を描画するための関数です。スタイル要素の種類、スタイルオプション、ウィジェットを指定して、コントロール要素を描画できます。

QRect bevelRect = style()->subElementRect(SE_PushButtonBevel, option, button);
style()->drawControl(SE_PushButtonBevel, option, button);

QPainter::drawPixmap()

QPainter::drawPixmap()は、ピクセルマップを描画するための関数です。スタイル要素のピクセルマップを取得して、ピクセルマップを描画できます。

QPixmap bevelPixmap = style()->standardPixmap(SP_PushButtonBevel);
QRect bevelRect = style()->subElementRect(SE_PushButtonBevel, option, button);
painter->drawPixmap(bevelRect, bevelPixmap);

QStyle::standardPixmap()

QStyle::standardPixmap()は、標準的なピクセルマップを取得するための関数です。スタイル要素の種類を指定して、標準的なピクセルマップを取得できます。

QPixmap bevelPixmap = style()->standardPixmap(SP_PushButtonBevel);
QRect bevelRect = style()->subElementRect(SE_PushButtonBevel, option, button);
painter->drawPixmap(bevelRect, bevelPixmap);
方法利点欠点
QStyle::subElementRect()スタイル要素の矩形を正確に取得できる描画処理を自分で行う必要がある
QPainter::drawControl()描画処理を簡単に行えるスタイル要素の種類が限定されている
QStyle::drawControl()描画処理を簡単に行えるスタイル要素の種類が限定されている
QPainter::drawPixmap()ピクセルマップを直接描画できるスタイル要素のピクセルマップが存在する必要がある
QStyle::standardPixmap()標準的なピクセルマップを簡単に取得できるスタイル要素によっては標準的なピクセルマップが存在しない