QTreeView Редактировать UserRole вместо DisplayRole при двойном щелчке

В моем проекте у меня есть QTreeView отображение предметов из QStandardItemModel, Каждый элемент имеет данные, хранящиеся в нескольких пользовательских ролях.

QStandardItem* item = new QStandardItem();
item->setIcon(iconByte);
item->setData(3, Qt::UserRole+1);
item->setData(name, Qt::UserRole+2);
item->setData(data, Qt::UserRole+3);
... and so on

Когда пользователь дважды щелкает элемент, появляется диалоговое окно с двумя строками, позволяющими пользователю редактировать части данных UserRole. Когда редактирование прекращается, редактирование проходит через некоторую логику, и отображаемое имя генерируется на основе новых данных UserRole.

Тем не менее, это становится очень утомительным очень быстро. Диалоги постоянно появляются и все такое, это медленное и уродливое решение.

Теперь я хотел бы полностью удалить диалог и показать строку редактирования виджетов В пределах самого элемента. По умолчанию при двойном щелчке по элементу для его редактирования отображается только один виджет редактирования строки для изменения роли DISPLAY. Однако я хочу, чтобы две строчные правки изменили две роли ПОЛЬЗОВАТЕЛЯ. И тогда нормальная логика продолжается.

Как бы я изменил часть элемента редактирования QTreeView?

Спасибо за ваше время!

0

Решение

Я бы использовал пользовательский подкласс QStyledItemDelegate чтобы решить это. Где-то рядом с вашим QTreeView Вы могли бы иметь QComboBox переключение между пользовательскими ролями; Ваш пользовательский делегат будет каким-то образом проинформирован о том, какая роль пользователя выбрана в данный момент, и перехватит метод, обновляющий данные в модели, чтобы установить правильную роль.

Пример реализации (не проверен, может содержать опечатки и ошибки):

class RoleSwitchingDelegate: public QStyledItemDelegate
{
public:
explicit RoleSwitchingDelegate(QComboBox * roleSwitcher, QObject * parent = 0);

virtual void setEditorData(QWidget * editor, const QModelIndex & index) const Q_DECL_OVERRIDE;
virtual void setModelData(QWidget * editor, QAbstractItemModel * model,
const QModelIndex & index) const Q_DECL_OVERRIDE;
private:
QComboBox * m_roleSwitcher;
};

RoleSwitchingDelegate::RoleSwitchingDelegate(QComboBox * roleSwitcher, QObject * parent) :
QItemDelegate(parent),
m_roleSwitcher(roleSwitcher)
{}

void RoleSwitchingDelegate::setEditorData(QWidget * editor, const QModelIndex & index) const
{
// Assuming the model stores strings for both roles so that the editor is QLineEdit
QLineEdit * lineEdit = qobject_cast<QLineEdit*>(editor);
if (!lineEdit) {
// Whoops, looks like the assumption is wrong, fallback to the default implementation
QStyledItemDelegate::setEditorData(editor, index);
return;
}

int role = m_roleSwitcher->currentIndex();
QString data = index.model()->data(index, role).toString();
lineEdit->setText(data);
}

void RoleSwitchingDelegate::setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const
{
// Again, assuming the model stores strings for both roles so that the editor is QLineEdit
QLineEdit * lineEdit = qobject_cast<QLineEdit*>(editor);
if (!lineEdit) {
// Whoops, looks like the assumption is wrong, fallback to the default implementation
QStyledItemDelegate::setModelData(editor, model, index);
return;
}

int role = m_roleSwitcher->currentIndex();
QString data = lineEdit->text();
model->setData(index, data, role);
}

Когда у вас есть делегат, вам просто нужно установить его на представление:

view->setItemDelegate(new RoleSwitchingDelegate(roleSwitchingComboBox, view));
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]