Qt5再入門: ブックマークの保存、復元
前回、ブックマークテーブルビューを中心に、アクションを追加したり、コンテキストメニューを作ったりしながらブックマークを追加、削除するロジックを作りました。しかしながら、このままではせっかく追加したブックマークもアプリ終了とともに消えてしまいます。
今回は、以前紹介した「状態の保存」、「状態の読み込み」機能を使って、このブックマークデータを保存、復元できるようにしたいと思います。
QVariant型に収める
ブックマークデータは、メモリ上次のようなイメージで格納されています。
QList<std::tuple<QStandardItem,QStandardItem,QStandardItem>>
または
QList<std::tuple<QString,QString,QString>>
これをQSettingsで保存可能な値、QVariant型に当てはめようとした場合、次のような方でやり取りできそうです。
QList<QList<QString>> → QList<QStringList> → QList<QVariant> → QVariantList
そこで、1つ1つのブックマークデータは要素3つのQStringList、ブックマークリスト全体ではQVariantListとして、QSettingsとやり取りすることにします。
ブックマークデータの保存
以前、「状態の保存」で紹介したMainWindow::saveSettingsメソッドに、ブックマークを保存するロジックを追加します。
// mainwindow.cpp
// ...
void MainWindow::saveSettings() const {
// 設定を初期化
QSettings settings;
// ウィンドウを最大化しているかを保存
settings.setValue("maximized", isMaximized());
// 最大化していなければ
if (!isMaximized()) {
// 位置情報を保存
settings.setValue("geometry/pos", frameGeometry().topLeft());
// サイズ情報を保存
settings.setValue("geometry/size", geometry().size());
}
// ブックマーク情報を保存
QVariantList list;
for (int i = 0; i < pModel_->rowCount(); ++i) {
QList<QStandardItem*> rows = pModel_->rowItems(i);
QStringList data;
for (int c = 0; c < 3; ++c) {
data << rows[c]->data(Qt::DisplayRole).toString();
}
list << data;
}
settings.setValue("bookmarks", list);
}
// ...
ブックマークデータの復元
同様に、「状態の読み込み」で紹介したMainWindow::loadSettingsに、ブックマークデータを復元するロジックを追加します。
// mainwindow.cpp
// ...
void MainWindow::loadSettings() {
// 設定を初期化
QSettings settings;
// ウィンドウの最大化を取得
bool maximized = settings.value("maximized", false).toBool();
// 最大化していなければ
if (!maximized) {
// デスクトップ情報とデフォルト値
QDesktopWidget d;
constexpr int dw = 800;
constexpr int dh = 600;
// 位置情報を取得し移動
move(settings.value(
"geometry/pos",
QPoint((d.width() - dw) / 2, (d.height() - dh) / 2)
).toPoint()
);
// サイズ情報を取得しウィンドウをリサイズ
resize(settings.value(
"geometry/size",
QSize(dw, dh)).toSize()
);
}
// 最大化していれば
else {
// ウィンドウを最大化
showMaximized();
}
// ブックマークデータを取得し、再現
QVariantList list = settings.value("bookmarks", QVariantList()).toList();
for (const QVariant &item : list) {
QStringList data = item.toStringList();
pModel_->appendRow(
QList<QStandardItem*>()
<< new QStandardItem(data.at(0))
<< new QStandardItem(data.at(1))
<< new QStandardItem(data.at(2))
);
}
ui_->bookmarksView->resizeColumnsToContents();
}
// ...
最後のresizeColumnsToContentsは、表示されているモデルデータ(Contents)に合わせて、列幅をリサイズするというものです。
レジストリを確認してみる
今回作成したブックマークも含め、レジストリにどのように格納されているか、確認してみます。
この中のbookmarksがブックマークデータで、種類はREG_BINARYになっています。
ちなみに、「geomerty/pos」「geometry/size」として保存した位置とサイズは、階層構造化されて次のような形で保存されているのがわかります。
まとめ
数回にわたってアプリケーション状態の保存と復元、モデル/ビュー、シグナル/スロット、データの追加/削除、アクションとコンテキストメニューなどを駆け足で紹介し、Notes C APIアプリケーションへの実装例をご覧いただきました。
次回からは、おそらく「Notes C API探訪」シリーズと「Qt5再入門」シリーズを短いスパンで行き来することになると思っています。