Qtの基礎 - ダイアログ

提供:MochiuWiki : SUSE, EC, PCB
ナビゲーションに移動 検索に移動

概要



ダイアログの種類

下表に、Qtにおいて、標準で存在するダイアログの種類を示す。

用途 クラス名
ファイル・ディレクトリ選択 QFileDialog
色選択 QFontDialog
インプットボックス QInputDialog
プログレスバー QProgressDialog
印刷関連 QPrintDialog
メッセージボックス QMessageBox



ファイル・ディレクトリ選択ダイアログ

QFileDialogクラス

下表に、用途別にQFileDialogのメソッドを示す。

メソッド 用途 戻り値
getOpenFileName ローカルファイル選択(開く) QString
getOpenFileNames 複数ローカルファイル選択(開く) QStringList
getOpenFileUrl リモートファイル選択(開く) QUrl
getOpenFileUrls 複数リモートファイル選択(開く) QList<QUrl>
getSaveFileName ローカルファイル選択(保存) QString
getSaveFileUrl リモートファイル選択(保存) QUrl
getExistingDirectory ローカルフォルダ選択 QString
getExistingDirectoryUrl リモートフォルダ選択 QUrl


フィルタを指定すると、拡張子で絞ってファイルを表示することができる。

# 書式フォーマット
[書式];;見出し(拡張子1 拡張子2 ...) [;;見出し(拡張子1 ...)]

# 例
すべて(*.*);;音声(*.wav *.wma *.mp3);;動画(*.wmv *.avi)


下表に、QFileDialogクラスのオプションを示す。(enum QFileDialog::Option)

定義 説明
ShowDirsOnly 0x00000001 フォルダのみ表示する。
(FileModeDirectoryの時に有効)
DontResolveSymlinks 0x00000002 シンボリックリンクを解釈しない。
(指定しない場合、解釈する)
DontConfirmOverwrite 0x00000004 既存ファイル選択時に確認画面を表示しない。
(指定しない場合、表示する)
DontUseNativeDialog 0x00000010 OS標準のダイアログを使用しない。
(指定しない場合、使用する)
ReadOnly 0x00000020 ReadOnlyを表示する。
HideNameFilterDetails 0x00000040 ファイル名フィルタの詳細が隠されているか示す。
DontUseCustomDirectoryIcons 0x00000080 ディレクトリのアイコンは常に標準のものを使用する。
ただし、カスタムアイコンを使用すると負荷が大きいため、
ディレクトリのアイコンは常に標準のものを使用した方がよい。


※注意
シンボリックリンク(ショートカット)を選択しても、ディレクトリ欄には表示されない。

また、DontResolveSymlinksを指定すると、シンボリックリンク(ショートカット)を選択した場合、エラーメッセージを出力する。
指定しない場合、シンボリックリンク(ショートカット)を解釈するため、リンク先のファイルまたはディレクトリを選択したことになる。

ファイル選択ダイアログ

ファイルを開く(getOpenFileNameメソッド)

ファイルとディレクトリの一覧を表示する。
getOpenFileNameメソッドは、ファイルを1つ選択できる。

# 書式フォーマット
[書式] 親, タイトル, パス, フィルター, 選択フィルタ, オプション


以下の例では、初期表示のパスを/home/<ユーザ名>、フィルタを2番目のフィルタ(*.txt)として表示する。
getOpenFileNameメソッドの戻り値には、選択したファイル名がフルパスで代入される。(キャンセルした場合、空文字が代入される)
変数SelFilterには、初期に選択するフィルターが入る。(キャンセルした場合、元のままになる)

 QString SelFilter = tr("テキスト(*.txt)");
 QString FileName = QFileDialog::getOpenFileName(this, tr("ファイルを開く"), "~/", tr("すべて(*.*);;テキスト(*.txt);;ソース(*.h *.cpp)"),
                                                 &SelFilter, QFileDialog::DontUseCustomDirectoryIcons);
 
 if(FileName.isEmpty())
 {  // キャンセル
    // キャンセル処理を記述
 }


また、引数を全て省略する場合、標準のダイアログが表示される。
標準のダイアログとは、タイトルは"開く"、初期表示のパスは"実行ファイルが存在するディレクトリ"となる。
また、フィルタ欄は表示されない。

 QString fileName = QFileDialog::getOpenFileName();


