首页 > 技术文章 > QTreeView使用总结9,使用委托,定制item输入效果

dpsying 2018-05-17 17:57 原文

1,简介

前面一些文章介绍了QTreeView的常规用法,接下来介绍一些高级的用法和改造技巧。
本文介绍delegate,即委托,对QTreeView的item进行改造,以实现特殊的输入方式。

2,其他参考资料

Qt官方提供的委托示例:SpinBoxDelegate
(在QtCreator的欢迎里搜delegate,其中spin box delegate example)

关于委托的详细介绍,可以参考豆子的博客:
Qt学习之路(48): 自定义委托

各种类型的委托控制输入的例子:
QT:在QTableView中使用各种自定义委托

3,效果

这里演示一个让某列使用QComboBox进行编辑的效果:
这里写图片描述

4,实现

继承QStyledItemDelegate,写一个MyDelegate类:

实现里面的以下方法:
createEditor: 当item激活编辑状态时,显示的内容。这里创建一个QComboBox
setEditorData:用以初始化createEditor里创建的控件内容。这里直接把当前item的text设置为QComboBox选中项。
setModelData:应用编辑后,修改model的data。这里把QComboBox的当前选中项文本设置为item的显示文本。
updateEditorGeometry:更新控件位置状态。

MyDelegate.h:

#ifndef MYDELEGATE_H
#define MYDELEGATE_H


#include <QStyledItemDelegate>

class MyDelegate : public QStyledItemDelegate
{
    Q_OBJECT

public:
    MyDelegate(QObject *parent = 0);

    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
                          const QModelIndex &index) const override;

    void setEditorData(QWidget *editor, const QModelIndex &index) const override;
    void setModelData(QWidget *editor, QAbstractItemModel *model,
                      const QModelIndex &index) const override;

    void updateEditorGeometry(QWidget *editor,
        const QStyleOptionViewItem &option, const QModelIndex &index) const override;
};


#endif

MyDelegate.cpp:


#include "mydelegate.h"
#include <QSpinBox>
#include <QComboBox>

MyDelegate::MyDelegate(QObject *parent)
    : QStyledItemDelegate(parent)
{
}

QWidget *MyDelegate::createEditor(QWidget *parent,
    const QStyleOptionViewItem &/* option */,
    const QModelIndex & index ) const
{
    if(index.column() == 3) //只对第4列采用此方法编辑
    {
        QComboBox* box = new QComboBox(parent);
        box->addItems(QStringList()<<"优"<<"良"<<"差");
        return box;
    }
    return NULL;
}

void MyDelegate::setEditorData(QWidget *editor,
                                    const QModelIndex &index) const
{
    QString value = index.model()->data(index, Qt::EditRole).toString();
    QComboBox* box = static_cast<QComboBox*>(editor);
    box->setCurrentText(value);
}

void MyDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
                                   const QModelIndex &index) const
{
    QComboBox* box = static_cast<QComboBox*>(editor);
    model->setData(index, box->currentText(), Qt::EditRole);
}

void MyDelegate::updateEditorGeometry(QWidget *editor,
    const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
{
    editor->setGeometry(option.rect);
}

在初始化QTreeView时,新建一个MyDelegate,设itemDelegate:
注意:要设置单元格编辑属性为可编辑(setEditTriggers),否则点击单元格不会有反应。

QTreeView* t = ui->treeView;
//    t->setEditTriggers(QTreeView::NoEditTriggers);            //单元格不能编辑
    t->setSelectionBehavior(QTreeView::SelectRows);         //一次选中整行
    t->setSelectionMode(QTreeView::SingleSelection);        //单选,配合上面的整行就是一次选单行
//    t->setAlternatingRowColors(true);                       //每间隔一行颜色不一样,当有qss时该属性无效
    t->setFocusPolicy(Qt::NoFocus);                         //去掉鼠标移到单元格上时的虚线框

    MyDelegate* delegate = new MyDelegate;
    t->setItemDelegate(delegate);

5,源码

https://pan.baidu.com/s/1-F0yXPrEgIcfdqudzMMtbA

推荐阅读