Qt QListWidget: editItem()でのアイテム編集を徹底解説

2025-05-31

QListWidget::editItem(QListWidgetItem *item) は、Qtの QListWidget クラスが提供するpublicなメソッド(関数)です。このメソッドは、指定された QListWidgetItem を編集モードにすることで、ユーザーがそのアイテムのテキストを直接編集できるようにします。

主な機能

  • 編集可能条件
    editItem() が機能するためには、対象となる QListWidgetItem が編集可能 (editable) である必要があります。これは、QListWidgetItemQt::ItemIsEditable フラグが設定されていることによって決まります。もしこのフラグが設定されていない場合、editItem() を呼び出しても編集モードにはなりません。
  • アイテムの編集開始
    この関数を呼び出すと、引数で渡された QListWidgetItem のテキスト編集が開始されます。通常、このときアイテムのテキスト部分に編集可能なテキストフィールド(LineEditのようなもの)が表示されます。

使用例のシナリオ

例えば、QListWidget に表示されているアイテムをユーザーがダブルクリックしたときに、そのアイテムのテキストを直接編集できるようにしたい場合などに利用されます。

基本的な使い方

  1. QListWidgetItemの取得
    まず、編集したい QListWidgetItem へのポインタを取得します。これは、現在の選択されているアイテム(currentItem())、特定の行のアイテム(item(row))、またはマウスカーソル下のアイテム(itemAt(pos))など、様々な方法で取得できます。
  2. 編集の開始
    取得した QListWidgetItem を引数として editItem() を呼び出します。

コード例 (C++)

#include <QApplication>
#include <QListWidget>
#include <QListWidgetItem>
#include <QVBoxLayout>
#include <QWidget>

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);

    QWidget window;
    QVBoxLayout *layout = new QVBoxLayout(&window);

    QListWidget *listWidget = new QListWidget(&window);
    layout->addWidget(listWidget);

    // アイテムを追加
    QListWidgetItem *item1 = new QListWidgetItem("アイテム1");
    // アイテムを編集可能に設定
    item1->setFlags(item1->flags() | Qt::ItemIsEditable);
    listWidget->addItem(item1);

    QListWidgetItem *item2 = new QListWidgetItem("アイテム2 (編集不可)");
    listWidget->addItem(item2); // デフォルトでは編集不可

    QListWidgetItem *item3 = new QListWidgetItem("アイテム3");
    item3->setFlags(item3->flags() | Qt::ItemIsEditable);
    listWidget->addItem(item3);

    // ダブルクリックでアイテムを編集モードにする例
    QObject::connect(listWidget, &QListWidget::itemDoubleClicked, listWidget, &QListWidget::editItem);

    // 特定のアイテムをコードから編集モードにする例
    // 例えば、アプリケーション起動時にitem1を編集モードにする
    // listWidget->editItem(item1); 

    window.show();
    return a.exec();
}
  • QListWidget と QListView
    QListWidget は、より低レベルな QListViewQStandardItemModel を組み合わせた便利なクラスです。より高度なカスタマイズが必要な場合は、QListView とカスタムの QItemDelegate を使用することを検討すると良いでしょう。
  • シグナルとスロット
    ユーザーがアイテムの編集を完了すると、QListWidget::itemChanged(QListWidgetItem *item) シグナルが発行されます。このシグナルを捕捉することで、編集されたテキストを取得し、アプリケーションのロジックに反映させることができます。
  • Qt::ItemIsEditable フラグ
    editItem() を呼び出す前に、対象の QListWidgetItemQt::ItemIsEditable フラグを持っていることを確認してください。このフラグがない場合、編集は開始されません。


アイテムが編集モードにならない/「edit: editing failed」エラー

これが最も一般的な問題です。

原因

  • Qt::ItemIsEditable フラグが設定されていない
    QListWidgetItem は、デフォルトでは編集可能ではありません。editItem() が機能するためには、対象のアイテムに Qt::ItemIsEditable フラグが設定されている必要があります。