名前を付けて保存(getSaveFileNameメソッド)

getSaveFileNameメソッドを使用して、ファイルを1つ保存することができる。
既に同じ名前のファイルが存在する場合、上書きの確認メッセージが表示される。

[書式] getSaveFileName(親ウインドウのポインタ, ダイアログのタイトル, 初期表示のパス, フィルタ, 選択フィルタ, オプション)


パスに.(カレントディレクトリ)を指定する時、実行ファイルが存在するディレクトリを表示する。
getSaveFileNameメソッドの戻り値は、選択したファイル名のフルパスである。(キャンセルした場合、空文字となる)
選択フィルタ(下例では、変数SelFilter)には、選択したフィルタが代入される。(キャンセルした場合、元のままとなる)
選択フィルタ(下例では、変数SelFilter)を指定しない場合、フィルタの初期表示はフィルタの1つ目の要素(下例では、*.tif *.tiff)となる。

 QString SelFilter = "";
 QString FileName = QFileDialog::getSaveFileName(this, tr("名前を付けて保存"), ".", 
                                                 tr("TIFF image document(*.tif *.tiff);;Portable network graphic(*.png)"),
                                                 &SelFilter, QFileDialog::DontUseCustomDirectoryIcons);
 if(FileName.isEmpty())
 {  // キャンセル
    // キャンセル処理を記述
 }


getSaveFileNameメソッドの引数を全て省略する時、標準のダイアログが表示される。
この時、ダイログのタイトルは"名前を付けて保存"、初期表示のパスは"実行ファイルが存在するディレクトリ"となる。
また、フィルタ欄と既存ファイルの上書き確認メッセージは表示される。

 QString FileName = QFileDialog::getSaveFileName();


ディレクトリ選択ダイアログ(getExistingDirectoryメソッド)

getExistingDirectoryメソッドを使用して、ディレクトリの一覧を表示する。
ディレクトリを1つ選択することができる。

# 書式フォーマット
[書式] getExistingDirectory(親ウインドウのポインタ, ダイアログのタイトル, 初期表示のパス, オプション)


QFileDialog::Optionsにおいて、ShowDirsOnlyを指定することで、ディレクトリのみ表示することができる。
getExistingDirectoryメソッドの戻り値は、選択したディレクトリ名のフルパスである。(キャンセルした場合、空文字となる)
また、以下のメッセージに対応するため、オプションにHideNameFilterDetailsを指定する。

selectNameFilter: Invalid parameter 'Directories' not found in 'All Files (*)'.


 QFileDialog::Options options = QFileDialog::ShowDirsOnly | QFileDialog::HideNameFilterDetails | QFileDialog::DontUseCustomDirectoryIcons;
 QString DirName = QFileDialog::getExistingDirectory(this, tr("ディレクトリの選択"), "~/", options);
 
 if(DirName.isEmpty())
 {  // キャンセル
    // キャンセル処理を記述
 }


また、オプションにDontUseNativeDialogを指定する時、下図に示すダイアログが表示される。


getExistingDirectoryメソッドの引数を全て省略する場合、標準のダイアログが表示される。
この時、タイトルは"フォルダーの選択"、初期表示のパスは"実行ファイルが存在するディレクトリ"となる。

 QString DirName = QFileDialog::getExistingDirectory();



色選択ダイアログ(QColorDialogクラス)

RGBを10進または16進で入力できる色選択ダイアログである。

getColorメソッドを使用すると、Qt標準の色選択ダイアログを表示する。

[書式] getColor(色, 親ウインドウのポインタ, ダイアログのタイトル, オプション)


以下の例では、初期表示として、青で透明度を指定している。

getColorメソッドの戻り値は、選択した色情報クラスである。(キャンセルした場合、Validがfalseになる)
色は、#AARRGGBB形式、#RRGGBB形式、Qt定義色(Qt::red等)で指定する。
透明度(AA、アルファチャンネル)を省略する時、初期値は255となる。
ShowAlphaChannelオプションを指定しない場合、AAに初期値を指定しても戻り値は固定でFF(255)となる。

 QColor color = QColorDialog::getColor("#800a64c8", this, tr("色選択"), QColorDialog::ShowAlphaChannel);
 
 if(color.isValid())
 {
    // color.name();  → "#0a64c8" (#RRGGBB)
    // color.name(QColor::HexArgb);  → "#800a64c8" (#AARRGGBB)
    // int r, g, b, a;
    // color.getRgb(&r, &g, &b, &a);  → r=10, g=100, b=200, a=128
 }


