「Qtの基礎 - ウインドウ」の版間の差分

提供:MochiuWiki - SUSE, Electronic Circuit, PCB
ナビゲーションに移動 検索に移動
261行目: 261行目:
   
   
     return app.exec();
     return app.exec();
}
</syntaxhighlight>
<br>
==== ウィンドウの背景を画像にする ====
<code>QStyle</code>クラスは、ウィンドウの外見を詳細に設定することができる。<br>
<br>
<code>QStyle</code>クラスを継承した派生クラスを作成して、必要な項目のうち、比較的簡単に設定できる項目である。<br>
<code>QStyle</code>クラスを継承した派生クラスは数種類用意されており、OSにより使用できるものが決まっている。<br>
<br>
以下の例は、Qtに付属しているサンプルを参考にしている。(<Qtのインストールディレクトリ>/examples/widgets/stylesheetディレクトリ)<br>
ここでは、examples/widgets/stylesディレクトリに合わせて、<code>QMotifStyle</code>クラスを継承した派生クラスを作成している。<br>
<br>
設定後、<code>QMainWindow</code>クラスまたは<code>QDialog</code>クラスのコンストラクタにおいて、以下のように記述して適用する。<br>
<syntaxhighlight lang="c++">
QApplication::setStyle(new MyStyle);  // MyStyleクラスは、QMotifStyleクラスの派生クラス
</syntaxhighlight>
<br>
ウィンドウの背景を画像にするには、まず、<code>polish</code>メソッドをオーバーライドする。<br>
次に、画像を設定するためのsetTextureメソッド(メソッド名は任意)を作成する。<br>
<syntaxhighlight lang="c++">
#pragma once
#include <QtGui/QMotifStyle>
class MyStyle : public QMotifStyle
{
public:
    MyStyle();
    ~MyStyle();
    void polish(QPalette &palette);
private:
    static void setTexture(QPalette &palette, QPalette::ColorRole role, const QPixmap &pixmap);
};
</syntaxhighlight>
<br>
<code>polish</code>メソッドとsetTextureメソッドは、以下のように記述する。<br>
背景画像は、型抜き画像としても使用することができる。したがって、背景用画像と型抜き用画像の2つを用意する必要はない。<br>
<syntaxhighlight lang="c++">
void MyStyle::polish(QPalette &palette)
{
    QPixmap backgroundImage("window.png");
    setTexture(palette, QPalette::Window, backgroundImage);
}
void MyStyle::setTexture(QPalette &palette, QPalette::ColorRole role, const QPixmap &pixmap)
{
    for(int i = 0; i < QPalette::NColorGroups; ++i)
    {
      QColor color = palette.brush(QPalette::ColorGroup(i), role).color();
      palette.setBrush(QPalette::ColorGroup(i), role, QBrush(color, pixmap));
    }
}
</syntaxhighlight>
<br>
==== ボタンのスタイルの変更 ====
上記のセクションにも記述した<code>polish</code>メソッドを使用して、ボタンのスタイルを変更することができる。<br>
<br>
<code>QPalette</code>クラスのコンストラクタでは、ボタンの色を定義する。<br>
ウィンドウおよびコントロールの設定の詳細は、[http://doc-snapshot.qt-project.org/4.8/qpalette.html Qtの公式WebサイトのQPalleteリファレンス]を参照すること。<br>
<syntaxhighlight lang="c++">
void MyStyle::polish(QPalette &palette)
{
    QPixmap backgroundImage("window.png");
    // 追加部分 : ボタンスタイルを変更
    palette = QPalette(QColor(0, 0, 0, 50));
    palette.setBrush(QPalette::ButtonText, Qt::cyan);
    setTexture(palette, QPalette::Window, backgroundImage);
}
</syntaxhighlight>
<br>
また、ボタンの背景を画像に変更するには、以下のように記述する。<br>
<syntaxhighlight lang="c++">
void MyStyle::polish(QPalette &palette)
{
    QPixmap backgroundImage("window.png");
    // 追加部分 : ボタンの背景を画像にする場合
    QPixmap buttonImage("button.png");
    // 追加部分 : ボタンを押下した時の背景
    QPixmap midImage = buttonImage;
    setTexture(palette, QPalette::Button, buttonImage);
    setTexture(palette, QPalette::Mid, midImage);
    setTexture(palette, QPalette::Window, backgroundImage);
  }
  }
  </syntaxhighlight>
  </syntaxhighlight>

2021年3月17日 (水) 06:27時点における版

概要

