自定义ItemDelegate,实现双击Item出现不同的组件

 需求:在QTableWidget界面中,需要对不同的Item设置不同的输入限制

解决方案1:

        通过setCellWidget函数在表格Item上设置界面组件,但此方法需要管理创建的界面组件,若表格显示的内容较多时,管理的组件也越多,且设置QSS样式后,表格与界面组件样式不统一影响美观。

解决方案2:

        通过setItemDelegate函数设置表格代理,受到QtTreePropertyBrowser原理启发,在createEditor中根据不同的类型创建不同的组件。

效果展示:

代码:

#ifndef ITEMDELEGATE_H
#define ITEMDELEGATE_H

#include <QStyledItemDelegate>

#define EditorType          "editorType"
#define ToolTip             "tooltip"
//QLineEdit String
#define InputMask           "inputMask"
#define MaxLength           "maxLength"
#define RegExp              "regExp"
//QSpinBox Int
#define Minimum             "minimum"
#define Maximum             "maximum"
#define SingleStep          "step"
#define Prefix              "prefix"
#define Suffix              "suffix"
//QDoubleSpinBox Double
#define Decimals            "decimals"
//QCheckBox Bool
//QDate
#define DisplayFormat       "displayFormat"
#define MaximumDateTime     "MaximumDateTime"
#define MinimumDateTime     "MinimumDateTime"
//QComboBox List
#define ComboBoxValue       "comboBoxValue"

#define ItemDelegateRole    (Qt::UserRole)

class QLineEdit;
class QSpinBox;
class QDoubleSpinBox;
class QCheckBox;
class QDateEdit;
class QTimeEdit;
class QDateTimeEdit;
class QComboBox;
/*!
 * \brief The ItemDelegate class    自定义代理
 * 通过获取index.data(Qt::UserRole).toHash()中的键值
 * 创建对应的代理编辑器
 */
class ItemDelegate : public QStyledItemDelegate
{
public:
    ItemDelegate(QObject* pParent = Q_NULLPTR);
    virtual ~ItemDelegate();

    /*!
     * \brief createEditor  创建编辑器
     * \param pParent       父对象
     * \param option        设置
     * \param index         索引
     * \return
     */
    QWidget *createEditor(QWidget *pParent, const QStyleOptionViewItem &option, const QModelIndex &index) const;

    /*!
     * \brief setEditorData 设置编辑器数据
     * \param pEditor       编辑器
     * \param index         索引
     */
    void setEditorData(QWidget *pEditor, const QModelIndex &index) const;

    /*!
     * \brief setModelData  设置模型数据
     * \param pEditor       编辑器
     * \param model         模型
     * \param index         索引
     */
    void setModelData(QWidget *pEditor, QAbstractItemModel *model, const QModelIndex &index) const;

    /*!
     * \brief updateEditorGeometry  更新编辑器样式
     * \param pEditor               编辑器
     * \param option                设置
     * \param index                 索引
     */
    void updateEditorGeometry(QWidget *pEditor, const QStyleOptionViewItem &option, const QModelIndex &index) const;

private:
    /*!
     * \brief createLineEdit    创建QLineEdit
     * \param hash              属性容器
     * \param pParent           父对象
     * \return                  指针
     */
    QLineEdit *createLineEdit(const QVariantHash& hash, QWidget *pParent) const;

    /*!
     * \brief createSpinBox     创建QSpinBox
     * \param hash              属性容器
     * \param pParent           父对象
     * \return                  指针
     */
    QSpinBox *createSpinBox(const QVariantHash& hash, QWidget *pParent) const;

    /*!
     * \brief createDoubleSpinBox   创建QDoubleSpinBox
     * \param hash                  属性容器
     * \param pParent               父对象
     * \return                      指针
     */
    QDoubleSpinBox* createDoubleSpinBox(const QVariantHash& hash, QWidget *pParent) const;

    /*!
     * \brief createCheckBox        创建QCheckBox
     * \param hash                  属性容器
     * \param pParent               父对象
     * \return                      指针
     */
    QCheckBox *createCheckBox(const QVariantHash& hash, QWidget *pParent) const;

    /*!
     * \brief createDateEdit    创建QDateEdit
     * \param hash              属性容器
     * \param pParent           父对象
     * \return                  指针
     */
    QDateEdit *createDateEdit(const QVariantHash& hash, QWidget *pParent) const;

    /*!
     * \brief createTimeEdit    创建QTimeEdit
     * \param hash              属性容器
     * \param pParent           父对象
     * \return                  指针
     */
    QTimeEdit *createTimeEdit(const QVariantHash& hash, QWidget *pParent) const;

