見出し画像

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)に合わせて、列幅をリサイズするというものです。

レジストリを確認してみる

今回作成したブックマークも含め、レジストリにどのように格納されているか、確認してみます。

スクリーンショット 2021-08-30 7.48.20

この中のbookmarksがブックマークデータで、種類はREG_BINARYになっています。

スクリーンショット 2021-08-30 7.49.26

ちなみに、「geomerty/pos」「geometry/size」として保存した位置とサイズは、階層構造化されて次のような形で保存されているのがわかります。

スクリーンショット 2021-08-30 7.48.44

まとめ

数回にわたってアプリケーション状態の保存と復元、モデル/ビュー、シグナル/スロット、データの追加/削除、アクションとコンテキストメニューなどを駆け足で紹介し、Notes C APIアプリケーションへの実装例をご覧いただきました。

次回からは、おそらく「Notes C API探訪」シリーズと「Qt5再入門」シリーズを短いスパンで行き来することになると思っています。

いいなと思ったら応援しよう!