QColorDialogのオプション(enum QColorDialog::ColorDialogOption)

オプション名 説明
ShowAlphaChannel 0x00000001 アルファチャンネル(透明度)を表示する。
NoButtons 0x00000002 OKとキャンセルのボタンを表示しない。
(ライブダイアログで役立つ)
DontUseNativeDialog 0x00000004 OS標準ではなくQt標準の色選択を使用する。
(指定しない場合、有効)。


getColorメソッドの引数を全て省略する時、標準のダイアログが表示される。
この時、標準ダイアログのタイトルは"Select Color"、色は白(#ffffff)、アルファチャンネルの項目は無い。

 QColor color = QColorDialog::getColor();



フォント選択ダイアログ(QFontDialog)

フォント選択ダイアログは、フォントを選択できるダイアログである。
QFontDialogクラスのgetFontメソッドは、Qt標準のフォント選択ダイアログを表示する。

[書式1] getFont(結果, 初期フォント, 親ウインドウのポインタ, ダイアログのタイトル, オプション)
[書式2] getFont(結果, 親ウインドウのポインタ)


以下の例では、初期フォントを18pxのCourier、等幅フォントとしている。
getFontメソッドの戻り値は、選択したフォント情報のクラスである。(キャンセルした場合、第1引数はfalseとなる)
[Esc]キーを押下する場合は、キャンセルしたものと見なされる。

 bool ok;
 QFont font = QFontDialog::getFont(&ok, QFont("Courier", 18), this, tr("フォント選択"), QFontDialog::MonospacedFonts);
 
 if(ok)
 {
    // font.family();  → "Courier"
    // font.pointSize();  → 18
    // font.italic();  → false (true:Font styleがItalic)
    // font.bold();  → false (true:Font styleがBold)
    // font.weight();  → 50 (bold()=trueの時は75)
    // font.strikeOut();  → false (true:EffectsのstrikeOutオン)
    // font.underline();  → false (true:Effectsのunderlineオン)
 }


QFontDialogクラスのオプション(enum QFontDialog::FontDialogOption)

オプション名 説明
NoButtons 0x00000001 [OK]ボタンと[キャンセル]ボタンを表示しない。
(ライブダイアログで役立つ)
ただし、ダイアログ右上の[閉じる]ボタンが使用できなくなる。
DontUseNativeDialog 0x00000002 OS標準ではなくQt標準のフォント選択を使用する。
指定しない場合、Qt標準のフォント選択を使用する。
ScalableFonts 0x00000004 スケーラブルフォントを表示する。
スケーラブルフォントとは、拡大縮小しても精度の変わらないフォントである。
NonScalableFonts 0x00000008 スケーラブルフォント以外を表示する。
MonospacedFonts 0x00000010 等幅フォントを表示する。
ProportionalFonts 0x00000020 可変幅フォントを表示する。


第1引数は必須であり、他の引数を全て省略する時、標準のフォント選択ダイアログが表示される。
この時、ダイアログのタイトルは"Select Font"、使用可能なフォントをアルファベット順に並べて、その先頭が選択された状態となる。

 bool ok;
 QFont font = QFontDialog::getFont(&ok);



インプットダイアログ



印刷ダイアログ

QPrintDialogクラス

印刷ダイアログにおいて、使用する場合は以下のヘッダファイルをインクルードする必要がある。

#include <QtPrintSupport>


また、プロジェクトファイル(.proファイル)に、以下のモジュールを追記する必要がある。

QT += core gui printsupport


下表に示すように、印刷ダイアログには、様々な支援クラスがある。

印刷ダイアログを使用する場合は、描画デバイスが必要である。
ページ設定等は、印刷ダイアログに組み込まれている。

印刷関連クラス

クラス名 説明
QAbstractPrintDialog 印刷ダイアログの抽象クラス
QPageSetupDialog ページ設定
QPrintDialog 印刷ダイアログ
QPrintEngine 印刷サブシステムとのインターフェース定義
QPrintPreviewDialog 印刷出力レイアウトのプレビューダイアログ
QPrintPreviewWidget 印刷プレビューウィジェット
QPrinter プリンタに出力する描画デバイス
QPrinterInfo 既存プリンタの情報


テキスト印刷

文字の印刷は、QTextDocumentを使用すると簡単にできる。

QTextEditクラス等は、QTextDocumentを取得できるので、テキストをセットする手間が省ける。

 QPrinter printer(QPrinter::HighResolution);
 
 QPrintDialog dialog(&printer, this);
 if(dialog.exec() == QDialog::Accepted)
 {
    QTextDocument doc;
    doc.setPlainText("テキスト印刷のサンプルです。\n改行しました。");
    doc.print(&printer);
 }


画像印刷

以下の例では、画像ファイル(image.jpgファイル)の縦横比を崩さずに、できるだけ大きなサイズで印刷している。

  1. 印刷領域の横と縦から、縦横比を崩さずに画像が収まるサイズを求める。
  2. 求めたサイズで、印刷領域の横と縦を変更する。
  3. 描画領域を画像サイズにして画像を描けば、自動的にサイズ調整と印刷領域への転送が行われる。
  • setViewportメソッドを使用して、印刷領域のサイズを変更しない場合、縦横比が崩れる。
  • setWindowメソッドを使用して、描画領域のサイズを変更しない場合、小さな画像になる。
 QPrinter printer(QPrinter::ScreenResolution);
 
 QPrintDialog dialog(&printer, this);
 if(dialog.exec() == QDialog::Accepted)
 {
    QPainter painter(&printer);
    QRect rect = painter.viewport();
    QPixmap pixmap("~/tmp/image.jpg");
    QSize size = pixmap.size();
    size.scale(rect.size(), Qt::KeepAspectRatio);
 
    painter.setViewport(rect.x(), rect.y(), size.width(), size.height());
    painter.setWindow(pixmap.rect());
    painter.drawPixmap(0, 0, pixmap);
 }


ウィジェット印刷

以下の例では、縦横比を崩さずに、横200pxでwidgetを印刷している。

  1. widgetクラスのgrabメソッドを使用して、QPixmapクラスを生成する。(widgetの子要素も含まれる)
  2. 生成したQPixmapクラスの横を200pxにして描画する。縦は横に合わせて自動的に伸縮される。
 QPrinter printer(QPrinter::ScreenResolution);
 
 QPrintDialog dialog(&printer, this);
 if(dialog.exec() == QDialog::Accepted)
 {
    QPixmap pixmap = widget->grab();
    QPainter painter(&printer);
    painter.drawPixmap(0, 0, pixmap.scaledToWidth(200));
 }


印刷プレビュー

以下の例では、用紙にA4縦を指定して印刷プレビューを表示している。
実際の描画は、redrawPreviewメソッド(ユーザ定義メソッド)で行う。

用紙のサイズと向きは、プレビュー画面で設定できるため、省略可能である。
プレビュー画面のサイズを指定しないと、とても小さな表示になるので注意すること。

設定変更による描画要求シグナルには、redrawPreviewメソッド(ユーザ定義メソッド)を接続する。
execメソッドを使用して、印刷プレビュー画面を表示する。(プレビュー画面を閉じるまで制御は戻らない)

 // mainwindow.cpp
 
 QPrinter printer(QPrinter::HighResolution);
 printer.setPaperSize(QPrinter::A4);
 printer.setOrientation(QPrinter::Portrait);
 
 QPrintPreviewDialog preview(&printer, this);
 preview.setFixedSize(this->width() - 100, this->height());

 connect(&preview, SIGNAL(paintRequested(QPrinter*)), this, SLOT(redrawPreview(QPrinter*)));
 
 preview.exec();


描画関数redrawPreviewメソッド(ユーザ定義メソッド)は、ヘッダファイルのスロットで宣言する。

 // mainwindow.h
 
 private slots:
    void redrawPreview(QPrinter *printer);


以下の例では、メイン画面のハードコピーを印刷プレビューに表示している。
用紙全体がプレビュー画面に収まるように、自動的に縮小表示される。
[ページ設定]画面の用紙の向きを変更する場合、自動的に伸縮率が変化する。

QPixmapクラスの生成以外は、画像印刷と同じ処理となる。

 void MainWindow::redrawPreview(QPrinter *p)
 {
    QPainter painter(p);
    QRect rect = painter.viewport();
    QPixmap pixmap = this->grab();
    QSize size = pixmap.size();
    size.scale(rect.size(), Qt::KeepAspectRatio);
 
    painter.setViewport(rect.x(), rect.y(), size.width(), size.height());
    painter.setWindow(pixmap.rect());
    painter.drawPixmap(0, 0, pixmap);
 }


画像の印刷解像度(dpi)を設定する

画像ファイルで見かける解像度は、印刷解像度である。
すなわち、dpiとは紙上1インチに表現する画素数の値のことである。

例えば、1440[px] x 1440[px]、72[dpi]の画像を印刷する場合、紙上のサイズは、1440[px] / 72[dpi] = 20[inch] = 508[mm]となる。

以下の例では、上記の値をQImageクラスに設定して保存している。

 // ドット / メートルに変換(72dpiの場合)
 int dpm = 72 / 0.0254;
 
 // 水平方向と垂直方向を別個に指定できる
 qimg.setDotsPerMeterX(dpm);
 qimg.setDotsPerMeterY(dpm);
  
 // dpiをファイル内に保持できるフォーマットのみ保存できる
 qimg.save(arrPath, "JPEG", -1);



プログレスバーダイアログ

QProgressDialogクラスを使用して、標準で用意されているプログレスバーダイアログを表示する。

QProgressDialogクラスの最後の引数はウインドウフラグであるが、ここでは使用しないため省略している。

[書式1] QProgressDialog <変数名>(親ウインドウのポインタ)
[書式2] QProgressDialog <変数名>(表示文字列, キャンセルボタン文字列, 最小値, 最大値, 親ウインドウのポインタ)


以下の例では、プログレスバーにおいて、500[ms]ごとに10%ずつ増加させて表示している。

 QProgressDialog ProgressDlg(tr("しばらくお待ちください・・・"), tr("キャンセル"), 0, 200, this);
 ProgressDlg.setWindowModality(Qt::WindowModal);
 ProgressDlg.setWindowTitle(tr("処理中"));
 ProgressDlg.show();
 
 for(int cnt = 0; cnt < 200; cnt += 20)
 {
    QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
    ProgressDlg.setValue(cnt);
 
    if(ProgressDlg.wasCanceled())
    {
       break;
    }
 
    Sleep(500);
 }
 
 progress.setValue(200);


また、全ての引数を省略する場合、標準のプログレスバーダイアログが表示される。
表示文字列は無し、キャンセルボタンのラベル名は"Cancel"、プログレスバーの最小値は0、最大値は100となる。

 QProgressDialog progress;



モーダルダイアログ

 // mainwindow.cpp
 void MainWindow::OnBtnClicked()
 {
    ModalDialog ModalDlg;
    ModalDlg.setModal(true);
    ModalDlg.exec();
 }



モードレスダイアログ

 // mainwindow.h
 
 #ifndef MAINWINDOW_H
 #define MAINWINDOW_H
 
 #include <QMainWindow>
 #include "ModelessDialog.h"
 
 namespace Ui
 {
    class MainWindow;
 }
 
 class MainWindow : public QMainWindow
 {
    Q_OBJECT
 
 public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
 
 private slots:
    void on_pushButton_clicked();
 
 private:
    Ui::MainWindow *ui;
    std::unique_ptr<ModelessDialog> ModelessDlg;
 };
 
 #endif // MAINWINDOW_H


 // mainwindow.cpp
 
 void MainWindow::OnBtnClicked()
 {
    ModelessDlg = std::make_unique<ModelessDialog>(this);
    ModelessDlg->show();
 }


モードレスダイアログ等を常に前面に表示する場合は、以下のように記述する。

 ModelessDlg = std::make_unique<ModelessDialog>(this);
 
 ModelessDlg->setWindowFlags(Qt::WindowStaysOnTopHint);
 
 ModelessDlg->show();



カスタムダイアログ

カスタムダイアログは、自由にレイアウト可能なダイアログである。
QDialogクラスを使用して作成することができる。

以下の例では、メール送信用のダイアログを作成している。(ただし、レイアウトと結果の取得のみ対応)

[OK]ボタンを押下する時、acceptedシグナルが発行されて、[CANCEL]ボタンを押下する時、rejectedシグナルが発行される。
各スロットは標準で用意されているため、任意の処理を記述せずに1または0を返す。
また、サイズグリップは表示されないが、ウインドウのサイズは自由に変更できる。

 QFormLayout Form();
 Form.setLabelAlignment(Qt::AlignRight);
 Form.addRow(tr("送信先 :"), new QLineEdit);
 Form.addRow(tr("件名 :"), new QLineEdit);
 Form.addRow(tr("本文 :"), new QTextEdit);
 
 QDialogButtonBox BtnBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal);
 BtnBox.button(QDialogButtonBox::Ok)->setText(tr("送信"));
 BtnBox.button(QDialogButtonBox::Cancel)->setText(tr("閉じる"));
 
 QVBoxLayout vbox;
 vbox.addLayout(Form);
 vbox.addWidget(BtnBox);
 
 QDialog Dlg(this);
 Dlg.setModal(true);
 Dlg.setWindowTitle(tr("メール送信"));
 Dlg.setLayout(vbox);
 
 connect(BtnBox, SIGNAL(accepted()), Dlg, SLOT(accept()));
 connect(BtnBox, SIGNAL(rejected()), Dlg, SLOT(reject()));
 
 // 1 : Ok(送信), 0 : Cancel(閉じる)
 int iRet = Dlg.exec();


