見出し画像

Qt5再入門: ウィジェットを動的に追加する(その2)

前回の記事では、ウィジェットの中に別のウィジェットを動的に追加する機能を実装しました。今回は、この機能を使ってDBファイル/ディレクトリ用のページに、Expand(展開)ボタンの追加と、FilePageクラスに追加したメンバーを紹介します。

Expandボタンの追加

Expandボタンは、こちらの記事で紹介しています。この記事ではディレクトリページでのExpandボタンの機能を紹介していますが、データベースページであれば文書や設計文書が展開されるようになります。

Expandボタンを追加するのは、FilePageを表示するタイミングではすでにある前提なので、コンストラクタ内の設定になります。

// filepage.cpp

FilePage::FilePage(
   const nxpp::Lmbcs &path,
   const nxpp::Lmbcs &server,
   QWidget *parent
   )
 : TabPage(parent)
 , path_(path)
 , server_(server)
 , pSubView_(nullptr)
 , pSubModel_(nullptr)
{
 // 更新シグナルをメインモデルのロードに接続
 connect(this, &TabPage::refresh,
         this, &FilePage::loadMainModel
         );

 // モデルの更新シグナルをファイルページのアイテム更新スロットに接続
 connect(
       mainModel(), &QStandardItemModel::itemChanged,
       this, &FilePage::updateItem
       );

 // Expandボタンの生成
 auto pButton = new QPushButton(tr("&Expand"), this);
 
 // Expandボタンのクリックをexpandスロット関数に紐付け
 connect(
       pButton, &QPushButton::clicked,
       this, &FilePage::expand
       );
 
 // ページ上部にExpandボタンを追加
 addToUpper(pButton);
}

FilePageコンストラクタ内の後半でExpandボタンを追加しています。ボタンのクリック動作は、シグナル/スロット機構により自身のexpandメソッドに紐付けています。

FilePageクラスの拡張

さて、ここではFilePageクラスに新しくpSubView_、pSubModel_の2つのメンバ変数が定義されているのが確認できます。また、expandスロット関数も新しく追加されました。

// filepage.h

class FilePage : public TabPage
{
 Q_OBJECT

 nxpp::Lmbcs path_;
 nxpp::Lmbcs server_;
 QTableView *pSubView_; // <= New!
 QStandardItemModel *pSubModel_; // <= New!

public:
 /**
  * @brief コンストラクタ
  * @param path パス
  * @param server サーバ
  * @param parent 親ウィジェット
  */
 FilePage(
     const nxpp::Lmbcs &path,
     const nxpp::Lmbcs &server,
     QWidget *parent = nullptr
     );

 /**
  * @brief 同じファイルかどうか
  * @param path パス
  * @param server サーバ
  * @return 同じファイルパスなら真
  */
 bool equalsTo(
     const nxpp::Lmbcs &path,
     const nxpp::Lmbcs &server
     ) const;

 /**
  * @brief ページの書き込み
  */
 virtual void loadMainModel() override;

 /**
  * @brief サブモデルに行を追加する
  * @param items セル(QStandardItem)リスト
  */
 void addRowToSubModel(const QList<QStandardItem*> items); // <= New!

 /**
  * @brief ローダー関数オブジェクト用抽象クラス
  */
 class Loader {
 public:
   /**
    * @param pPage ページへのポインタ
    * @param dbPtr データベースポインタ
    */
   virtual void operator ()(FilePage *pPage, nxpp::DbPtr dbPtr) = 0;

   /**
    * @brief データベース/ディレクトリ共通のパス行追加
    * @param pPage ページへのポインタ
    * @param dbPtr データベースポインタ
    */
   void addPaths(FilePage *pPage, nxpp::DbPtr dbPtr);
 };

 /**
  * @brief アップデーター関数オブジェクト用抽象クラス
  */
 class Updater {
 public:
   /**
    * @param pPage ページへのポインタ
    * @param dbPtr データベースポインタ
    * @param item 更新されたアイテム(セル)
    */
   virtual void operator ()(
       FilePage *pPage,
       nxpp::DbPtr dbPtr,
       QStandardItem *item
       ) = 0;
 };

 /**
  * @brief エキスパンダー関数オブジェクト用抽象クラス
  */
 class Expander { // <= New!
 public:
   virtual void setHeader(QStandardItemModel *pModel) = 0;
   virtual void operator ()(
       FilePage *pPage,
       nxpp::DbPtr dbPtr
       ) = 0;
 };

public slots:
 /**
  * @brief アイテム更新スロット
  * @param item 更新されたアイテム(セル)
  */
 void updateItem(QStandardItem *item);

 /**
  * @brief 展開スロット
  */
 void expand(); // <= New!
};

pSubView_メンバ変数は、QTableViewとして定義しています。
pSubModel_メンバ変数は、QStandardItemModelとして定義しています。
expandスロット関数は引数なしメソッドです。

これらの他に、addRowToSubModelメソッド、Expanderインナークラスも定義されています。

// filepage.cpp

void FilePage::addRowToSubModel(const QList<QStandardItem*> items) {
 pSubModel_->appendRow(items);
}

addRowToSubModelメソッドは、QStandardItemをセルとするリスト(=テーブルの行情報)をサブモデルに追加します。pSubModel_をプライベートとしているので、モデルに直接ではなく、このメソッドを使って行情報を追加します。

FilePage::Expanderインナークラスは、関数オブジェクトのインターフェースです。expandメソッド内で実際に動作するロジックは、これの派生クラスで定義します。

次回は、このexpandメソッドとExpanderインナークラスが連動して、ディレクトリページでディレクトリ内のDBファイル、サブディレクトリをリストアップする機能につなげていくまでを紹介します。

この記事が気に入ったらサポートをしてみませんか?