トラブルシューティング

  • 対象の QListWidgetItem が作成された際、または編集を許可したいタイミングで、必ず setFlags() メソッドを使って Qt::ItemIsEditable を追加してください。
    QListWidgetItem *item = new QListWidgetItem("編集可能なアイテム");
    item->setFlags(item->flags() | Qt::ItemIsEditable); // この行が重要
    myListWidget->addItem(item);
    

編集後に変更が反映されない、または予期せぬ動作をする

原因

  • itemChanged シグナルの二重トリガー
    itemChanged シグナルは、アイテムのデータが変更されたときに発行されます。コード内でアイテムのフラグを変更したり、テキストをプログラム的に設定したりすると、このシグナルが意図せず二度トリガーされることがあります。
  • シグナルとスロットの誤解
    ユーザーがアイテムの編集を完了したときに、その変更をアプリケーションのデータモデルに反映させるには、適切なシグナルを捕捉する必要があります。editItem() 自体は編集モードを開始するだけで、テキストの変更を自動的に処理するわけではありません。

トラブルシューティング

  • QAbstractItemDelegate::commitData シグナル
    より詳細な制御が必要な場合、特にカスタムデリゲートを使用している場合は、QAbstractItemDelegate::commitData(QWidget *editor) シグナルを捕捉することで、エディターが閉じられたときにデータがコミットされるタイミングを正確に知ることができます。これは itemChanged よりも編集終了を正確に捉えることができます(変更がなかった場合でも発行されうるため)。
  • itemChanged シグナルの抑制 (必要な場合)
    プログラム的にアイテムのテキストを変更する際に itemChanged シグナルが発行されるのを避けたい場合は、blockSignals(true) で一時的にシグナルをブロックし、変更後に blockSignals(false) で解除するという方法があります。しかし、これは慎重に使用する必要があります。
    listWidget->blockSignals(true);
    item->setText("新しいテキスト"); // この変更ではitemChangedは発行されない
    listWidget->blockSignals(false);
    
  • itemChanged シグナルを接続する
    アイテムのテキストが変更されたことを検出するために、QListWidget::itemChanged(QListWidgetItem *item) シグナルをカスタムスロットに接続します。
    connect(listWidget, &QListWidget::itemChanged, this, &MyMainWindow::onListItemChanged);
    
    void MyMainWindow::onListItemChanged(QListWidgetItem *item) {
        qDebug() << "アイテムが変更されました:" << item->text();
        // ここで、変更されたテキストをデータモデルに保存するなどの処理を行う
    }
    

編集中のフォーカス喪失や不自然な挙動

原因

  • イベント処理の不足/過剰
    Qtのイベントループの理解が不足していると、予期せぬタイミングで編集が終了したり、GUIの更新が適切に行われなかったりすることがあります。
  • 他のウィジェットとのフォーカス競合
    editItem() で編集モードになった後、他のウィジェット(例: メッセージボックスや別の入力フォーム)を表示したり、フォーカスを奪ったりすると、編集が中断されたり、エディターが消えてしまったりすることがあります。

トラブルシューティング

  • イベントフィルターやカスタムデリゲートの検討
    より複雑な編集ロジックや、編集の開始・終了を細かく制御したい場合は、QListWidget のイベントフィルターをインストールしたり、カスタムの QItemDelegate を実装したりすることを検討してください。これにより、編集ウィジェットのライフサイクルやイベントをより詳細に制御できます。
  • フォーカス管理
    編集モード中に意図せずフォーカスが他のウィジェットに移らないように、setFocus()clearFocus() を適切に利用してフォーカスを管理します。
  • モーダルダイアログの使用
    編集中に他の入力が必要な場合は、QDialogexec() メソッドのようなモーダルダイアログを使用し、リストウィジェットの編集が完了するまで他の操作をブロックすることを検討してください。

