2016-04-11 4 views
2

У меня есть своя модель таблицы подкласса от QAbstractTableModel. Он установлен на моем представлении (подклассом от QTableView). Внутри представления я использую класс делегата (подклассифицированный от QItemDelegate) для редактирования элементов.QItemDelegate, как обеспечить собственный EndEditHint в сигнале closeEditor()?

Я хочу настроить следующее поведение: когда я закончу редактирование данных с помощью моего делегата, следующий элемент в модели (элемент в следующей строке и в том же столбце) должен стать редактируемым.

Документация гласит, что она дана сообщением QAbstractItemDelegate::EditNextItem, который отправляется в сообщении closeEditor(). Но по умолчанию этот сигнал отправляется с параметром QAbstractItemDelegate::NoHint. Проблема в том, что я не должен явно вызывать этот сигнал, переопределяя основные виртуальные функции QItemDelegate, например setModelData().

Документация также сообщает, что этот сигнал отправляется внутренним фильтром событий, который устанавливается на делегат элемента при вызове конструктора QAbstractItemDelegate().

Как я могу предоставить свой собственный EndEditHint в closeEditor() сигнал?

ответ

0

Когда вы закончите редактирование, делегат отправит сигнал closeEditor() с подсказкой SubmitModelCache. Вы должны придерживаться такого поведения, чтобы обновить вашу модель.

Чтобы немедленно открыть редактор в следующей ячейке после совершения данных из предыдущего редактирования вы можете переделайте фунцкцию QItemDelegate::eventFilter() но я нахожу гораздо более проще просто переопределить QAbstractItemView::closeEditor() метод:

void CMyTableView::closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint) 
{ 
    QTableView::closeEditor(editor, hint); 

    QModelIndex index = moveCursor(MoveNext, Qt::NoModifier); 
    if (!index.isValid()) 
     return; 

    QPersistentModelIndex persistent(index); 
    selectionModel()->setCurrentIndex(persistent, flags); 

    // currentChanged signal would have already started editing 
    if (index.flags() & Qt::ItemIsEditable && (!(editTriggers() & QAbstractItemView::CurrentChanged))) 
     edit(persistent); 
} 

Даже простое решение будет (я не уверен в этом, но это, безусловно, стоит попробовать):

void CMyTableView::closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint) 
{ 
    QTableView::closeEditor(editor, hint); 
    QTableView::closeEditor(nullptr, QAbstractItemDelegate::EditNextItem);  
} 

метод moveCursor() возвращает индекс следующего столбца и той же строке. Если вы хотите изменить это поведение, переописать его:

QModelIndex CMyTableView::moveCursor(CursorAction action, Qt::KeyboardModifiers modifiers) 
{ 
    if (action == QAbstractItemView::MoveNext) 
     action = QAbstractItemView::MoveDown; 
    else if (action == QAbstractItemView::MovePrevious) 
      action = QAbstractItemView::MoveUp; 

    // Next row, same column. 
    return QTableView::moveCursor(action, modifiers); 
} 

И кстати: При нажатии клавиши Tab, поведение по умолчанию QTableView является то, что в настоящее время редактор закрыт, данные сохраняются и в следующем ячейка отредактирована.
Итак, возможно, единственное, что вам нужно сделать, это просто переопределить метод QTableView::moveCursor().

Смежные вопросы