Qtプログラミングで色を操る!QColorクラスの基礎と実践
QColor
クラスは、Qtフレームワークにおいて色を表現・操作するための基本的なクラスです。GUIアプリケーションで要素の色を設定したり、グラフィックを描画したりする際に頻繁に使用されます。
特徴と主な機能
QColor
クラスには、以下のような特徴と機能があります。
-
多様な色モデルのサポート:
- RGB (Red, Green, Blue): 赤、緑、青の3原色の組み合わせで色を表現します。コンピュータのディスプレイで色を表示する際に最も一般的に使われます。
- HSV (Hue, Saturation, Value): 色相、彩度、明度の3つの要素で色を表現します。人間が直感的に色を理解しやすいモデルです。
- CMYK (Cyan, Magenta, Yellow, Black): シアン、マゼンタ、イエロー、ブラックの4色で色を表現します。主に印刷業界で使われます。
- アルファチャネル (Alpha Channel): 上記の色モデルに加えて、透明度を表現するためのアルファチャネルをサポートしています。0(完全な透明)から255(完全な不透明)の範囲で指定します。
-
色の生成方法:
- RGB値による指定:
QColor(int r, int g, int b, int a = 255)
のように、赤、緑、青、透明度の値を直接指定して色を作成できます。 - 名前による指定:
"red"
,"blue"
,"darkGray"
のような色の名前(SVG 1.0のカラーネームに対応)を使って色を作成できます。 - 16進数文字列による指定:
"#RRGGBB"
や"#AARRGGBB"
のような16進数文字列で色を指定することも可能です。 - 定義済みの色:
Qt::red
,Qt::blue
,Qt::white
,Qt::black
など、Qtに予め定義されているグローバルな色を使用できます。
- RGB値による指定:
-
色の取得と変換:
- 各色モデルのコンポーネント(例:
red()
,hue()
,cyan()
)を個別に取得できます。 getRgb()
,getHsv()
,getCmyk()
などのメソッドを使って、一度に複数のコンポーネントを取得することも可能です。toRgb()
,toHsv()
,toCmyk()
などのメソッドで、異なる色モデルに変換した新しいQColor
オブジェクトを取得できます。
- 各色モデルのコンポーネント(例:
-
色の操作:
lighter()
やdarker()
メソッドを使って、現在の色を明るくしたり暗くしたりできます。setRgb()
,setHsv()
,setCmyk()
などで、既存のQColor
オブジェクトの色を変更できます。
-
浮動小数点精度での指定:
- 整数の0-255の範囲だけでなく、0.0-1.0の浮動小数点数で色のコンポーネントを指定する関数(例:
redF()
,setHsvF()
)も提供されています。
- 整数の0-255の範囲だけでなく、0.0-1.0の浮動小数点数で色のコンポーネントを指定する関数(例:
-
プラットフォーム独立性:
QColor
はプラットフォームやデバイスに依存しないように設計されており、Qtが色のマッピングを抽象化してくれます。
#include <QColor>
#include <QDebug> // デバッグ出力用
int main() {
// RGB値で色を作成(赤、緑、青、不透明度)
QColor redColor(255, 0, 0); // 完全な赤
QColor semiTransparentBlue(0, 0, 255, 128); // 半透明の青
qDebug() << "Red Color RGB:" << redColor.red() << redColor.green() << redColor.blue();
qDebug() << "Semi-Transparent Blue Alpha:" << semiTransparentBlue.alpha();
// 色の名前で作成
QColor greenColor("green");
qDebug() << "Green Color Name:" << greenColor.name(); // #008000FF のような形式で出力
// 16進数文字列で作成
QColor purpleColor("#800080"); // 紫色
qDebug() << "Purple Color RGB:" << purpleColor.red() << purpleColor.green() << purpleColor.blue();
// 定義済みの色
QColor defaultBlue = Qt::blue;
qDebug() << "Default Blue RGB:" << defaultBlue.red() << defaultBlue.green() << defaultBlue.blue();
// HSV値で色を作成し、RGB値を取得
QColor hsvColor;
hsvColor.setHsv(0, 255, 255); // 色相0(赤)、彩度最大、明度最大
qDebug() << "HSV Color (Hue 0) RGB:" << hsvColor.red() << hsvColor.green() << hsvColor.blue();
// 色を明るくする
QColor lighterRed = redColor.lighter(150); // 150%明るくする
qDebug() << "Lighter Red RGB:" << lighterRed.red() << lighterRed.green() << lighterRed.blue();
// 色が有効かどうかのチェック
QColor invalidColor(999, 0, 0); // 範囲外の値
qDebug() << "Invalid Color is valid?" << invalidColor.isValid(); // false を出力
return 0;
}
コンパイルエラー: fatal error: QColor: No such file or directory
原因
QColor
クラスを使用するために必要なヘッダーファイルがインクルードされていないか、Qtのモジュールが.pro
ファイルに正しく追加されていない場合に発生します。
トラブルシューティング
-
.pro
ファイルにモジュールを追加:QColor
は通常、QtのQtGui
モジュール(Qt 5以降)またはQtWidgets
モジュール(QGuiApplication
を使用しない場合)に属しています。プロジェクトの.pro
ファイルに以下の行を追加しているか確認してください。QT += gui # QColorを使用するために必要 QT += widgets # GUIアプリケーションでQWidgetなどを使う場合に必要
Qt 6では、
QT += gui
ではなくQT += Gui
のように大文字で指定する必要があります。 -
ヘッダーのインクルードを確認:
QColor
を使用するC++ファイルの先頭に、以下の行を追加しているか確認してください。#include <QColor>
ランタイムエラー/不正な色表示: 不適切な値の指定
QColor
のコンストラクタやsetRgb()
などのメソッドに、範囲外の値を渡した場合に、期待通りの色が表示されないことがあります。例えば、RGB値は通常0から255の範囲です。
isValid()
メソッドでチェック:QColor
オブジェクトが有効な色を表しているかどうかは、isValid()
メソッドで確認できます。無効な値を設定するとisValid()
はfalse
を返します。QColor myColor(300, 0, 0); // 無効なRGB値 if (!myColor.isValid()) { qWarning() << "Error: Invalid color specified!"; }
- 値の範囲を確認:
- RGB: 各コンポーネント(赤、緑、青、アルファ)は0から255の整数値です。
- HSV: 色相(Hue)は0から359、彩度(Saturation)と明度(Value)は0から255の整数値です。
- 浮動小数点版のメソッド(例:
setRgbF()
)を使用する場合は、0.0から1.0の範囲で指定します。
ランタイムエラー/警告: QColor::setNamedColor: Unknown color name '...'
QColor
コンストラクタやsetNamedColor()
メソッドに、Qtが認識しない色の名前を文字列で渡した場合に発生します。
- 名前ではなくRGB値で指定:
もしカスタムの色を使用したい場合は、色の名前ではなくRGB値(
QColor(r, g, b)
)または16進数文字列(QColor("#RRGGBB")
)で直接指定することを検討してください。QColor unknownColor("myCustomColor"); // これはおそらく警告を出す QColor validColor("darkGray"); // これは問題ない // 代替案: QColor customColor(123, 45, 67); // RGB値で指定 QColor hexColor("#7B2D43"); // 16進数で指定
- 正しい色の名前を使用:
QtはSVG 1.0で定義されている色の名前(例:
"red"
,"blue"
,"darkGray"
,"lightGreen"
など)をサポートしています。スペルミスがないか、またはサポートされていない独自の色の名前を使用していないか確認してください。
QMLとの連携に関する問題: TypeError: Type error
C++で定義したQColor
プロパティをQML側で操作しようとした際に、型変換がうまくいかない場合に発生することがあります。
- QMLとC++間の型変換:
Qtは通常、
QColor
をQMLのcolor
型に自動的に変換します。しかし、QML側で期待される型とC++側で提供される型が一致しない場合に問題が発生します。- C++からQMLへ
QColor
を渡す場合は、Q_PROPERTY(QColor myColor ...)
として定義し、QML側で直接myComponent.myColor = someColor
のように代入してみてください。 - もし
Q_INVOKABLE
な関数でQColor
を返す場合は、その関数の戻り値の型がQColor
であることを確認してください。文字列で返す場合は、QML側で文字列として受け取り、QMLのQt.color()
関数などで変換することを検討します。
// C++側 class MyCppObject : public QObject { Q_OBJECT Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor NOTIFY backgroundColorChanged) public: QColor backgroundColor() const { return m_backgroundColor; } void setBackgroundColor(const QColor& color) { if (m_backgroundColor != color) { m_backgroundColor = color; emit backgroundColorChanged(); } } signals: void backgroundColorChanged(); private: QColor m_backgroundColor; }; // QML側 MyCppObject { id: myObject backgroundColor: "red" // QMLで直接色名を指定 } Rectangle { color: myObject.backgroundColor // C++から受け取った色を使用 }
- C++からQMLへ
QColorのインスタンス化と寿命
QColor
は軽量な値クラスなので、通常はスタックで作成したり、値渡しで利用したりしても問題ありません。しかし、誤ってポインタとして扱ったり、不適切なメモリ管理を行ったりすると問題が発生する可能性があります。
- ポインタの使用は避ける:
特別な理由がない限り、
QColor*
のようにポインタで扱うことは避けるべきです。// 悪い例 (通常は不要) QColor* myColorPtr = new QColor(0, 0, 255); // ... delete myColorPtr; // メモリリークを避けるために解放が必要 // 良い例 QColor myColor(0, 0, 255);
- 値クラスとしての理解:
QColor
はQString
やQPoint
などと同様に値クラスです。コピーは高速で、所有権の管理についてあまり心配する必要はありません。QColor color1 = Qt::red; QColor color2 = color1; // 値がコピーされる
異なる色空間(RGB, HSV, CMYK)間での変換や、特定のコンポーネント(例: アルファ値)の扱いの誤解。
- 変換メソッドの利用:
例えば、RGBで色を設定した後、HSV値を取得したい場合は
toHsv()
メソッドを使用します。QColor rgbColor(255, 128, 0); // オレンジ QColor hsvColor = rgbColor.toHsv(); qDebug() << "Hue:" << hsvColor.hue() << "Saturation:" << hsvColor.saturation() << "Value:" << hsvColor.value();
- アルファ値の確認:
色が透明であるはずなのに透明にならない場合、アルファ値が255(完全な不透明)になっていないか確認してください。
QColor transparentRed(255, 0, 0, 100); // 100は半透明 // QPainterなどで描画する際に、QPainter::CompositionModeを設定しないと透明度が反映されない場合がある
- 色空間の理解:
- RGB: 画面表示に最適。各チャネルが独立して光の強度を示す。
- HSV: 人間が直感的に色を調整するのに便利(色相をずらす、彩度を下げるなど)。
- CMYK: 印刷用。インクの混合をシミュレートする。
QColorオブジェクトの基本的な作成と値の取得
最も基本的なQColor
オブジェクトの作成方法と、その色コンポーネント(RGB、アルファ値)の取得方法です。
#include <QApplication> // QApplicationはQtアプリケーションの基本的な制御を提供
#include <QLabel> // テキストや画像を表示するためのウィジェット
#include <QPalette> // ウィジェットの色を設定するためのクラス
#include <QColor> // 色を表現するクラス
#include <QDebug> // デバッグ出力用
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
// --- QColorの作成例 ---
// 1. RGB値(赤、緑、青、アルファ)で作成
// 各値は0〜255の範囲。アルファは省略すると255(不透明)
QColor redColor(255, 0, 0); // 純粋な赤
QColor semiTransparentBlue(0, 0, 255, 128); // 半透明の青
// 2. 色の名前(SVG 1.0のカラーネーム)で作成
QColor greenColor("green"); // "green"
QColor darkGrayColor("darkGray"); // "darkGray"
// 3. 16進数文字列で作成
// #RRGGBB または #AARRGGBB 形式
QColor purpleColor("#800080"); // 紫色
QColor orangeColor("#FFA500"); // オレンジ色
QColor transparentYellow("#80FFFF00"); // 半透明の黄色
// 4. Qtの定義済み定数で作成
QColor blueColor = Qt::blue;
QColor whiteColor = Qt::white;
// --- 色コンポーネントの取得例 ---
qDebug() << "--- Color Component Values ---";
qDebug() << "Red Color:";
qDebug() << " RGB:" << redColor.red() << redColor.green() << redColor.blue();
qDebug() << " Alpha:" << redColor.alpha();
qDebug() << " Hex Name:" << redColor.name(QColor::HexRgb); // #FF0000
qDebug() << "Semi-Transparent Blue:";
qDebug() << " RGB:" << semiTransparentBlue.red() << semiTransparentBlue.green() << semiTransparentBlue.blue();
qDebug() << " Alpha:" << semiTransparentBlue.alpha();
qDebug() << " Hex Name (ARGB):" << semiTransparentBlue.name(QColor::HexArgb); // #800000FF
qDebug() << "Purple Color:";
qDebug() << " RGB:" << purpleColor.red() << purpleColor.green() << purpleColor.blue();
qDebug() << " Alpha:" << purpleColor.alpha();
qDebug() << " Is valid?" << purpleColor.isValid(); // true
// 無効な色(範囲外の値を指定)
QColor invalidColor(300, 0, 0);
qDebug() << "Invalid Color is valid?" << invalidColor.isValid(); // false を出力
// --- QLabelを使った色の表示例 ---
QLabel *label = new QLabel("Hello QColor!");
label->setAlignment(Qt::AlignCenter);
// 背景色を設定 (QPaletteを使用)
QPalette palette = label->palette();
palette.setColor(QPalette::Window, orangeColor); // ウィジェットの背景色
palette.setColor(QPalette::WindowText, Qt::white); // テキストの色
label->setAutoFillBackground(true); // パレットの背景色を適用するために必要
label->setPalette(palette);
// 半透明の背景を持つラベル
QLabel *transparentLabel = new QLabel("Transparent Text");
transparentLabel->setAlignment(Qt::AlignCenter);
QPalette transparentPalette = transparentLabel->palette();
transparentPalette.setColor(QPalette::Window, transparentYellow);
transparentPalette.setColor(QPalette::WindowText, Qt::darkBlue);
transparentLabel->setAutoFillBackground(true);
transparentLabel->setPalette(transparentPalette);
// ウィンドウにラベルを配置
QWidget *window = new QWidget();
QVBoxLayout *layout = new QVBoxLayout(window);
layout->addWidget(label);
layout->addWidget(transparentLabel); // 半透明のラベルも追加
window->setWindowTitle("QColor Example");
window->resize(300, 150);
window->show();
return app.exec();
}
解説:
QLabel
ウィジェットの背景色や文字色を設定するためにQPalette
クラスを使用しています。setAutoFillBackground(true)
を呼び出すことで、パレットの背景色がウィジェットに適用されます。isValid()
はQColor
オブジェクトが有効な色を表しているかを確認するのに便利です。name()
メソッドは色を16進数文字列として返します。引数にQColor::HexRgb
やQColor::HexArgb
を指定することで、アルファ値を含む形式で出力できます。red()
,green()
,blue()
,alpha()
メソッドで各コンポーネントの値を取得できます。QColor
の作成方法は複数あります。最も一般的なのはRGB値の直接指定、色の名前(文字列)、16進数文字列です。
色モデル間の変換 (RGB, HSV, CMYK)
QColor
は、RGB以外にもHSV(Hue, Saturation, Value)やCMYK(Cyan, Magenta, Yellow, Black)といった色モデルをサポートしており、相互に変換することができます。
#include <QApplication>
#include <QLabel>
#include <QColor>
#include <QDebug>
#include <QVBoxLayout>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QColor originalColor(150, 75, 200); // オリジナルの色 (紫っぽい色)
qDebug() << "--- Original Color (RGB) ---";
qDebug() << "R:" << originalColor.red() << "G:" << originalColor.green() << "B:" << originalColor.blue() << "A:" << originalColor.alpha();
// --- RGBからHSVへの変換 ---
QColor hsvColor = originalColor.toHsv();
qDebug() << "\n--- Converted to HSV ---";
qDebug() << "Hue:" << hsvColor.hue() << "Saturation:" << hsvColor.saturation() << "Value:" << hsvColor.value() << "Alpha:" << hsvColor.alpha();
qDebug() << "(float) H:" << hsvColor.hueF() << "S:" << hsvColor.saturationF() << "V:" << hsvColor.valueF();
// --- RGBからCMYKへの変換 ---
QColor cmykColor = originalColor.toCmyk();
qDebug() << "\n--- Converted to CMYK ---";
qDebug() << "Cyan:" << cmykColor.cyan() << "Magenta:" << cmykColor.magenta() << "Yellow:" << cmykColor.yellow() << "Black:" << cmykColor.black() << "Alpha:" << cmykColor.alpha();
qDebug() << "(float) C:" << cmykColor.cyanF() << "M:" << cmykColor.magentaF() << "Y:" << cmykColor.yellowF() << "K:" << cmykColor.blackF();
// --- HSV値からQColorを作成し、RGBを取得 ---
QColor hsvCreatedColor;
hsvCreatedColor.setHsv(0, 255, 255); // 色相0(赤)、彩度最大、明度最大
qDebug() << "\n--- HSV Created Color (Red) ---";
qDebug() << "R:" << hsvCreatedColor.red() << "G:" << hsvCreatedColor.green() << "B:" << hsvCreatedColor.blue(); // 255 0 0 となる
// --- QLabels for visualization ---
QWidget *window = new QWidget();
QVBoxLayout *layout = new QVBoxLayout(window);
auto createColorLabel = [](const QColor &color, const QString &text) {
QLabel *label = new QLabel(text);
label->setAlignment(Qt::AlignCenter);
QPalette palette;
palette.setColor(QPalette::Window, color);
label->setAutoFillBackground(true);
label->setPalette(palette);
return label;
};
layout->addWidget(createColorLabel(originalColor, "Original RGB Color"));
layout->addWidget(createColorLabel(hsvColor.toRgb(), "Converted back from HSV")); // HSVからRGBに戻す
layout->addWidget(createColorLabel(cmykColor.toRgb(), "Converted back from CMYK")); // CMYKからRGBに戻す
layout->addWidget(createColorLabel(hsvCreatedColor, "Created from HSV"));
window->setWindowTitle("QColor Conversions");
window->resize(300, 250);
window->show();
return app.exec();
}
解説:
*_F()
の付くメソッド(例:hueF()
)は、浮動小数点精度で値を返します(0.0〜1.0)。setHsv()
,setRgb()
などのメソッドを使って、既存のQColor
オブジェクトの色モデルを変更することも可能です。hue()
,saturation()
,value()
,cyan()
,magenta()
,yellow()
,black()
メソッドで、それぞれの色モデルのコンポーネント値を取得できます。toHsv()
,toCmyk()
メソッドを使って、現在のQColor
オブジェクトを新しいHSVまたはCMYKのQColor
オブジェクトに変換します。
QColor
は、色の明るさを変更したり、他の色とブレンドしたりする機能も提供します。
#include <QApplication>
#include <QLabel>
#include <QColor>
#include <QDebug>
#include <QVBoxLayout>
#include <QPushButton>
#include <QSlider>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QWidget *window = new QWidget();
QVBoxLayout *layout = new QVBoxLayout(window);
// --- 明るさの変更 ---
QLabel *originalLabel = new QLabel("Original Red");
originalLabel->setAlignment(Qt::AlignCenter);
QColor baseRed(200, 0, 0); // 基本の赤
QPalette originalPalette = originalLabel->palette();
originalPalette.setColor(QPalette::Window, baseRed);
originalLabel->setAutoFillBackground(true);
originalLabel->setPalette(originalPalette);
layout->addWidget(originalLabel);
QLabel *lighterLabel = new QLabel("Lighter Red (150%)");
lighterLabel->setAlignment(Qt::AlignCenter);
QColor lighterRed = baseRed.lighter(150); // 150%明るくする
QPalette lighterPalette = lighterLabel->palette();
lighterPalette.setColor(QPalette::Window, lighterRed);
lighterLabel->setAutoFillBackground(true);
lighterLabel->setPalette(lighterPalette);
layout->addWidget(lighterLabel);
QLabel *darkerLabel = new QLabel("Darker Red (50%)");
darkerLabel->setAlignment(Qt::AlignCenter);
QColor darkerRed = baseRed.darker(50); // 50%暗くする
QPalette darkerPalette = darkerLabel->palette();
darkerPalette.setColor(QPalette::Window, darkerRed);
darkerLabel->setAutoFillBackground(true);
darkerLabel->setPalette(darkerPalette);
layout->addWidget(darkerLabel);
// --- 色のブレンド ---
QLabel *blendedLabel = new QLabel("Blended Color");
blendedLabel->setAlignment(Qt::AlignCenter);
QColor colorA = Qt::blue;
QColor colorB = Qt::yellow;
// colorAとcolorBを50:50でブレンド
QColor blendedColor = colorA.lighter(colorB.lighter(200)).darker(colorA.darker(100)); // このブレンド方法は一例
// より簡単なブレンド: QColor::fromRgbF() などで手動でR,G,Bの平均を取る
// QColor blendedColor = QColor::fromRgbF((colorA.redF() + colorB.redF()) / 2.0,
// (colorA.greenF() + colorB.greenF()) / 2.0,
// (colorA.blueF() + colorB.blueF()) / 2.0);
// あるいは、QPainter::CompositionMode を使って描画時にブレンドする方が一般的
// 実際にはより数学的なブレンドやQPainterを使うことが多い
// ここでは単純な例として、それぞれの明るさを調整して加算
QColor simpleBlend = QColor(
(colorA.red() + colorB.red()) / 2,
(colorA.green() + colorB.green()) / 2,
(colorA.blue() + colorB.blue()) / 2
);
QPalette blendedPalette = blendedLabel->palette();
blendedPalette.setColor(QPalette::Window, simpleBlend); // 平均色をセット
blendedLabel->setAutoFillBackground(true);
blendedLabel->setPalette(blendedPalette);
layout->addWidget(blendedLabel);
// スライダーで色の明るさをリアルタイムで調整する例
QSlider *brightnessSlider = new QSlider(Qt::Horizontal);
brightnessSlider->setRange(0, 200); // 0%から200%まで
brightnessSlider->setValue(100); // 初期値は100%
layout->addWidget(new QLabel("Adjust Red Brightness:"));
layout->addWidget(brightnessSlider);
// スライダーの値が変更されたらラベルの背景色を更新
QObject::connect(brightnessSlider, &QSlider::valueChanged, [=](int value){
QColor currentRed = baseRed.lighter(value);
QPalette p = originalLabel->palette();
p.setColor(QPalette::Window, currentRed);
originalLabel->setPalette(p);
});
window->setWindowTitle("QColor Operations");
window->resize(350, 400);
window->show();
return app.exec();
}
解説:
- スライダーと
QObject::connect
を使用して、色の明るさをリアルタイムで変更するインタラクティブな例も示しています。 - 色のブレンドはより複雑ですが、
QColor
自体には直接的なブレンドメソッドはありません。一般的には、各RGBコンポーネントを数学的に平均したり、QPainter
のコンポジションモード(QPainter::CompositionMode_SourceOver
など)を使用して描画時にブレンドします。上記の例では単純な平均化でブレンドをシミュレートしています。 lighter(factor)
とdarker(factor)
メソッドは、現在の色を指定されたファクター(パーセンテージ、100が元の明るさ)で明るくしたり暗くしたりします。
QColor
自体は色の表現とその操作に特化したクラスであり、これに代わる「色」の概念を扱う直接的なクラスは Qt にはほとんどありません。しかし、「色の指定方法」「色の管理方法」「色を使った描画方法」という観点から、QColor
と連携したり、間接的に色の概念を扱う代替・関連技術を説明します。
CSS (Cascading Style Sheets) による色の指定
Qt のウィジェットやアプリケーション全体の色を制御する強力な方法の一つに、CSS(Qt Style Sheets)があります。これはウェブ開発で使われるCSSと非常によく似ており、ウィジェットのプロパティ(背景色、文字色、ボーダー色など)を直接指定できます。
特徴
- 特定のウィジェットタイプ、ID、クラスなどに対してスタイルを適用できる。
- ランタイムでスタイルを変更できるため、テーマ変更などに利用できる。
- 宣言的にスタイルを記述できるため、見た目のカスタマイズが容易。
QColor
との関係
CSSで色を指定する際も、結局は色の名前や16進数コードを使用するため、内部的にはQColor
が使用されています。しかし、開発者からは直接QColor
オブジェクトを操作するよりも、文字列ベースで色を指定する形になります。
例
#include <QApplication>
#include <QPushButton>
#include <QWidget>
#include <QVBoxLayout>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QPushButton *button1 = new QPushButton("Blue Button");
QPushButton *button2 = new QPushButton("Custom Styled Button");
// CSSで背景色と文字色を設定
button1->setStyleSheet("background-color: blue; color: white;");
// より複雑なスタイル設定
button2->setStyleSheet(
"QPushButton {"
" background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #FF6600, stop: 1 #FF0000);" // グラデーション
" color: white;"
" border-style: outset;"
" border-width: 2px;"
" border-radius: 10px;"
" border-color: #880000;"
" font: bold 14px;"
" padding: 6px;"
"}"
"QPushButton:pressed {" // 押された時のスタイル
" background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #FF0000, stop: 1 #FF6600);"
" border-style: inset;"
"}"
);
QWidget *window = new QWidget();
QVBoxLayout *layout = new QVBoxLayout(window);
layout->addWidget(button1);
layout->addWidget(button2);
window->setWindowTitle("Qt Style Sheets Example");
window->show();
return app.exec();
}
QPaletteによるテーマ/UI要素ごとの色の管理
QPalette
クラスは、ウィジェットの各「役割(Role)」に応じた色を管理するためのクラスです。例えば、ウィジェットの背景色(Window
)、文字色(WindowText
)、ボタンの背景色(Button
)、ボタンの文字色(ButtonText
)など、UI要素が持つ様々な色の役割を抽象化しています。
- アプリケーション全体、または個々のウィジェットに対してパレットを設定できる。
- システム設定やデスクトップ環境のテーマに追従できる。
- ウィジェットの状態(アクティブ、非アクティブ、無効)に応じた色グループを持つ。
QPalette
は内部的にQColor
オブジェクトを使って色を保持します。QPalette::setColor()
やQPalette::brush()
などでQColor
オブジェクトを渡したり、受け取ったりします。
#include <QApplication>
#include <QLabel>
#include <QPushButton>
#include <QPalette>
#include <QVBoxLayout>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QLabel *label = new QLabel("Palette Example");
QPushButton *button = new QPushButton("Click Me");
// ウィジェットのパレットを取得
QPalette labelPalette = label->palette();
// ラベルの背景色と文字色を設定
labelPalette.setColor(QPalette::Window, Qt::magenta); // 背景色
labelPalette.setColor(QPalette::WindowText, Qt::yellow); // 文字色
label->setAutoFillBackground(true); // 背景色を適用するために必要
label->setPalette(labelPalette);
// ボタンのパレットを個別に設定
QPalette buttonPalette = button->palette();
// ボタンの通常時の背景色と文字色を設定
buttonPalette.setColor(QPalette::Button, QColor(50, 150, 250)); // 明るい青
buttonPalette.setColor(QPalette::ButtonText, Qt::white);
// ボタンの無効時の文字色を設定
buttonPalette.setColor(QPalette::Disabled, QPalette::ButtonText, Qt::darkGray);
button->setPalette(buttonPalette);
// ボタンを無効にしてみる
// button->setEnabled(false);
QWidget *window = new QWidget();
QVBoxLayout *layout = new QVBoxLayout(window);
layout->addWidget(label);
layout->addWidget(button);
window->setWindowTitle("QPalette Example");
window->show();
return app.exec();
}
QRgb型と非メンバ関数 (qRgb, qAlpha, qRedなど)
QColor
クラスが導入される以前、Qt 1.x の時代などでは、色を単なる unsigned int
型で表現することが一般的でした。この unsigned int
は、通常 0xAARRGGBB の形式でアルファ、赤、緑、青の各コンポーネントを格納します。Qt はこの QRgb
型(unsigned int
のtypedef)と、それを操作するための非メンバ関数を提供しています。
QImage
のピクセルデータへのアクセスなどで使用されることがある。- パフォーマンスが非常に重視されるピクセル操作などで直接バイトを操作するのと同等の感覚で扱える。
- 低レベルでの色の操作が必要な場合や、古いコードベースとの互換性が必要な場合に利用。
QColor
はQRgb
型との相互変換が可能です(例: QColor::fromRgb(QRgb)
、QColor::rgb()
)。通常、QColor
を使用する方がオブジェクト指向的で安全ですが、特定の場合にQRgb
を直接扱うことがあります。
#include <QApplication>
#include <QImage>
#include <QPainter>
#include <QLabel>
#include <QRgb> // QRgb型と関連関数
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
// QRgb値の作成
QRgb red = qRgb(255, 0, 0); // 赤
QRgb semiTransparentGreen = qRgba(0, 255, 0, 128); // 半透明の緑
// QRgb値から各コンポーネントを取得
qDebug() << "Red (QRgb):";
qDebug() << " R:" << qRed(red) << "G:" << qGreen(red) << "B:" << qBlue(red);
qDebug() << "Semi-Transparent Green (QRgb):";
qDebug() << " R:" << qRed(semiTransparentGreen) << "G:" << qGreen(semiTransparentGreen) << "B:" << qBlue(semiTransparentGreen) << "A:" << qAlpha(semiTransparentGreen);
// QColorからQRgbへの変換、およびその逆
QColor qtColor = Qt::blue;
QRgb qColorAsRgb = qtColor.rgb(); // QColorからQRgbへ
QColor newQtColor = QColor::fromRgb(qColorAsRgb); // QRgbからQColorへ
qDebug() << "Qt Blue as QRgb (R,G,B):" << qRed(qColorAsRgb) << qGreen(qColorAsRgb) << qBlue(qColorAsRgb);
// QImageのピクセル操作でQRgbを使用する例
QImage image(100, 100, QImage::Format_ARGB32);
for (int y = 0; y < image.height(); ++y) {
for (int x = 0; x < image.width(); ++x) {
// グラデーションを作成
int r = x * 255 / image.width();
int g = y * 255 / image.height();
int b = 0;
QRgb pixelColor = qRgb(r, g, b);
image.setPixel(x, y, pixelColor);
}
}
QLabel *imageLabel = new QLabel();
imageLabel->setPixmap(QPixmap::fromImage(image));
QWidget *window = new QWidget();
QVBoxLayout *layout = new QVBoxLayout(window);
layout->addWidget(imageLabel);
window->setWindowTitle("QRgb Example");
window->show();
return app.exec();
}
QBrushとQPen
QBrush
は図形の「塗りつぶし」を定義するクラスで、単色だけでなく、グラデーション、パターン、画像など、様々な種類の塗りつぶしをサポートします。QPen
は図形の「輪郭線」を定義するクラスで、色、幅、スタイル(実線、点線など)を指定できます。
- 単なる色以上の塗りつぶしや線のスタイルを管理できる。
QPainter
による描画操作において、色を直接指定する代わりにQBrush
やQPen
を使用することで、より豊かな視覚表現が可能になる。
QBrush
とQPen
は、その色を指定する際にQColor
オブジェクトを引数に取ります。
#include <QApplication>
#include <QWidget>
#include <QPainter>
#include <QBrush>
#include <QPen>
#include <QColor>
// 描画を行うカスタムウィジェット
class DrawingWidget : public QWidget {
protected:
void paintEvent(QPaintEvent *event) override {
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing); // アンチエイリアス
// --- QBrushの使用例 ---
// 単色のブラシ (QColorを使用)
QBrush solidBrush(Qt::red);
painter.setBrush(solidBrush);
painter.drawRect(10, 10, 80, 80);
// グラデーションのブラシ (QColorを使用)
QLinearGradient gradient(100, 10, 180, 90); // 始点と終点
gradient.setColorAt(0, Qt::blue); // 0%の位置は青
gradient.setColorAt(1, Qt::yellow); // 100%の位置は黄
QBrush gradientBrush(gradient);
painter.setBrush(gradientBrush);
painter.drawEllipse(100, 10, 80, 80);
// --- QPenの使用例 ---
// 単色のペン (QColorを使用)
QPen redPen(Qt::red);
redPen.setWidth(5); // 太さ5ピクセル
painter.setPen(redPen);
painter.drawLine(200, 10, 280, 90);
// 太くて点線のペン (QColorを使用)
QPen dashedBluePen(Qt::blue);
dashedBluePen.setWidth(3);
dashedBluePen.setStyle(Qt::DotLine); // 点線スタイル
painter.setPen(dashedBluePen);
painter.drawRect(200, 10, 80, 80);
// QBrushとQPenの組み合わせ
QBrush purpleBrush(QColor(128, 0, 128)); // 紫色のブラシ
QPen greenPen(Qt::darkGreen); // 濃い緑のペン
greenPen.setWidth(2);
painter.setBrush(purpleBrush);
painter.setPen(greenPen);
painter.drawRoundedRect(10, 100, 100, 50, 10, 10); // 角丸四角形
}
};
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
DrawingWidget *widget = new DrawingWidget();
widget->setWindowTitle("QBrush and QPen Example");
widget->resize(300, 200);
widget->show();
return app.exec();
}
Qt 6 では、より高度なカラーマネージメントのために QColorSpace
クラスが導入されました。これは、特定のデバイスや標準(sRGB、Display P3など)に対応した色空間を定義し、異なる色空間間での正確な色変換を可能にします。
- プロフェッショナルなグラフィックアプリケーションや画像処理で重要になる。
- HDR(High Dynamic Range)のような新しいディスプレイ技術に対応。
- モニターや印刷デバイスの特性に合わせた色表示を可能にする。
QColor
は、QColorSpace
オブジェクトを指定して色を作成したり、ある色空間の色を別の色空間に変換したりすることができます。
例(簡略化)
#include <QApplication>
#include <QColor>
#include <QColorSpace> // Qt 6以降
#include <QDebug>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
// sRGB色空間の赤色
QColor srgbRed = QColor::fromRgb(255, 0, 0, QColorSpace::SRgb);
// Display P3色空間の赤色(Qt 6.2以降で利用可能)
// QColor displayP3Red = QColor::fromRgb(255, 0, 0, QColorSpace::DisplayP3);
// 現在の色空間を取得
qDebug() << "sRGB Red Color Space:" << srgbRed.colorSpace().name();
// 別の色空間に変換
// QColor convertedRed = srgbRed.toColorSpace(QColorSpace::DisplayP3);
// qDebug() << "Converted Red Color Space:" << convertedRed.colorSpace().name();
// 注: QColorSpaceは複雑なテーマであり、具体的な描画や表示はさらに詳細な設定が必要です。
// この例は概念を示すためのものです。
return 0; // QApplicationがイベントループに入らないため、すぐに終了
}
QColor
はQtにおける色の基本的な「単位」ですが、その使い方や管理方法には様々な代替・関連技術があります。
- 正確なカラーマネージメントや高度な色空間の扱いなら:
QColorSpace
(Qt 6以降)。 - 図形の塗りつぶしや線の描画なら:
QBrush
とQPen
(これらはQColor
を内部で使う)。 - 低レベルでのピクセル操作や古いAPIとの互換性なら:
QRgb
型と関連の非メンバ関数。 - ウィジェットの役割に応じた色の体系的な管理なら:
QPalette
。 - GUIの見た目を手軽にカスタマイズするなら:
Qt Style Sheets
(CSS)。