以下の例では、6つの選択ボタンを表示している。

各ボタンにはプロパティを設定してボタン番号を設定する。(buttonNoは任意の名前である)
全てのボタンのイベントは、スロットexitDialogで処理する。

最小サイズと最大サイズを同じ値に設定することで、ダイアログのサイズを固定している。
サイズグリップをオフにしても、サイズ変更不可にはならない。

ダイアログ右上の[x]ボタンを押下した場合、buttonは0になる。

 QStringList List;
 List << "グルメツアー" << "買い物ツアー" << "農業体験ツアー";
 List << "工場見学" << "寺社巡り" << "歴史に触れる旅";
 
 QLabel Label("コースを選択してください。");
 Label.setFixedHeight(30);
 
 QGridLayout Grid;
 Grid.setContentsMargins(20, 16, 20, 24); // left, top, right, bottom
 Grid.setHorizontalSpacing(20);
 Grid.setVerticalSpacing(0);
 
 for(int i = 0; i < 3; i++)
 {
    QLabel LabelCourse(QString((int)'A' + i) + " コース");
    LabelCourse.setFixedHeight(20);
    Grid.addWidget(LabelCourse, 0, i, Qt::AlignHCenter);
 
    QPushButton Btn(List[i]);
    Btn.setFixedSize(150, 40);
    Btn.setStyleSheet("background:green; color:lightyellow;");
    Btn.setProperty("buttonNo", i + 1);
 
    connect(&Btn, SIGNAL(clicked()), this, SLOT(exitDialog()));
 
    Grid.addWidget(&Btn, 1, i, Qt::AlignHCenter);
 }
 
 Grid.addWidget(new QLabel(""), 2, 0, 1, 3);
 
 for(int i = 0; i < 3; i++)
 {
    QLabel *label = new QLabel(QString((int)'D' + i) + " コース");
    label->setFixedHeight(20);
    Grid.addWidget(label, 3, i, Qt::AlignHCenter);
 
    QPushButton *pbtn = new QPushButton(list[i+3]);
    pbtn->setFixedSize(150, 40);
    pbtn->setStyleSheet("background:green; color:lightyellow;");
    pbtn->setProperty("buttonNo", i + 3 + 1);
 
    connect(pbtn, SIGNAL(clicked()), this, SLOT(exitDialog()));
 
    Grid.addWidget(pbtn, 4, i, Qt::AlignHCenter);
 }
 
 QWidget Widget;
 Widget.setLayout(&Grid);
 Widget.setStyleSheet("background:lightyellow;");
 
 QPushButton BtnQuit("どれも選ばない");
 BtnQuit.setProperty("buttonNo", 0);
 connect(&BtnQuit, SIGNAL(clicked()), this, SLOT(exitDialog()));
 
 QVBoxLayout vbox;
 vbox.addWidget(Label);
 vbox.addWidget(Widget);
 vbox.addStretch();
 vbox.addWidget(BtnQuit);
 
 QDialog Dlg(this);
 Dlg.setModal(true);
 Dlg.setWindowTitle(tr("ご案内"));
 Dlg.setSizeGripEnabled(false);
 Dlg.setMinimumSize(560, 290);
 Dlg.setMaximumSize(560, 290);
 Dlg.setLayout(vbox);
 
 // 0 : 選択しない, 1~6 : グルメ ~ 歴史に触れる
 int iRet = Dlg.exec();


