Qt Widgets: ダブルクリックで開くエディタを閉じる - QTreeWidget::closePersistentEditor()


QTreeWidget::closePersistentEditor() メソッドは、指定されたアイテムと列の永続エディタを閉じます。永続エディタとは、セルをダブルクリックすると自動的に開くエディタのことです。

構文

void QTreeWidget::closePersistentEditor(QTreeWidgetItem *item, int column = 0);

パラメータ

  • column: 永続エディタを閉じる列(デフォルトは 0)
  • item: 永続エディタを閉じるアイテム

戻り値

なし

詳細

QTreeWidget::closePersistentEditor() メソッドは、指定されたアイテムと列の永続エディタを閉じます。永続エディタが既に閉じている場合、このメソッドは何も実行しません。

このメソッドは、次のような状況で使用されます。

  • プログラムによってエディタを閉じる必要があるとき
  • ユーザーがエディタをキャンセルしたとき
  • ユーザーがエディタからフォーカスを外したとき

次の例では、QTreeWidget アイテムをダブルクリックすると、そのアイテムの最初の列の永続エディタが開きます。ユーザーがエディタからフォーカスを外すと、エディタが閉じられます。

QTreeWidget *treeWidget = new QTreeWidget;
treeWidget->setColumnCount(2);
treeWidget->setHeaderLabels(QStringList() << "Name" << "Value");

QTreeWidgetItem *item = new QTreeWidgetItem(treeWidget);
item->setText(0, "Item 1");
item->setText(1, "Value 1");

treeWidget->connect(treeWidget, &QTreeWidget::itemDoubleClicked,
                   [treeWidget](QTreeWidgetItem *item, int column) {
                       treeWidget->editItem(item, column);
                   });

treeWidget->connect(treeWidget, &QTreeWidget::itemChanged,
                   [treeWidget](QTreeWidgetItem *item) {
                       treeWidget->closePersistentEditor(item);
                   });
  • 永続エディタを閉じるには、QAbstractItemDelegate::closeEditor() シグナルを発行することもできます。
  • QTreeWidget::closePersistentEditor() メソッドは、QAbstractItemView::closeEditor() メソッドと同じ役割を果たします。


例 1: ダブルクリックで永続エディタを開き、フォーカスが外れると閉じる

#include <QApplication>
#include <QTreeWidget>

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

    QTreeWidget *treeWidget = new QTreeWidget;
    treeWidget->setColumnCount(2);
    treeWidget->setHeaderLabels(QStringList() << "Name" << "Value");

    QTreeWidgetItem *item = new QTreeWidgetItem(treeWidget);
    item->setText(0, "Item 1");
    item->setText(1, "Value 1");

    treeWidget->connect(treeWidget, &QTreeWidget::itemDoubleClicked,
                       [treeWidget](QTreeWidgetItem *item, int column) {
                           treeWidget->editItem(item, column);
                       });

    treeWidget->connect(treeWidget, &QTreeWidget::itemChanged,
                       [treeWidget](QTreeWidgetItem *item) {
                           treeWidget->closePersistentEditor(item);
                       });

    treeWidget->show();

    return app.exec();
}

例 2: キーボードの Enter キーで永続エディタを閉じる

この例では、QTreeWidget アイテムを編集中にキーボードの Enter キーを押すと、永続エディタが閉じられます。

#include <QApplication>
#include <QKeyEvent>
#include <QTreeWidget>

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

    QTreeWidget *treeWidget = new QTreeWidget;
    treeWidget->setColumnCount(2);
    treeWidget->setHeaderLabels(QStringList() << "Name" << "Value");

    QTreeWidgetItem *item = new QTreeWidgetItem(treeWidget);
    item->setText(0, "Item 1");
    item->setText(1, "Value 1");

    treeWidget->connect(treeWidget, &QTreeWidget::itemDoubleClicked,
                       [treeWidget](QTreeWidgetItem *item, int column) {
                           treeWidget->editItem(item, column);
                       });

    treeWidget->installEventFilter(new QObject {
        bool eventFilter(QObject *obj, QEvent *event) {
            if (event->type() == QEvent::KeyPress) {
                QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
                if (keyEvent->key() == Qt::Key_Enter &&
                    treeWidget->currentItem() &&
                    treeWidget->isEditing()) {
                    treeWidget->closePersistentEditor(treeWidget->currentItem());
                    return true;
                }
            }
            return QObject::eventFilter(obj, event);
        }
    });

    treeWidget->show();

    return app.exec();
}