Qtにおいて、ウィンドウのメニューバー、ツールバー、ステータスバーの作成手順を記載する。


メニュー

サブメニュー名の&の直後の文字列がニーモニックとして使用される。

下図の"File"はQMenuクラス、"Open"はQActionクラスである。

Qt Basic Window 1.jpg


"Open"の右側にあるアイコンを選択するとサブメニューを入力できる。
サブメニューを入力すると、その親メニュー(上図では、"Open")はQMenuクラスに変更される。

追加したアクションは、Qt Designer画面下にある[アクションエディタ]ペインに表示される。

Qt Basic Window 2.jpg



ツールバー

ここでは、ツールバーのアイコン(24x24のpng形式が標準)を作成したとする。

リソースファイルの作成

[ファイル] - [ファイル/プロジェクトの新規作成] - 画面左の[ファイルとクラス] - [Qt] - [Qt リソースファイル]を選択する。
Qtのリソースディレクトリ名をResource、ディレクトリパスはプロジェクト直下とする。

リソースエディタを開く

Qtのメイン画面左にあるプロジェクトツリーの[Resources]直下に、リソースファイル(.qrc)が表示されるので、
リソースファイルを右クリックして、[エディタで開く]を選択する。

※注意
リソースファイルの新規作成時は、自動的にリソースエディタが開く。

新規登録

以下に、リソースファイルが空の場合の登録手順を示す。

  1. まず、リソースエディタを開いて、[Add Prefix]ボタンを押下する。
    または、プロジェクトツリーにあるリソースファイルを右クリックして、[プレフィックスの追加...]を選択する。
  2. プレフィックス名に/(スラッシュ)を入力する。
  3. 次に、[Add Files]ボタンを押下する。
  4. ファイル選択ダイアログ画面にて、リソースファイルを選択する。([Ctrl] + [A]キーで全選択できる)


※注意
プロジェクトツリーにあるリソースファイルを右クリックして、[既存ファイルの追加...]を選択する場合、既定のプレフィックスが作成される。
また、プレフィックスには任意の文字列を指定することができる。

追加登録

以下に、リソースを追加する手順を示す。

  1. まず、リソースエディタを開いて、プレフィックスの行を選択する。
    または、プロジェクトツリーにあるプレフィックス名を右クリックして、[既存のファイルの追加...]を選択する。
  2. [Add Files]ボタンを押下する。
  3. ファイル選択ダイアログ画面にて、リソースファイルを選択する。([Ctrl] + [A]キーで全選択できる)


※注意
プロジェクトツリーのプレフィックス(/)を右クリックして、[既存のファイルを追加]を選択して登録することもできる。

リソースの削除

以下に、リソースを削除する手順を示す。

  1. 削除するリソースの行を選択する。
  2. [削除]ボタンを押下して、ファイルの削除画面を表示する。
  3. ファイル名を確認して、[OK]ボタンを押下する。


※注意
[Delete file permanently]にチェックを入力して削除する場合、ファイルの実体も削除される。
プロジェクトツリーで削除するリソースを右クリックして、[Remove...]を選択して削除することもできる。

リソースの保存

メニューを選択してリソースファイルを上書き保存する。
[ファイル] - [<リソースファイル名>の保存]


リソースをテキストエディタで編集する

テキストエディタを使用すると、リソースファイルの内容を直接変更することができる。

プロジェクトツリーのリソースファイル(.qrc)を右クリックして、[テキストエディタで開く]を選択する。

 // リソースのテキストエディタでの編集例
 <RCC>
    <qresource prefix="/">
       <file>images/drag.png</file>
       <file>images/flower.png</file>
       <file>images/photo.png</file>
    </qresource>
 </RCC>


※注意
テキストエディタでファイルパスの設定を削除しても、ファイルの実体が削除されることはない。


リソースの使用例

リソース名の文字列の取得

プロジェクトツリーのプレフィックスの下にリソース名が表示されている。

リソース名を右クリックして、[パス ":~" をコピー]を選択する。

使用例 1

ソフトウェアのタイトルバーのアイコンとして使用する。

 // プロジェクトディレクトリ直下のimagesディレクトリ内にあるflower.pngファイル
 setWindowIcon(QIcon(":/images/flower.png"));


使用例 2

ラベルにセットして、画像として表示する。

 // プロジェクトディレクトリ直下のimagesディレクトリ内にあるphoto.pngファイル
 std::unique_ptr<QLabel> pLabel = std::make_unique<QLabel>();
 pLabel->setPixmap(QPixmap(":/images/photo.png"));


