QTreeWidget设置Delegate

1、QT分为:Mode层,View层,数据存放在Mode里面,显示在View层,当我们修改了View层的同时,需要修改Mode层。

2、Delegate工作原理:当我们点击支持编辑的列,创建自定义的编辑控件(可为button、spinbox、combobox等等),然后从Mode层,取值,设置给控件,当自定义控件,编辑完成,再设置给Mode层

3、自定义Delegate

class ItemDelegate : public QStyledItemDelegate
{
    Q_OBJECT
public:
    ItemDelegate (QObject *parent = nullptr);
    ~ItemDelegate ();

public:
    virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    virtual void setEditorData(QWidget *editor, const QModelIndex &index) const;
    virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
    virtual void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;
};
#include "stdafx.h"
#include "ItemDelegate.h"
#include 
#include 

ItemDelegate::ItemDelegate(QObject *parent)
    : QStyledItemDelegate(parent)
{
    // 如果继承的是QItemDelegate,那么在paint中,是不能支持parent的QSS的
}

ItemDelegate::~ItemDelegate()
{

}

QWidget * ItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    // step:1 根据不同的列,创建需要的控件,不支持的直接返回空
    if (index.column() == 1|| index.column() == 2)
    {
        QSpinBox *spinBox = new QSpinBox(parent);
        spinBox->setRange(0, 255);
        return spinBox;
    }
    else if(index.column() == 3|| index.column() == 4)
    {
        QDoubleSpinBox *dSpinBox = new QDoubleSpinBox(parent);
        dSpinBox->setRange(0, 100);
        dSpinBox->setSingleStep(1.00);
        return dSpinBox;
    }
    return nullptr;
}

void ItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QStyleOptionViewItem viewOption(option);
    initStyleOption(&viewOption, index);
    QStyledItemDelegate::paint(painter, viewOption, index);
}

void ItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    // step:2 给控件设置值
    if (index.column() == 1|| index.column() == 2)
    {
        QSpinBox *spinBox = dynamic_cast(editor);
        if (spinBox)
        {
            int value = index.data().toString().toInt();
            spinBox->setValue(value);
        }
    }
    else if (index.column() == 3|| index.column() == 4)
    {
        QDoubleSpinBox *dSpinBox = dynamic_cast(editor);
        if (dSpinBox)
        {
            double value = index.data().toString().toDouble();
            dSpinBox->setValue(value);
        }
    }

}

void ItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
    // step:3编辑完成,设置值给Mode层
    if (index.column() == 1|| index.column() == 2)
    {
        QSpinBox *spinBox = dynamic_cast(editor);
        if (spinBox)
        {
            int value = spinBox->value();
            model->setData(index, value, Qt::DisplayRole);
        }
    }
    else if (index.column() == 3|| index.column() == 4)
    {
        QDoubleSpinBox *dSpinBox = dynamic_cast(editor);
        if (dSpinBox)
        {
            double value = dSpinBox->value();
            model->setData(index, QString::number(value, 'f', 2), Qt::DisplayRole);
        }
    }
}

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

4、启用Delegate

ui->treeWidget->setItemDelegate(new ItemDelegate(ui->treeWidget));
// 当鼠标点击时候,开启编辑
connect(ui->treeWidget, &QTreeWidget::clicked, this, [this](const QModelIndex &index)
    {
        if (index.column() == 1|| index.column() == 2|| index.column() == 3
            || index.column() == 4)
        {
            ui->treeWidget->edit(index);
        }
    });

// 检测Item变化是为了给底层设值
connect(ui->treeWidget, &QTreeWidget::itemChanged, this, [this]{onItemChanged();});

// mEditing 是为了监测是否在编辑状态,在创建QTreeWidgetItem时候 设置为tree,添加完成设置为False
void MainWindow::onItemChanged(QTreeWidgetItem *item, int column)
{
    if (mEditing || nullptr == item)
    {
        return;
    }
    // 然后给底层设值值
    // do something
}

// Item 支持编辑
 QTreeWidgetItem *item = new QTreeWidgetItem(ui->treeWidget);
 item->setFlags(item->flags() | Qt::ItemIsEditable);

 

你可能感兴趣的:(QT,QTreeView)