web-dev-qa-db-ja.com

Qt:ワンクリックでセルの編集を開始

デフォルトでは、QTableViewのセルはダブルクリック後に編集を開始します。この動作を変更する方法。 ワンクリックで編集を開始するために必要です。

セルにコンボボックスデリゲートを設定しました。セルをクリックすると、それが選択されるだけです。セルをダブルクリックすると、QComboBoxエディターがアクティブになりますが、展開されません。 QComboBoxsetCellWidget関数でQTableWidgetを追加したかのように、ワンクリックで展開したい。 model-view-delegateを使用して同じ効果が必要です。

17
Ashot

ワンクリックで編集使用しているビューでmousePressEventを再実装できます

void YourView::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        QModelIndex index = indexAt(event->pos());
        if (index.column() == 0) { // column you want to use for one click
            edit(index);
        }
    }
    QTreeView::mousePressEvent(event);
}

編集時にQComboboxを拡張 QItemDelegateのサブクラスにsetEditorDataを実装し、最後にshowPopupを呼び出す必要があります。

しかし、予期しない動作があります。マウスがその領域を離れると、QComboBoxは消えます。しかし、私にとってはそれは利点です。シングルクリックで別のアイテムを選択して離すことができます。

void IconDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    Q_UNUSED(index);
    QComboBox *comboBox = qobject_cast<QComboBox*>(editor);
    // Add data
    comboBox->addItem(QIcon(":/icons/information16.png"), "info");
    comboBox->addItem(QIcon(":/icons/warning16.png"), "warning");
    comboBox->addItem(QIcon(":/icons/send16.png"), "send");
    comboBox->addItem(QIcon(":/icons/select16.png"), "select");
    comboBox->showPopup(); // <<<< Show popup here
}

一緒にそれは速い方法で動作します。 クリックアンドホールドアイテムを選択してデータをコミットするリリース(ワンクリックしてリリースするだけ)

クリックして展開されたqcomboboxを表示し、次にクリックして選択/非表示にする場合は、現時点では解決策がわかりません。

14
fbucek

この関数setEditTriggersを使用して編集トリガーを設定できます

C++

yourView->setEditTriggers(QAbstractItemView::AllEditTriggers)

Python:

yourView.setEditTriggers(QAbstractItemView.AllEditTriggers)

列挙型QAbstractItemView :: EditTriggerフラグQAbstractItemView :: EditTriggers

この列挙型は、アイテムの編集を開始するアクションについて説明しています。

Constant    Value   Description
QAbstractItemView::NoEditTriggers   0   No editing possible.
QAbstractItemView::CurrentChanged   1   Editing start whenever current item changes.
QAbstractItemView::DoubleClicked    2   Editing starts when an item is double clicked.
QAbstractItemView::SelectedClicked  4   Editing starts when clicking on an already selected item.
QAbstractItemView::EditKeyPressed   8   Editing starts when the platform edit key has been pressed over an item.
QAbstractItemView::AnyKeyPressed    16  Editing starts when any key is pressed over an item.
QAbstractItemView::AllEditTriggers  31  Editing starts for all above actions.

EditTriggersタイプは、QFlagsのtypedefです。 OR EditTrigger値の組み合わせを格納します。

18
shijq73

ジェイソンによって提供されたアイデアに基づいて、私はこの解決策を思いつきました。

シングルクリックでエディターを起動するために、ビューのQAbstractItemView::clicked(const QModelIndex &index)シグナルを同じビューのQAbstractItemView::edit(const QModelIndex &index)スロットに接続しました。

Qt4を使用する場合は、デリゲートにスロットを作成する必要があります。このスロットへの引数としてコンボボックスを渡します。このスロットでは、QComboBox::showPopupを呼び出します。したがって、次のようになります。

void MyDelegate::popUpComboBox(QComboBox *cb)
{
    cb->showPopup();
}

ただし、最初にQComboBox*タイプを登録する必要があります。デリゲートのコンストラクターでこれを呼び出すことができます。

qRegisterMetaType<QComboBox*>("QComboBox*");

このスロットが必要な理由は、リストビューの位置と方向が不明であるため、MyDelegate::createEditorにポップアップをすぐに表示できないためです。したがって、MyDelegate::createEditorで行うことは、キュー接続でこのスロットを呼び出します。

QComboBox *cb = new QComboBox(parent);
// populate your combobox...
QMetaObject::invokeMethod(const_cast<MyDelegate*>(this), "popUpComboBox", Qt::QueuedConnection, Q_ARG(QComboBox*, cb));

これにより、エディターがアクティブ化されたときにコンボボックスのリストビューが正しく表示されます。

Qt5を使用している場合、スロットは必要ありません。 QComboBox::showPopupからのキュー接続でMyDelegate::createEditorを呼び出すだけです。これを行う最も簡単な方法は、QTimerを使用することです。

QTimer::singleShot(0, cb, &QComboBox::showPopup);

一部の追加情報の場合、これは、エディターが表示されているときだけでなく、常に表示されるようにコンボボックスをペイントする方法です。

void MyDelegate::Paint(QPainter *Painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    if(index.column() == 1) // show combobox only in the second column
    {
        QStyleOptionComboBox box;
        box.state = option.state;

        box.rect = option.rect;
        box.currentText = index.data(Qt::EditRole).toString();

        QApplication::style()->drawComplexControl(QStyle::CC_ComboBox, &box, Painter, 0);
        QApplication::style()->drawControl(QStyle::CE_ComboBoxLabel, &box, Painter, 0);
        return;
    }
    QStyledItemDelegate::Paint(Painter, option, index);
}
2
thuga

このソリューションは私にとって完璧に機能します。セルをシングルクリックすると、コンボがポップアップします。

class GFQtComboEnumItemDelegate : public QStyledItemDelegate
{
    void setEditorData(QWidget *editor, const QModelIndex &index) const
    {
        QComboBox* pE = qobject_cast<QComboBox*>(editor);
        ... // init the combo here
        if(m_must_open_box)
        {
            m_must_open_box = false;
            pE->showPopup();
        }
    }


    bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
    {
        if (event->type() == QEvent::MouseButtonRelease)
        {
            QMouseEvent* pME = static_cast<QMouseEvent*>(event);
            if(pME->button() == Qt::LeftButton)
            {
                QAbstractItemView* pView = qobject_cast<QAbstractItemView*>( const_cast<QWidget*>(option.widget) );
                if(pView != nullptr)
                {
                    emit pView->setCurrentIndex(index);
                    m_must_open_box = true;
                    emit pView->edit(index);
                }
                return true;
            }
        }
        return QStyledItemDelegate::editorEvent(event, model, option, index);
    }
    mutable bool m_must_open_box;
};
1
KungPhoo

QStyledItemDelegate::createEditor()をオーバーライドすると、作成後にコンボボックスを展開できます。

0
Jason