mainwindow.hファイルにスロットの宣言を記述する。

 // mainwindow.h
 
 private slots:
    void exitDialog();


スロットの処理を記述する。

シグナルの送信元を調べて、QDialogであれば閉じる。
送信元のウインドウがQDialogではない場合、処理は実行しない。
buttonNoプロパティの値を取得してdoneメソッドを実行すると、ダイアログを閉じてexecメソッドの戻り値に変数iNoを渡す。

 // mainwindow.cpp
 
 void MainWindow::exitDialog()
 {
    QWidget *Window = static_cast<QWidget *>(sender())->window();
 
    if(win->inherits("QDialog"))
    {
       QDialog *Dlg = static_cast<QDialog *>(win);
       int iNo = (sender()->property("buttonNo")).toInt();
       Dlg->done(iNo);
    }
 }



メッセージボックス(QMessageBoxクラス)

QMessageBoxクラスを使用して、メッセージボックスを表示する。

[書式] QMessageBox <変数名>(親ウインドウのポインタ, タイトル, 表示文字列, ボタン, デフォルト)


QMessageBoxクラスのアイコン(enum QMessageBox::Icon)

アイコン 説明 標準Pixmap
NoIcon 0 アイコンなし
Information 1 情報 SP_MessageBoxInformation
Warning 2 警告 SP_MessageBoxWarning
Critical 3 重大な問題 SP_MessageBoxCritical
Question 4 質問 SP_MessageBoxQuestion