原因

  • 無効なポインタの引き渡し
    editItem() に、すでに削除された、または無効な QListWidgetItem へのポインタを渡すと、クラッシュする可能性があります。
  • QListWidgetItem のライフサイクル管理の誤り
    QListWidgetItem は、QListWidget に追加されると、通常 QListWidget がその所有権を持ちます。しかし、takeItem() などでアイテムをリストから取り出した場合、開発者がそのアイテムのメモリを解放する責任を負うことになります。不適切に管理するとメモリリークやダングリングポインタが発生し、クラッシュの原因となることがあります。
  • ポインタの有効性チェック
    editItem() を呼び出す前に、渡そうとしている QListWidgetItem のポインタが有効であることを確認してください。特に、currentItem()selectedItems() などで取得したアイテムが nullptr でないかを確認することが重要です。
  • 所有権の理解
    addItem() やコンストラクタで親を指定して QListWidgetItem を作成した場合、QListWidget がアイテムの削除を管理します。しかし、takeItem() でリストからアイテムを取り出した場合は、手動で delete する必要があります。


QListWidget::editItem() を使用する最も一般的なシナリオは、ユーザーがリスト内のアイテムを直接編集できるようにすることです。ここでは、いくつかの具体的な例を示します。

例 1: ダブルクリックでアイテムを編集可能にする

ユーザーがリストアイテムをダブルクリックしたときに、そのアイテムが編集モードになるようにする典型的な例です。

目的

  • 編集されたテキストをコンソールに出力する。
  • アイテムをダブルクリックすると編集可能にする。
  • QListWidget にアイテムを追加する。

コード (C++)

#include <QApplication>
#include <QListWidget>
#include <QListWidgetItem>
#include <QVBoxLayout>
#include <QWidget>
#include <QDebug> // for qDebug()

class MyListEditExample : public QWidget {
    Q_OBJECT // シグナルとスロットを使用するために必要

public:
    MyListEditExample(QWidget *parent = nullptr) : QWidget(parent) {
        QVBoxLayout *layout = new QVBoxLayout(this);
        listWidget = new QListWidget(this);
        layout->addWidget(listWidget);

        // アイテムを追加し、編集可能に設定
        QListWidgetItem *item1 = new QListWidgetItem("ダブルクリックで編集 (Item 1)");
        item1->setFlags(item1->flags() | Qt::ItemIsEditable); // 編集可能フラグを設定
        listWidget->addItem(item1);

        QListWidgetItem *item2 = new QListWidgetItem("ダブルクリックで編集 (Item 2)");
        item2->setFlags(item2->flags() | Qt::ItemIsEditable);
        listWidget->addItem(item2);

        QListWidgetItem *item3 = new QListWidgetItem("編集不可アイテム");
        // item3->setFlags(item3->flags() | Qt::ItemIsEditable); // このアイテムは編集不可のまま
        listWidget->addItem(item3);

        // シグナルとスロットの接続
        // アイテムがダブルクリックされたら、そのアイテムを編集モードにする
        connect(listWidget, &QListWidget::itemDoubleClicked, listWidget, &QListWidget::editItem);

        // アイテムのテキストが変更されたら、onItemChanged スロットを呼び出す
        connect(listWidget, &QListWidget::itemChanged, this, &MyListEditExample::onItemChanged);

        setWindowTitle("QListWidget::editItem() 例");
        resize(400, 300);
    }

private slots:
    // アイテムのテキストが変更されたときに呼び出されるスロット
    void onItemChanged(QListWidgetItem *item) {
        qDebug() << "アイテムのテキストが変更されました:";
        qDebug() << "  元のアイテムID (ポインタ):" << item; // デバッグ用にポインタを表示
        qDebug() << "  新しいテキスト:" << item->text();
        // ここで、変更されたテキストをデータモデルに保存するなどの処理を行う
    }

private:
    QListWidget *listWidget;
};

