双击

时间:2016-12-29 05:59:17

标签: c++ qt qabstractitemview

在我的项目中,我有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数据生成显示名称。

但是,这很快就变得非常繁琐。随着对话框的不断涌现等等,这是一个缓慢而丑陋的解决方案。

我现在想完全删除对话框并在项目本身中显示行编辑小部件。默认情况下,双击某个项目进行编辑只会显示一个行编辑小部件以更改DISPLAY角色。但是,我想要两行编辑来更改两个USER角色。然后正常的逻辑继续。

我如何修改QTreeView的编辑项部分?

谢谢你的时间!

1 个答案:

答案 0 :(得分:2)

我会使用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));