使用例 3

ドラッグ&ドロップにおいて、ドラッグ中の画像として使用する。

 // プロジェクトディレクトリ直下のimagesディレクトリ内にあるdrag.pngファイル
 std::unique_ptr<QDrag> pDrag = std::make_unique<QDrag>(this);
 qDrag->setPixmap(QPixmap(":/images/drag.png"));


使用例 3

サブメニューにアイコンを割り当てる手順を示す。

  1. Qt Designer画面下のアクションエディタを右クリックして、[編集...]を選択する。
  2. [アクションを編集]画面が開くので、[アイコン(I):]項目の[...]ボタンを押下してリソースに登録した画像ファイルを選択する。
    または、[▼]ボタンを押下して、[ファイルを選択...]から画像ファイルを選択することもできる。
  3. アクションエディタにて、アクションの左側に選択したアイコンが表示される。


使用例 4

ツールバーにアイコンを割り当てる手順を示す。

  1. ツールバーの追加は、Qt Designerに表示しているウィンドウを右クリックして、[ツールバーを追加]を選択する。
  2. ツールバーの追加後、アクションエディタから任意のアクションをツールバーへ、ドラッグ&ドロップする。



ステータスバー

ウインドウまたはダイアログにおいて、ステータスバーを表示する。

 #include <QStatusBar>
 
 QStatusBar StatusBar;
 StatusBar->showMessage(tr("ステータスを表示中..."));


ステータスバーにプログレスバーを表示する場合、以下のように記述する。

 #include <QStatusBar>
 
 QStatusBar StatusBar;
 QProgressBar bar;
 StatusBar->addWidget(&bar);
 
 bar.setMinimum(0);
 bar.setMaximum(100);
 for(int i = 0; i < 100; i++)
 {
    bar.setValue(i);
    // 以下に処理を記述
    // ...
 }
 
 StatusBar->removeWidget(&bar);



タブオーダーの設定

タブオーダーを無効化するには、ウインドウにある全てのウィジェットのタブオーダーを自分自身にする。

 QList<QWidget *>widgets = findChildren<QWidget *>();
 
 foreach(QWidget *widget, widgets)
 {
    widget->setTabOrder(widget, widget);
 }



ウインドウおよびウィジェットの形状の変更

ウインドウおよびプッシュボタン等のウィジェットにおいて、形状を非矩形に変更する、および、背景を画像に変更する手順を記載する。

非矩形ウインドウ

まず、型抜き用画像を作成する。
型抜き用画像は、ウインドウの形状を表す部分を描画した画像のことであり、画像以外の箇所を透過ピクセルにする。
したがって、型抜き用画像は透過(アルファチャンネル)をサポートするフォーマットで保存する必要がある。

これは、Inkscape(ソフトウェア)を使用して、ウィンドウの形状を描画してPNG形式で保存する方法を推奨する。

次に、QMainWindowクラスまたはQDialogクラスのコンストラクタにおいて、以下のように記述する。

 MainWindow::MainWindow()
 {
    Qt::WindowFlags flags = Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint | Qt::FramelessWindowHint;
    setWindowFlags(flags);
    QPixmap pixmap("window.png");
    setMask(pixmap.mask());
 
    // 型抜き画像のサイズに合わせる
    resize( 300, 300 );
 }


ウインドウおよびウィジェットの外観の変更

例えば、ウインドウの背景色を変更する場合、QMainWindowクラスまたはQDialogクラスのコンストラクタにおいて、以下のように記述する。

 MainWindow::MainWindow()
 {
    // 背景色を設定する
    setStyleSheet("* {background-color : rgb( 255, 255, 128 )}");
 
    // 透過率を設定する
    setWindowOpacity(0.7);
 }


また、上記の変更は、Qt Designerから実行することもできる。
Qt Designer画面から、ウインドウまたはウィジェットの[プロパティ] - [styleSheet]項目を選択する。
[スタイルシートを変更]画面が開くので、[〜を追加]プルダウンから"background-color"と"Opacity"のQSSを追加する。

QSSをプロジェクト全体に適用する

一般的に、QSSの設定は各ウィジェットごとに設定するが、プロジェクト全体で共通のQSSを設定することもできる。
QSSの書式や構文は、CSSとほぼ同じである。

以下の例は、Qtに付属しているサンプルを参考にしている。(<Qtのインストールディレクトリ>/examples/widgets/stylesheetディレクトリ)
まず、MainWindow.qssファイルを作成する。

 // MainWindow.qss
 
 // QPushButtonの設定例
 QPushButton
 {
    background-color: #000088;
    border-color: #000044;
    border-style: solid;
    border-radius: 5;
 }
 
 QPushButton:hover
 {
   background-color: #880000;
 }
 
 QPushButton:pressed
 {
    background-color: #008800;
 }