// moc処理のために必要
#include "main.moc" // ファイル名に合わせて変更 (例: MylistEditExample.h なら #include "MylistEditExample.moc")

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    MyListEditExample window;
    window.show();
    return a.exec();
}

解説

  1. Q_OBJECT マクロ
    シグナルとスロットを使用するクラスには、必ず Q_OBJECT マクロが必要です。
  2. Qt::ItemIsEditable フラグ
    QListWidgetItem::setFlags() を使って、アイテムに Qt::ItemIsEditable フラグを設定しています。これにより、そのアイテムが編集可能になります。このフラグがないと、editItem() を呼び出しても編集モードにはなりません。
  3. itemDoubleClicked シグナル
    QListWidgetitemDoubleClicked シグナルを QListWidget::editItem スロットに直接接続しています。これにより、ユーザーがアイテムをダブルクリックすると、そのアイテムが自動的に編集モードになります。
  4. itemChanged シグナル
    ユーザーがアイテムの編集を完了し、テキストが変更された場合、QListWidget::itemChanged シグナルが発行されます。これを onItemChanged スロットに接続し、変更されたテキストを qDebug() で表示しています。実アプリケーションでは、ここで変更をデータモデルに保存するなどの処理を行います。

例 2: ボタンクリックで特定のアイテムを編集可能にする

ユーザーの操作ではなく、プログラムの制御で特定のアイテムを編集モードにする例です。

目的

  • ボタンをクリックすると、特定の(または選択されている)アイテムを編集可能にする。
  • QListWidget にアイテムを追加する。

コード (C++)

#include <QApplication>
#include <QListWidget>
#include <QListWidgetItem>
#include <QVBoxLayout>
#include <QPushButton>
#include <QWidget>
#include <QDebug>

class ProgrammaticEditExample : public QWidget {
    Q_OBJECT

public:
    ProgrammaticEditExample(QWidget *parent = nullptr) : QWidget(parent) {
        QVBoxLayout *layout = new QVBoxLayout(this);
        listWidget = new QListWidget(this);
        layout->addWidget(listWidget);

        QPushButton *editButton = new QPushButton("選択アイテムを編集", this);
        layout->addWidget(editButton);

        // アイテムを追加(全て編集可能に設定)
        for (int i = 0; i < 5; ++i) {
            QListWidgetItem *item = new QListWidgetItem(QString("アイテム %1").arg(i + 1));
            item->setFlags(item->flags() | Qt::ItemIsEditable); // 全て編集可能
            listWidget->addItem(item);
        }

        // ボタンクリックで選択されたアイテムを編集モードにする
        connect(editButton, &QPushButton::clicked, this, &ProgrammaticEditExample::onEditButtonClicked);
        
        // アイテム変更時のシグナルも接続しておく
        connect(listWidget, &QListWidget::itemChanged, this, &ProgrammaticEditExample::onItemChanged);

        setWindowTitle("プログラムからの編集例");
        resize(400, 300);
    }

private slots:
    void onEditButtonClicked() {
        QListWidgetItem *selectedItem = listWidget->currentItem(); // 現在選択されているアイテムを取得

        if (selectedItem) { // アイテムが選択されている場合
            qDebug() << "アイテムをプログラムから編集します:" << selectedItem->text();
            listWidget->editItem(selectedItem); // 選択されたアイテムを編集モードにする
        } else {
            qDebug() << "編集するアイテムが選択されていません。";
        }
    }

    void onItemChanged(QListWidgetItem *item) {
        qDebug() << "アイテムのテキストが変更されました (プログラムからの編集後):" << item->text();
    }

private:
    QListWidget *listWidget;
};