簡素なメッセージボックス

状況に応じて、以下に示す4種類を使い分ける。
変数iRetには、QMessageBox::YesまたはQMessageBox::Noのいずれかが入る。
また、QMessageBox::questionは、ボタンを指定しない場合でも[Yes]ボタンと[No]ボタンが表示される。

 QMessageBox::information(this, tr("情報"), tr("メッセージ"));
 QMessageBox::warning(this, tr("警告"), tr("メッセージ"));
 QMessageBox::critical(this, tr("致命的エラー"), tr("メッセージ"));
 
 int iRet = QMessageBox::question(this, tr("確認"), tr("メッセージ"));


標準のメッセージボックス

複数のボタンを表示して選択されたボタンを返す。

書式1は最初の3つの引数が必須、書式2は必要な情報を後で指定する。
書式1の最後の引数にはウインドウフラグがあるが、ここでは省略している。

[書式1] QMessageBox <変数名>(アイコン, タイトル, 表示文字列, ボタン, 親ウインドウのポインタ)
[書式2] QMessageBox <変数名>(親ウインドウのポインタ)


以下の例では、上記の書式1の形式でメッセージボックスを表示している。

 QMessageBox MsgBox(QMessageBox::Question, tr("確認"), tr("これでよろしいですか?"), 
                    QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, this);
 
 int iRet = MsgBox.exec();