例 3: プログラムによって永続エディタを閉じる

この例では、ボタンをクリックすると、QTreeWidget アイテムの永続エディタが閉じられます。

#include <QApplication>
#include <QPushButton>
#include <QTreeWidget>

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

    QTreeWidget *treeWidget = new QTreeWidget;
    treeWidget->setColumnCount(2);
    treeWidget->setHeaderLabels(QStringList() << "Name" << "Value");

    QTreeWidgetItem *item = new QTreeWidgetItem(treeWidget);
    item->setText(0, "Item 1");
    item->setText(1, "Value 1");

    QPushButton *closeButton = new QPushButton("Close Editor");
    closeButton->connect(closeButton, &QPushButton::clicked,
                         [treeWidget]() {
                             if (treeWidget->currentItem() &&
                                 treeWidget->isEditing()) {
                                 treeWidget->closePersistentEditor(treeWidget->currentItem());
                             }
                         });

    QVBoxLayout *layout = new QVBoxLayout;
    layout->addWidget(treeWidget);
    layout->addWidget(closeButton);

    QWidget *widget = new QWidget;
    widget->setLayout(layout);
    widget


QAbstractItemDelegate::closeEditor() シグナルを発行する

QAbstractItemDelegate::closeEditor() シグナルは、永続エディタが閉じるときに発行されます。このシグナルを接続して、エディタが閉じられたときに実行するコードを記述することができます。

#include <QApplication>
#include <QDelegate>
#include <QTreeWidget>

class MyDelegate : public QItemDelegate {
public:
    void closeEditor(QWidget *editor, QAbstractItemModel *model,
                     const QStyleOptionViewItem &option,
                     QEvent *event) override {
        // エディタが閉じられたときに実行するコードを記述
        QTreeWidget *treeWidget = static_cast<QTreeWidget *>(option.widget);
        if (treeWidget->currentItem() && treeWidget->isEditing()) {
            treeWidget->closePersistentEditor(treeWidget->currentItem());
        }
    }
};

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

    QTreeWidget *treeWidget = new QTreeWidget;
    treeWidget->setColumnCount(2);
    treeWidget->setHeaderLabels(QStringList() << "Name" << "Value");

    QTreeWidgetItem *item = new QTreeWidgetItem(treeWidget);
    item->setText(0, "Item 1");
    item->setText(1, "Value 1");

    MyDelegate *delegate = new MyDelegate;
    treeWidget->setItemDelegateForColumn(0, delegate);

    treeWidget->show();

    return app.exec();
}

QAbstractItemModel::setData() メソッドを使用する

QAbstractItemModel::setData() メソッドを使用して、アイテムのデータを直接設定することができます。これにより、永続エディタが閉じられます。

#include <QApplication>
#include <QAbstractItemModel>
#include <QTreeWidget>

class MyModel : public QAbstractItemModel {
public:
    QModelIndex index(int row, int column, const QParentIndex &parent = QModelIndex()) const override {
        if (row < 0 || column < 0 || row >= rowCount(parent) || column >= columnCount(parent)) {
            return QModelIndex();
        }

        return createIndex(parent.row(), column, parent.internalPointer());
    }

    int rowCount(const QModelIndex &parent = QModelIndex()) const override {
        if (parent.isValid()) {
            return 0;
        }

        return 1;
    }

    int columnCount(const QModelIndex &parent = QModelIndex()) const override {
        if (parent.isValid()) {
            return 0;
        }

        return 2;
    }

    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override {
        if (!index.isValid()) {
            return QVariant();
        }

        if (role != Qt::DisplayRole) {
            return QVariant();
        }

        if (index.row() == 0 && index.column() == 0) {
            return "Item 1";
        } else if (index.row() == 0 && index.column() == 1) {
            return "Value 1";
        } else {
            return QVariant();
        }
    }

    bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override {
        if (!index.isValid()) {
            return false;
        }

        if (role != Qt::EditRole) {
            return false;
        }

        if (index.row() == 0 && index.column() == 0) {
            // アイテムのデータを更新
            emit dataChanged(index, index);
            return true;
        } else {
            return false;
        }
    }
};

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

    QTreeWidget *treeWidget = new QTreeWidget;
    treeWidget->setColumnCount(2);
    treeWidget->setHeaderLabels(QStringList() << "Name" << "Value");

    MyModel *model = new MyModel;
    treeWidget->setModel(model);

    treeWidget->show