    /*!
     * \brief createDateTimeEdit    创建QDateTimeEdit
     * \param hash                  属性容器
     * \param pParent               父对象
     * \return                      指针
     */
    QDateTimeEdit *createDateTimeEdit(const QVariantHash& hash, QWidget *pParent) const;

    /*!
     * \brief createDateTimeEdit    创建QComboBox
     * \param hash                  属性容器
     * \param pParent               父对象
     * \return                      指针
     */
    QComboBox *createComboBox(const QVariantHash& hash, QWidget *pParent)const;
};

#endif // ITEMDELEGATE_H
#include "ItemDelegate.h"

#include <QLineEdit>
#include <QSpinBox>
#include <QDoubleSpinBox>
#include <QCheckBox>
#include <QDateEdit>
#include <QTimeEdit>
#include <QDateTimeEdit>
#include <QComboBox>

ItemDelegate::ItemDelegate(QObject *pParent) :
    QStyledItemDelegate(pParent)
{

}

ItemDelegate::~ItemDelegate()
{

}

QWidget *ItemDelegate::createEditor(QWidget *pParent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    Q_UNUSED(option)
    QVariant value = index.data(Qt::UserRole);
    if(QVariant::Hash == value.type())
    {
        const QVariantHash hash = index.data(Qt::UserRole).toHash();
        if(hash.contains(EditorType))
        {
            switch (hash[EditorType].type())
            {
            case QVariant::String:
                return createLineEdit(hash, pParent);
            case QVariant::Int:
                return createSpinBox(hash, pParent);
            case QVariant::Double:
                return createDoubleSpinBox(hash, pParent);
            case QVariant::Bool:
                return createCheckBox(hash, pParent);
            case QVariant::Date:
                return createDateEdit(hash, pParent);
            case QVariant::Time:
                return createTimeEdit(hash, pParent);
            case QVariant::DateTime:
                return createDateTimeEdit(hash, pParent);
            case QVariant::List:
                return createComboBox(hash, pParent);
            default:
                break;
            }
        }
    }
    return new QLineEdit(pParent);
}

void ItemDelegate::setEditorData(QWidget *pEditor, const QModelIndex &index) const
{
    QVariant value = index.data(Qt::UserRole);
    if(QVariant::Hash == value.type())
    {
        const QVariantHash hash = index.data(Qt::UserRole).toHash();
        if(hash.contains(EditorType))
        {
            switch (hash[EditorType].type())
            {
            case QVariant::String:
            {
                QLineEdit* pLineEdit = qobject_cast<QLineEdit*>(pEditor);
                if(pLineEdit)
                {
                    pLineEdit->setText(index.data().toString());
                }
                return;
            }
            case QVariant::Int:
            {
                QSpinBox* pSpinBox = qobject_cast<QSpinBox*>(pEditor);
                if(pSpinBox)
                {
                    pSpinBox->setValue(index.data().toString().toInt());
                }
                return;
            }
            case QVariant::Double:
            {
                QDoubleSpinBox* pDSpinBox = qobject_cast<QDoubleSpinBox*>(pEditor);
                if(pDSpinBox)
                {
                    pDSpinBox->setValue(index.data().toString().toInt());
                }
                return;
            }
            case QVariant::Bool:
            {
                QCheckBox* pCheckBox = qobject_cast<QCheckBox*>(pEditor);
                if(pCheckBox)
                {
                    bool bChecked = index.data().toString() == "True" ? true : false;
                    pCheckBox->setChecked(bChecked);
                    pCheckBox->setText(bChecked ? "True" : "False");
                }
                return;
            }
            case QVariant::Date:
            {
                QDateEdit* pDateEdit = qobject_cast<QDateEdit*>(pEditor);
                if(pDateEdit)
                {
                    QDate date;
                    if(hash.contains(DisplayFormat))
                    {
                        date = QDate::fromString(index.data().toString(), hash[DisplayFormat].toString());
                    }
                    else
                    {
                        date = QDate::fromString(index.data().toString());
                    }
                    pDateEdit->setDate(date);
                }
                return;
            }
            case QVariant::Time:
            {
                QTimeEdit* pTimeEdit = qobject_cast<QTimeEdit*>(pEditor);
                if(pTimeEdit)
                {
                    QTime time;
                    if(hash.contains(DisplayFormat))
                    {
                        time = QTime::fromString(index.data().toString(), hash[DisplayFormat].toString());
                    }
                    else
                    {
                        time = QTime::fromString(index.data().toString());
                    }
                    pTimeEdit->setTime(time);
                }
                return;
            }
            case QVariant::DateTime:
            {
                QDateTimeEdit* pDateTimeEdit = qobject_cast<QDateTimeEdit*>(pEditor);
                if(pDateTimeEdit)
                {
                    QDateTime dateTime;
                    if(hash.contains(DisplayFormat))
                    {
                        dateTime = QDateTime::fromString(index.data().toString(), hash[DisplayFormat].toString());
                    }
                    else
                    {
                        dateTime = QDateTime::fromString(index.data().toString());
                    }
                    pDateTimeEdit->setDateTime(dateTime);
                }
                return;
            }
            case QVariant::List:
            {
                QComboBox* pComboBox = qobject_cast<QComboBox*>(pEditor);
                if(pComboBox)
                {
                    pComboBox->setCurrentText(index.data().toString());
                }
                return;
            }
            default:
                break;
            }
        }
    }

    QLineEdit* pLineEdit = qobject_cast<QLineEdit*>(pEditor);
    if(pLineEdit)
    {
        pLineEdit->setText(index.data().toString());
    }
}