以下の例では、上記の書式2の形式でメッセージボックスを表示している。
setDefaultButtonメソッドにより、標準でフォーカスが当たるボタンを指定できる。

 QMessageBox MsgBox(this);
 
 MsgBox.setIcon(QMessageBox::Question);
 MsgBox.setWindowTitle(tr("確認"));
 MsgBox.setText(tr("これでよろしいですか?"));
 MsgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
 MsgBox.setDefaultButton(QMessageBox::Cancel);
 MsgBox.setButtonText(QMessageBox::Yes, tr("OK"));
 MsgBox.setButtonText(QMessageBox::No, tr("Cancel"));
 MsgBox.setButtonText(QMessageBox::Cancel, tr("Back"));
 
 int iRet = MsgBox.exec();


ボタンについて

QMessageBoxクラスでは、様々なボタンが用意されている。
各ボタンには意味があるため、それに応じて使用する必要がある。

ボタンは記述した順番で並ぶわけではないので注意すること。
[Cancel]ボタンを記述しない場合、メッセージボックス右上の[x]ボタンが使用できなくなる可能性がある。

QMessageBoxクラスのボタン(enum QMessageBox::StandardButton)

ボタン名 説明 役割名
Ok 0x00000400 了解 AcceptRole
Open 0x00002000 開く AcceptRole
Save 0x00000800 保存 AcceptRole
Cancel 0x00400000 キャンセル RejectRole
Close 0x00200000 閉じる RejectRole
Discard 0x00800000 破棄または保存しない DestructiveRole
Apply 0x02000000 現在の変更を適用する ApplyRole
Reset 0x04000000 リセット ResetRole
RestoreDefaults 0x08000000 デフォルトに戻す ResetRole
Help 0x01000000 ヘルプ HelpRole
SaveAll 0x00001000 全て保存 AcceptRole
Yes 0x00004000 はい YesRole
YesToAll 0x00008000 全てはい YesRole
No 0x00010000 いいえ NoRole
NoToAll 0x00020000 全ていいえ NoRole
Abort 0x00040000 異常終了 RejectRole
Retry 0x00080000 再試行 AcceptRole
Ignore 0x00100000 無視 AcceptRole
NoButton 0x00000000 ボタンなし 無効