#include "main.moc" // もしくはあなたのファイル名に合わせて

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    ProgrammaticEditExample window;
    window.show();
    return a.exec();
}
  1. QPushButton
    「選択アイテムを編集」ボタンを作成し、レイアウトに追加しています。
  2. clicked シグナル
    ボタンの clicked シグナルを onEditButtonClicked スロットに接続しています。
  3. onEditButtonClicked スロット
    • listWidget->currentItem() を使って、現在 QListWidget で選択されているアイテムへのポインタを取得します。
    • 選択されたアイテムがある場合 (selectedItemnullptr でない場合) 、listWidget->editItem(selectedItem) を呼び出して、そのアイテムを編集モードにします。
    • この例でも、全てのアイテムは初期化時に Qt::ItemIsEditable フラグが設定されています。


QListWidget::editItem() は手軽にアイテムのテキスト編集機能を提供しますが、より高度なカスタマイズやデータモデルとの連携が必要な場合、あるいは編集時のUI/UXを細かく制御したい場合には、いくつかの代替手段が考えられます。

主な代替方法は以下の3つです。

  1. カスタムの QItemDelegate を使用する
  2. QListWidget の代わりに QListView とカスタムの QStandardItemModel を使用する
  3. 独自のカスタム編集ダイアログや入力ウィジェットを実装する

それぞれについて詳しく見ていきましょう。

カスタムの QItemDelegate を使用する

これは、Qt のモデル/ビューアーキテクチャの強力な機能の一つで、アイテムの描画と編集を完全にカスタマイズできる方法です。QListWidget の内部でも、デフォルトの QItemDelegate が使用されています。

いつ使うか

  • アイテムの描画自体をカスタマイズしたい場合(例: アイコン、複数のテキスト行、進捗バーなど)。
  • 編集中の入力検証を細かく行いたい場合。
  • 編集時のウィジェット(エディタ)を QLineEdit 以外のものにしたい場合(例: QSpinBox, QComboBox, QCheckBox など)。

基本的な手順

  1. QStyledItemDelegate (または QItemDelegate) を継承したカスタムデリゲートクラスを作成します。
  2. 以下の主要なメソッドをオーバーライドします。
    • createEditor(): 編集が開始されたときに呼び出され、実際に編集に使われるウィジェット(エディタ)を返します。
    • setEditorData(): モデルからエディタへデータを設定します。
    • setModelData(): エディタからモデルへデータを保存します。
    • updateEditorGeometry(): エディタのサイズと位置を決定します。
  3. QListWidget (または QListView) の setItemDelegate() メソッドに、作成したカスタムデリゲートのインスタンスを設定します。

コード例 (概念)

// mycustomdelegate.h
#include <QStyledItemDelegate>
#include <QLineEdit> // 例えばQLineEditをエディタとして使う場合

class MyCustomDelegate : public QStyledItemDelegate
{
    Q_OBJECT
public:
    explicit MyCustomDelegate(QObject *parent = nullptr) : QStyledItemDelegate(parent) {}

    // 編集ウィジェットを作成する
    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
                          const QModelIndex &index) const override
    {
        // ここでカスタムの編集ウィジェットを作成して返す
        // 例: QLineEdit
        QLineEdit *editor = new QLineEdit(parent);
        return editor;
    }

    // モデルのデータを編集ウィジェットに設定する
    void setEditorData(QWidget *editor, const QModelIndex &index) const override
    {
        QString value = index.model()->data(index, Qt::EditRole).toString();
        QLineEdit *lineEdit = static_cast<QLineEdit*>(editor);
        lineEdit->setText(value);
    }

    // 編集ウィジェットのデータをモデルに保存する
    void setModelData(QWidget *editor, QAbstractItemModel *model,
                      const QModelIndex &index) const override
    {
        QLineEdit *lineEdit = static_cast<QLineEdit*>(editor);
        model->setData(index, lineEdit->text(), Qt::EditRole);
    }

    // 編集ウィジェットのジオメトリを更新する
    void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,
                              const QModelIndex &index) const override
    {
        editor->setGeometry(option.rect);
    }
};