void ItemDelegate::setModelData(QWidget *pEditor, QAbstractItemModel *model, const QModelIndex &index) const
{
    QVariant value = index.data(Qt::UserRole);
    if(QVariant::Hash == value.type())
    {
        const QVariantHash hash = index.data(Qt::UserRole).toHash();
        if(hash.contains(EditorType))
        {
            switch (hash[EditorType].type())
            {
            case QVariant::String:
            {
                QLineEdit* pLineEdit = qobject_cast<QLineEdit*>(pEditor);
                if(pLineEdit)
                {
                    model->setData(index, pLineEdit->text());
                }
                return;
            }
            case QVariant::Int:
            {
                QSpinBox* pSpinBox = qobject_cast<QSpinBox*>(pEditor);
                if(pSpinBox)
                {
                    model->setData(index, QString::number(pSpinBox->value()));
                }
                return;
            }
            case QVariant::Double:
            {
                QDoubleSpinBox* pDSpinBox = qobject_cast<QDoubleSpinBox*>(pEditor);
                if(pDSpinBox)
                {
                    model->setData(index, QString::number(pDSpinBox->value()));
                }
                return;
            }
            case QVariant::Bool:
            {
                QCheckBox* pCheckBox = qobject_cast<QCheckBox*>(pEditor);
                if(pCheckBox)
                {
                    model->setData(index, pCheckBox->checkState() == Qt::Checked ? "True" : "False");
                }
                return;
            }
            case QVariant::Date:
            {
                QDateEdit* pDateEdit = qobject_cast<QDateEdit*>(pEditor);
                if(pDateEdit)
                {
                    QString str;
                    if(hash.contains(DisplayFormat))
                    {
                        str = pDateEdit->date().toString(hash[DisplayFormat].toString());
                    }
                    else
                    {
                        str = pDateEdit->date().toString();
                    }
                    model->setData(index, str);
                }
                return;
            }
            case QVariant::Time:
            {
                QTimeEdit* pTimeEdit = qobject_cast<QTimeEdit*>(pEditor);
                if(pTimeEdit)
                {
                    QString str;
                    if(hash.contains(DisplayFormat))
                    {
                        str = pTimeEdit->time().toString(hash[DisplayFormat].toString());
                    }
                    else
                    {
                        str = pTimeEdit->time().toString();
                    }
                    model->setData(index, str);
                }
                return;
            }
            case QVariant::DateTime:
            {
                QDateTimeEdit* pDateTimeEdit = qobject_cast<QDateTimeEdit*>(pEditor);
                if(pDateTimeEdit)
                {
                    QString str;
                    if(hash.contains(DisplayFormat))
                    {
                        str = pDateTimeEdit->dateTime().toString(hash[DisplayFormat].toString());
                    }
                    else
                    {
                        str = pDateTimeEdit->dateTime().toString();
                    }
                    model->setData(index, str);
                }
                return;
            }
            case QVariant::List:
            {
                QComboBox* pComboBox = qobject_cast<QComboBox*>(pEditor);
                if(pComboBox)
                {
                    model->setData(index, pComboBox->currentText());
                }
                return;
            }
            default:
                break;
            }
        }
    }

    QLineEdit* pLineEdit = qobject_cast<QLineEdit*>(pEditor);
    if(pLineEdit)
    {
        model->setData(index, pLineEdit->text());
    }
}

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