次に、MainWindow.qssファイルをQApplicationクラスのsetStyleSheetメソッドに渡す。
QApplicationクラスのインスタンスはシングルトンとして生成されているため、そのインスタンスから実行する。
また、QSSファイルはリソースとして登録しておくとよい。

以下の例では、main関数でQSSファイルを読み込み、設定している。
QSSには、他にも様々なクラスやセレクタが存在する。

 #include "MainWindow.h"
 #include <QtCore>
 
 int main(int argc, char *argv[])
 {
    QApplication app(argc, argv);
 
    QFile file(":/qss/MainWindow.qss");
    file.open( QFile::ReadOnly );
    QString strStyles = QLatin1String(file.readAll());
 
    app.setStyleSheet( strStyles );
 
    MainWindow w;
    w.show();
 
    return app.exec();
 }


ウィンドウの背景を画像にする

QStyleクラスは、ウィンドウの外見を詳細に設定することができる。

QStyleクラスを継承した派生クラスを作成して、必要な項目のうち、比較的簡単に設定できる項目である。
QStyleクラスを継承した派生クラスは数種類用意されており、OSにより使用できるものが決まっている。

以下の例は、Qtに付属しているサンプルを参考にしている。(<Qtのインストールディレクトリ>/examples/widgets/stylesheetディレクトリ)
ここでは、examples/widgets/stylesディレクトリに合わせて、QMotifStyleクラスを継承した派生クラスを作成している。

設定後、QMainWindowクラスまたはQDialogクラスのコンストラクタにおいて、以下のように記述して適用する。

 QApplication::setStyle(new MyStyle);  // MyStyleクラスは、QMotifStyleクラスの派生クラス


ウィンドウの背景を画像にするには、まず、polishメソッドをオーバーライドする。
次に、画像を設定するためのsetTextureメソッド(メソッド名は任意)を作成する。

 #pragma once
 
 #include <QtGui/QMotifStyle>
 
 class MyStyle : public QMotifStyle
 {
 public:
    MyStyle();
    ~MyStyle();
 
    void polish(QPalette &palette);
 
 private:
    static void setTexture(QPalette &palette, QPalette::ColorRole role, const QPixmap &pixmap);
 };


polishメソッドとsetTextureメソッドは、以下のように記述する。
背景画像は、型抜き画像としても使用することができる。したがって、背景用画像と型抜き用画像の2つを用意する必要はない。

 void MyStyle::polish(QPalette &palette)
 {
    QPixmap backgroundImage("window.png");
 
    setTexture(palette, QPalette::Window, backgroundImage);
 }
 
 void MyStyle::setTexture(QPalette &palette, QPalette::ColorRole role, const QPixmap &pixmap)
 {
    for(int i = 0; i < QPalette::NColorGroups; ++i)
    {
       QColor color = palette.brush(QPalette::ColorGroup(i), role).color();
       palette.setBrush(QPalette::ColorGroup(i), role, QBrush(color, pixmap));
    }
 }


ボタンのスタイルの変更

上記のセクションにも記述したpolishメソッドを使用して、ボタンのスタイルを変更することができる。

QPaletteクラスのコンストラクタでは、ボタンの色を定義する。
ウィンドウおよびコントロールの設定の詳細は、Qtの公式WebサイトのQPalleteリファレンスを参照すること。

 void MyStyle::polish(QPalette &palette)
 {
    QPixmap backgroundImage("window.png");
 
    // 追加部分 : ボタンスタイルを変更
    palette = QPalette(QColor(0, 0, 0, 50));
    palette.setBrush(QPalette::ButtonText, Qt::cyan);
 
    setTexture(palette, QPalette::Window, backgroundImage);
 }


また、ボタンの背景を画像に変更するには、以下のように記述する。

 void MyStyle::polish(QPalette &palette)
 {
    QPixmap backgroundImage("window.png");
 
    // 追加部分 : ボタンの背景を画像にする場合
    QPixmap buttonImage("button.png");
 
    // 追加部分 : ボタンを押下した時の背景
    QPixmap midImage = buttonImage;
 
    setTexture(palette, QPalette::Button, buttonImage);
    setTexture(palette, QPalette::Mid, midImage);
    setTexture(palette, QPalette::Window, backgroundImage);
 }