// メインコード (QListWidgetを使用する場合)
#include <QApplication>
#include <QListWidget>
#include "mycustomdelegate.h" // 作成したデリゲートをインクルード

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);

    QListWidget listWidget;
    listWidget.setItemDelegate(new MyCustomDelegate(&listWidget)); // カスタムデリゲートを設定

    // アイテムを追加し、編集可能に設定
    QListWidgetItem *item1 = new QListWidgetItem("アイテム1");
    item1->setFlags(item1->flags() | Qt::ItemIsEditable);
    listWidget.addItem(item1);

    QListWidgetItem *item2 = new QListWidgetItem("アイテム2");
    item2->setFlags(item2->flags() | Qt::ItemIsEditable);
    listWidget.addItem(item2);

    listWidget.show();
    return a.exec();
}

利点

  • モデル/ビューの分離により、より堅牢な設計が可能。
  • データ型に応じたエディタを柔軟に切り替えられる。
  • 編集時のUIを完全に制御できる。

欠点

  • QListWidget::editItem() よりも学習コストと実装の手間がかかる。

QListWidget の代わりに QListView とカスタムの QStandardItemModel を使用する

QListWidgetQListViewQStandardItemModel を内部で組み合わせた便利なクラスですが、より細かくデータとビューを分離したい場合は、直接 QListViewQStandardItemModel を使うのが推奨されます。

いつ使うか

  • データモデル層でのきめ細やかな制御が必要な場合。
  • データを異なるビュー(QTableView, QTreeView など)で再利用したい場合。
  • より複雑なデータ構造を扱いたい場合(例: アイテムごとに複数の列を持つ、ツリー構造など)。

基本的な手順

  1. QStandardItemModel のインスタンスを作成し、データを追加します。
  2. QStandardItem を作成し、必要に応じて setEditable(true) で編集可能にします。
  3. QListView のインスタンスを作成し、setModel() メソッドで上記で作成したモデルを設定します。
  4. 編集を開始するには、QListView::edit(const QModelIndex &index) メソッドを使用します。

コード例 (概念)

#include <QApplication>
#include <QListView>
#include <QStandardItemModel>
#include <QStandardItem>
#include <QVBoxLayout>
#include <QWidget>
#include <QDebug>

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);

    QWidget window;
    QVBoxLayout *layout = new QVBoxLayout(&window);

    QListView *listView = new QListView(&window);
    layout->addWidget(listView);

    QStandardItemModel *model = new QStandardItemModel(&window);
    listView->setModel(model);

    // アイテム(QStandardItem)を追加
    QStandardItem *item1 = new QStandardItem("編集可能なアイテム A");
    item1->setEditable(true); // 編集可能に設定
    model->appendRow(item1);

    QStandardItem *item2 = new QStandardItem("編集可能なアイテム B");
    item2->setEditable(true);
    model->appendRow(item2);

    QStandardItem *item3 = new QStandardItem("編集不可アイテム C");
    item3->setEditable(false); // 編集不可
    model->appendRow(item3);

    // ダブルクリックでアイテムを編集モードにする
    QObject::connect(listView, &QListView::doubleClicked, [listView](const QModelIndex &index){
        if (index.isValid() && index.flags() & Qt::ItemIsEditable) {
            listView->edit(index); // QListView::edit() を使用
        }
    });

    // モデルのデータが変更されたときに通知を受け取る
    QObject::connect(model, &QStandardItemModel::itemChanged, [](QStandardItem *item){
        qDebug() << "モデルのアイテムが変更されました:" << item->text();
    });

    window.setWindowTitle("QListView と QStandardItemModel の例");
    window.resize(400, 300);
    window.show();

    return a.exec();
}

利点

  • 同じモデルを複数のビューで共有できる。
  • データとビューの分離が明確になり、大規模なアプリケーションに適している。
  • Qt のモデル/ビューフレームワークに完全に準拠し、拡張性が高い。

欠点

  • QListWidget に比べて設定するオブジェクトが多く、学習曲線が少し急になる。