QLineEdit *ItemDelegate::createLineEdit(const QVariantHash &hash, QWidget *pParent) const
{
    QLineEdit* pLineEdit = new QLineEdit(pParent);
    //设置提示文本
    if(hash.contains(ToolTip))
    {
        pLineEdit->setToolTip(hash[ToolTip].toString());
    }

    //设置输入格式
    if(hash.contains(InputMask))
    {
        pLineEdit->setInputMask(hash[InputMask].toString());
    }

    //设置最大输入字符个数
    if(hash.contains(MaxLength))
    {
        pLineEdit->setMaxLength(hash[MaxLength].toInt());
    }

    //设置输入限制
    if(hash.contains(RegExp))
    {
        pLineEdit->setValidator(new QRegExpValidator(QRegExp(hash[RegExp].toString()), pLineEdit));
    }

    return pLineEdit;
}

QSpinBox *ItemDelegate::createSpinBox(const QVariantHash &hash, QWidget *pParent) const
{
    QSpinBox* pSpinBox = new QSpinBox(pParent);

    //设置提示文本
    if(hash.contains(ToolTip))
    {
        pSpinBox->setToolTip(hash[ToolTip].toString());
    }

    //设置最小值
    if(hash.contains(Minimum))
    {
        pSpinBox->setMinimum(hash[Minimum].toInt());
    }

    //设置最大值
    if(hash.contains(Maximum))
    {
        pSpinBox->setMaximum(hash[Maximum].toInt());
    }

    //设置步长
    if(hash.contains(SingleStep))
    {
        pSpinBox->setSingleStep(hash[SingleStep].toInt());
    }

    //设置前缀文本
    if(hash.contains(Prefix))
    {
        pSpinBox->setPrefix(hash[Prefix].toString());
    }

    //设置后缀文本
    if(hash.contains(Suffix))
    {
        pSpinBox->setSuffix(hash[Suffix].toString());
    }

    return pSpinBox;
}

QDoubleSpinBox *ItemDelegate::createDoubleSpinBox(const QVariantHash &hash, QWidget *pParent) const
{
    QDoubleSpinBox* pDSpinBox = new QDoubleSpinBox(pParent);

    //设置提示文本
    if(hash.contains(ToolTip))
    {
        pDSpinBox->setToolTip(hash[ToolTip].toString());
    }

    //设置最小值
    if(hash.contains(Minimum))
    {
        pDSpinBox->setMinimum(hash[Minimum].toDouble());
    }

    //设置最大值
    if(hash.contains(Maximum))
    {
        pDSpinBox->setMaximum(hash[Maximum].toDouble());
    }

    //设置步长
    if(hash.contains(SingleStep))
    {
        pDSpinBox->setSingleStep(hash[SingleStep].toDouble());
    }

    //设置前缀文本
    if(hash.contains(Prefix))
    {
        pDSpinBox->setPrefix(hash[Prefix].toString());
    }

    //设置后缀文本
    if(hash.contains(Suffix))
    {
        pDSpinBox->setSuffix(hash[Suffix].toString());
    }

    return pDSpinBox;
}

QCheckBox *ItemDelegate::createCheckBox(const QVariantHash &hash, QWidget *pParent) const
{
    Q_UNUSED(hash)
    QCheckBox* pCheckBox = new QCheckBox(pParent);
    pCheckBox->setChecked(false);
    pCheckBox->setText("False");
    pCheckBox->setStyleSheet(QString("QCheckBox{background-color: white;}"));
    connect(pCheckBox, &QCheckBox::clicked, this, [=](bool bChecked){
        pCheckBox->setText(bChecked ? "True" : "False");
    });

    //设置提示文本
    if(hash.contains(ToolTip))
    {
        pCheckBox->setToolTip(hash[ToolTip].toString());
    }
    return pCheckBox;
}

QDateEdit *ItemDelegate::createDateEdit(const QVariantHash &hash, QWidget *pParent) const
{
    QDateEdit* pDateEdit = new QDateEdit(pParent);

    //设置提示文本
    if(hash.contains(ToolTip))
    {
        pDateEdit->setToolTip(hash[ToolTip].toString());
    }

    //设置显示样式
    if(hash.contains(DisplayFormat))
    {
        pDateEdit->setDisplayFormat(hash[DisplayFormat].toString());
    }

    //设置最大日期时间
    if(hash.contains(MaximumDateTime))
    {
        pDateEdit->setMaximumDateTime(hash[MaximumDateTime].toDateTime());
    }

    //设置最小日期时间
    if(hash.contains(MinimumDateTime))
    {
        pDateEdit->setMinimumDateTime(hash[MinimumDateTime].toDateTime());
    }
    return pDateEdit;
}

