Qtの基礎 - ダイアログ

提供:MochiuWiki - SUSE, Electronic Circuit, PCB
2021年1月27日 (水) 16:10時点におけるWiki (トーク | 投稿記録)による版 (→‎モーダルダイアログ)
ナビゲーションに移動 検索に移動

概要



ダイアログの種類

下表に、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);



インプットダイアログ



印刷ダイアログ



プログレスバー



モーダルダイアログ

 // 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();
 }



カスタムダイアログ



メッセージボックス(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();