Qt5再入門: Qt DesignerでNotes C APIコンバートシミュレーターダイアログを作る(その10/QGroupBoxとQTabWidget)
今回は、Qtウィジェットのグループボックスとタブウィジェットについて紹介します。
QGroupBox
QGroupBoxは、フレームとタイトルから構成されるウィジェットのコンテナです。それだけであれば単なる「見た目の囲い込み」ですが、このコンテナが特徴的なのは、チェックボックスを持つことができ、そのチェックの有無で囲い込んだウィジェットを有効/無効化することができる点です。
前回同様、ダイアログをQt Designerで開きます(前回までのウィジェットは削除してあります)。
左側にあるウィジェットペインの、「Containers」カテゴリーにある「Group Box」をドラッグして、ダイアログ上に持ってきてドロップします。
適当に広げておきます。
グループボックスのプロパティ「checkable」にチェックを付けると、タイトルの左脇にチェックボックスが出現します。
適当に入力ウィジェットをグループボックスの枠内に配置します。
少し下を空けておきましょう。
グループボックスの枠外に入力ウィジェットを適当に配置します。
保存してQt Designerを閉じ、Qt Creatorでコンパイルします。
QGroupBoxのデバッグ実行
ここまで配置したウィジェットを操作して、グループボックスのチェックボックスの働きを確認しておきましょう。
このように、グループボックスのチェックボックスからチェックを外すと、枠内に配置したウィジェットが一斉に無効化され、チェックを付けると元に戻ります。
QTabWidget
QTabWidgetは、タブバーと呼ばれる見出しタグと、タグ1つにページエリア1つが関連付いた、書類整理ファイルのようなコンテナです。Notesクライアントのワークスペースや、Visual Studio Codeのページ管理に似た見た目を持ちます。
QGroupBox同様、ダイアログをQt Designerで開きます(さきほどのウィジェットは削除してあります)。
左側にあるウィジェットペインの、「Containers」カテゴリーにある「Tab Widget」をドラッグして、ダイアログ上に持ってきてドロップします。
タブウィジェットの範囲内で右クリックしてコンテキストメニューを表示し、「ページを挿入」→「このページの後」を選択します。
「Tab 1」を選んだ状態でページを追加したので、真ん中に新しいページが挿入されました。
ページタブをドラッグして、一つ右、「Tab 2」の右側に来るようにします。
「Tab 1」を選択します。するとプロパティの「currentIndex」が0に変わります。
この状態でプロパティ「currentTabText」を「Line Edit」と変更します。
同様に「Tab 2」を選び、プロパティ「currentTabText」を「Spin Box」にします。
最後に先ほど追加したタブを選び、プロパティ「currentTabText」を「Date/Time Edit」にします。
Line EditタブにはLine Editウィジェットを配置します。
Spin BoxタブにはSpin Boxウィジェットを配置します。
Date/Time EditタブにはDate/Time Editウィジェットを配置します。
タブのオブジェクト名(objectName)を図のように変更します。
タブウィジェットの範囲外にコンボボックスを配置します。
保存してQt Designerを閉じ、Qt Creatorに戻ります。
コーディング
ダイアログのコンストラクタ内に、以下のように追記します。
// convertsimulatordialog.cpp
// ...
ConvertSimulatorDialog::ConvertSimulatorDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::ConvertSimulatorDialog)
{
ui->setupUi(this);
// 空っぽのコンボボックスにタブウィジェットのタブ名を追加する。
for (int i = 0; i < ui->tabWidget->count(); ++i) {
ui->comboBox->addItem(ui->tabWidget->tabText(i));
}
// コンボボックスの変更シグナルをタブウィジェットに接続する。
connect(
ui->comboBox, SIGNAL(currentIndexChanged(int)),
ui->tabWidget, SLOT(setCurrentIndex(int))
);
// タブウィジェットの切り替えシグナルをコンボボックスに接続する。
connect(
ui->tabWidget, SIGNAL(currentChanged(int)),
ui->comboBox, SLOT(setCurrentIndex(int))
);
// コンボボックスとタブウィジェットの最初の選択肢を設定する。
ui->comboBox->setCurrentIndex(0);
ui->tabWidget->setCurrentIndex(0);
}
// ...
ここまでの変更をすべてコンパイルします。
QTabWidgetのデバッグ実行
ご覧いただいたように、タブを切り替えるとコンボボックスのインデックスが変更され、コンボボックスを変更するとタブが切り替わるのがわかります。興味深いのは、互いの変更シグナルをもう一方が受け取っても、処理ループが発生していないことです。
まとめ
というか、「ちなみに・・・」な話。
QTabWidgetを使っていると、タブを追加ができるタブ(プラス記号のような)や、タブ名の横に×印アイコンを配置して削除する機能などを、タブバー上に組み込みたい衝動に駆られます。ですが、少なくとも5.14ではデフォルトでそのような機能はない(※訂正内容を後述)みたいです。タブを追加したり削除したりするメソッド自体はあるので、オープンソースの利点を活かして、タブウィジェットを改造/カスタムして、追加タブや削除アイコンの組み込みを実現されている方もいらっしゃるようです。挑戦してみたい方は、そのような達人の門を叩いてみてはいかがでしょうか。
(2021/9/29追記)上記で削除機能はデフォルトでないと書いていますが、その後の調査でオプションスイッチをオンにすることで削除ボタンが有効になります。QTabWidget::tabsClosableをtrueにすると、タブに×ボタンが表示されます。ただし、これをオンにしても実際に削除できるようになるわけではなく、tabCloseRequested(int index)というシグナルが送出されるようになります。なので、実際にタブを削除処理するスロットを実装して、そこに接続することで実現できます。なお、+ボタンについてはデフォルトで装備できるという情報は、現時点では見つかっておりません。