独自のカスタム編集ダイアログや入力ウィジェットを実装する

これは、アイテムのインプレース編集(リスト内で直接編集)ではなく、別のウィンドウやエリアで編集を行わせる方法です。

いつ使うか

  • ポップアップやフローティングする編集領域が必要な場合。
  • 編集中にユーザーに他の選択肢や操作を提供したい場合。
  • データベースなど、編集後に時間のかかる保存処理が必要な場合。
  • 複雑な入力フォームや複数のフィールドを一度に編集させたい場合。

基本的な手順

  1. リストアイテムが選択されたり、ダブルクリックされたりするシグナル(例: QListWidget::itemDoubleClicked)を捕捉します。
  2. スロット内で、カスタムの QDialog (または QWidget) をインスタンス化し、現在のアイテムのテキストを渡して初期化します。
  3. ダイアログを表示し、ユーザーが編集を完了するのを待ちます。
  4. ダイアログから新しいテキストを取得し、元の QListWidgetItem のテキストを setText() で更新します。

コード例 (概念)

#include <QApplication>
#include <QListWidget>
#include <QListWidgetItem>
#include <QVBoxLayout>
#include <QPushButton>
#include <QLineEdit>
#include <QDialog>
#include <QLabel>
#include <QDebug>

// 編集用のカスタムダイアログ
class EditDialog : public QDialog {
    Q_OBJECT
public:
    EditDialog(const QString &initialText, QWidget *parent = nullptr) : QDialog(parent) {
        QVBoxLayout *layout = new QVBoxLayout(this);
        QLabel *label = new QLabel("新しいテキスト:", this);
        lineEdit = new QLineEdit(initialText, this);
        QPushButton *okButton = new QPushButton("OK", this);
        QPushButton *cancelButton = new QPushButton("キャンセル", this);

        layout->addWidget(label);
        layout->addWidget(lineEdit);
        layout->addWidget(okButton);
        layout->addWidget(cancelButton);

        connect(okButton, &QPushButton::clicked, this, &QDialog::accept);
        connect(cancelButton, &QPushButton::clicked, this, &QDialog::reject);

        setWindowTitle("アイテムを編集");
    }

    QString newText() const {
        return lineEdit->text();
    }

private:
    QLineEdit *lineEdit;
};

// メインウィンドウ
class MainListWindow : public QWidget {
    Q_OBJECT
public:
    MainListWindow(QWidget *parent = nullptr) : QWidget(parent) {
        QVBoxLayout *layout = new QVBoxLayout(this);
        listWidget = new QListWidget(this);
        layout->addWidget(listWidget);

        // アイテムを追加
        for (int i = 0; i < 3; ++i) {
            listWidget->addItem(QString("アイテム %1").arg(i + 1));
        }

        // ダブルクリックでカスタムダイアログを開く
        connect(listWidget, &QListWidget::itemDoubleClicked, this, &MainListWindow::onItemDoubleClicked);

        setWindowTitle("カスタムダイアログでの編集例");
        resize(400, 300);
    }

private slots:
    void onItemDoubleClicked(QListWidgetItem *item) {
        if (!item) return;

        EditDialog dialog(item->text(), this);
        if (dialog.exec() == QDialog::Accepted) {
            item->setText(dialog.newText());
            qDebug() << "アイテムがカスタムダイアログで変更されました:" << item->text();
        }
    }

private:
    QListWidget *listWidget;
};

#include "main.moc" // またはあなたのファイル名に合わせて

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    MainListWindow window;
    window.show();
    return a.exec();
}

利点

  • 複雑なバリデーションロジックをダイアログ内に閉じ込めることができる。
  • 複数の関連するデータを一度に編集できる。
  • 編集UIを非常に柔軟に設計できる。
  • シンプルなテキスト編集のためにはオーバーキルとなる場合がある。
  • インプレース編集ではないため、UXが異なる(ユーザーが別のウィンドウを開く必要がある)。