QTimeEdit *ItemDelegate::createTimeEdit(const QVariantHash &hash, QWidget *pParent) const
{
    QTimeEdit* pTimeEdit = new QTimeEdit(pParent);

    //设置提示文本
    if(hash.contains(ToolTip))
    {
        pTimeEdit->setToolTip(hash[ToolTip].toString());
    }

    //设置显示样式
    if(hash.contains(DisplayFormat))
    {
        pTimeEdit->setDisplayFormat(hash[DisplayFormat].toString());
    }

    //设置最大日期时间
    if(hash.contains(MaximumDateTime))
    {
        pTimeEdit->setMaximumDateTime(hash[MaximumDateTime].toDateTime());
    }

    //设置最小日期时间
    if(hash.contains(MinimumDateTime))
    {
        pTimeEdit->setMinimumDateTime(hash[MinimumDateTime].toDateTime());
    }
    return pTimeEdit;
}

QDateTimeEdit *ItemDelegate::createDateTimeEdit(const QVariantHash &hash, QWidget *pParent) const
{
    QDateTimeEdit* pDateTimeEdit = new QDateTimeEdit(pParent);

    //设置提示文本
    if(hash.contains(ToolTip))
    {
        pDateTimeEdit->setToolTip(hash[ToolTip].toString());
    }

    //设置显示样式
    if(hash.contains(DisplayFormat))
    {
        pDateTimeEdit->setDisplayFormat(hash[DisplayFormat].toString());
    }

    //设置最大日期时间
    if(hash.contains(MaximumDateTime))
    {
        pDateTimeEdit->setMaximumDateTime(hash[MaximumDateTime].toDateTime());
    }

    //设置最小日期时间
    if(hash.contains(MinimumDateTime))
    {
        pDateTimeEdit->setMinimumDateTime(hash[MinimumDateTime].toDateTime());
    }
    return pDateTimeEdit;
}

QComboBox *ItemDelegate::createComboBox(const QVariantHash &hash, QWidget *pParent) const
{
    QComboBox* pComboBox = new QComboBox(pParent);

    //设置提示文本
    if(hash.contains(ToolTip))
    {
        pComboBox->setToolTip(hash[ToolTip].toString());
    }

    //设置List
    if(hash.contains(ComboBoxValue))
    {
        pComboBox->addItems(hash[ComboBoxValue].toStringList());
    }
    return pComboBox;
}
    ui->tableWidget->setItemDelegate(new ItemDelegate);

    QTableWidgetItem* pItem = new QTableWidgetItem;
    pItem->setText("123");
    ui->tableWidget->setItem(0, 0, pItem);
    QVariantHash hash;
    hash.insert(EditorType, QVariant::String);
    hash.insert(MaxLength, 10);
    pItem->setData(ItemDelegateRole, hash);

    pItem = new QTableWidgetItem;
    pItem->setText("234");
    ui->tableWidget->setItem(0, 1, pItem);
    hash.clear();
    hash.insert(EditorType, QVariant::Int);
    hash.insert(Minimum, 0);
    hash.insert(Maximum, 1000);
    pItem->setData(ItemDelegateRole, hash);

    pItem = new QTableWidgetItem;
    pItem->setText("True");
    ui->tableWidget->setItem(0, 2, pItem);
    hash.clear();
    hash.insert(EditorType, QVariant::Bool);
    pItem->setData(ItemDelegateRole, hash);

    pItem = new QTableWidgetItem;
    pItem->setText("Test1");
    ui->tableWidget->setItem(1, 0, pItem);
    hash.clear();
    hash.insert(EditorType, QVariant::List);
    hash.insert(ComboBoxValue, QStringList() << "Test1" << "Test2" << "Test3");
    pItem->setData(ItemDelegateRole, hash);

    pItem = new QTableWidgetItem;
    QString strFormat = QString("yyyy/MM/dd hh:mm:ss");
    pItem->setText(QDateTime::currentDateTime().toString(strFormat));
    ui->tableWidget->setItem(1, 1, pItem);
    hash.clear();
    hash.insert(EditorType, QVariant::DateTime);
    hash.insert(DisplayFormat, strFormat);
    pItem->setData(ItemDelegateRole, hash);

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值