QTreeView 在双击时编辑 UserRole 而不是 DisplayRole
QTreeView Edit UserRole Instead of DisplayRole Upon Double Click
在我的项目中,我有一个 QTreeView
显示来自 QStandardItemModel
的项目。每个项目都有存储在多个 UserRoles 中的数据。
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 数据生成显示名称。
但是,这很快就会变得非常乏味。随着对话框不断弹出等等,这是一个缓慢而丑陋的解决方案。
我现在想完全删除对话框并在项目本身内显示行编辑小部件。默认情况下,双击一个项目来编辑它只会显示一个行编辑小部件来更改显示角色。但是我想要两行编辑来更改两个用户角色。然后继续正常的逻辑。
我将如何修改 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));
在我的项目中,我有一个 QTreeView
显示来自 QStandardItemModel
的项目。每个项目都有存储在多个 UserRoles 中的数据。
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 数据生成显示名称。
但是,这很快就会变得非常乏味。随着对话框不断弹出等等,这是一个缓慢而丑陋的解决方案。
我现在想完全删除对话框并在项目本身内显示行编辑小部件。默认情况下,双击一个项目来编辑它只会显示一个行编辑小部件来更改显示角色。但是我想要两行编辑来更改两个用户角色。然后继续正常的逻辑。
我将如何修改 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));