В моем проекте у меня есть 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
?
Спасибо за ваше время!
Я бы использовал пользовательский подкласс 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));
Других решений пока нет …