下表に、各ボタンの役割を示す。

QMessageBoxクラスのボタンの役割(enum QMessageBox::ButtonRole)

ロール名 説明
InvalidRole -1 無効
AcceptRole 0 同意および受諾
(OK, Save, SaveAll, Open, Retry, Ignore)
RejectRole 1 拒否
(Abort, Close, Cancel)
DestructiveRole 2 変更を破棄して閉じる。
(Discard)
ActionRole 3 ダイアログ内の要素を変更する。
HelpRole 4 ヘルプ要求
(Help)
YesRole 5 受諾または全て受諾
(Yes, YesToAll)
NoRole 6 拒否または全て拒否
(No, NoToAll)
ResetRole 7 ダイアログ内の項目をデフォルトに戻す。
(Reset, RestoreDefaults)
ApplyRole 8 変更を適用する。
(Apply)


プッシュボタン追加

メッセージボックスに任意のボタンを追加する場合、以下のように記述する。
任意のボタンでは、役割も指定する必要がある。

 QMessageBox MsgBox(this);
 
 QPushButton *anyButton = MsgBox.addButton(tr("hoge"), QMessageBox::ActionRole);
 
 MsgBox.setWindowTitle(tr("hogeボタンの表示"));
 MsgBox.setText(tr("メッセージ"));
 MsgBox.exec();
 
 if(MsgBox.clickedButton() == anyButton)
 {  // [hoge]ボタンが押下された場合
    // 処理を記述
 }


概要ダイアログ

Qtのライセンス等の情報を表示する。

 QMessageBox MsgBox;
 MsgBox.aboutQt(this, tr("Qtについて"));


以下の例では、ソフトウェアの説明を表示している。
aboutメソッドでは、必ずソフトウェアのアイコンが表示される。

 QString strOverView = "<span style=\"font-weight:bold\">Qtサンプル画面</span><br><br>"
                       "このプログラムはQt C++で作成したものです。<br>"
                       "いろいろなレイアウトやウィジェットの使用例が入っています。<br><br>"
                       "※ご注意<br>"
                       "必ずしもこの使用法が正しいとは限りません。<br>"
                       "自分で使うプログラムとしては十分動くというだけです。<br>"
                       "何の保証もありませんので、自己責任でお使いください。<br><br>"
                       "Top Page: "
                       "<a href=\"http://www.sample.com/index.html\">"
                       "http://dorafop.my.coocan.jp/index.html</a>";
 
 QMessageBox MsgBox;
 MsgBox.about(this, tr("このプログラムについて"), strOverView);


QMessageBoxクラスにおいて、任意のアイコンを表示する場合は、以下のように記述する。

 QMessageBox MsgBox(this);
 MsgBox.setText(text);
 MsgBox.setWindowTitle(tr("このプログラムについて"));
 MsgBox.setIconPixmap(QPixmap(":/images/logo.png"));
 
 MsgBox.exec();



ステータスバー

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

 #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);