您的当前位置:首页正文

Qt 实战(10)模型视图 | 10.5、代理

2024-11-24 来源:个人技术集锦


前言:

一、代理

1、简介

Qt中的代理主要分为两类:QItemDelegateQStyledItemDelegateQStyledItemDelegateQItemDelegate的改进版,提供了更好的样式支持,能够与平台的外观和感觉保持一致,因此通常推荐使用QStyledItemDelegate

使用代理时要创建一个继承自QStyledItemDelegate的代理类,并重新几个比较重要的虚函数,每个虚函数的功能如下:

// 创建编辑器:当用户触发编辑行为时,代理负责创建并返回相应的编辑器控件(如QLineEdit、QSpinBox、QComboBox等)。
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 paint(QPainter *painter, const QStyleOptionViewItem &option,
    const QModelIndex &index) const override;

2、自定义代理

  • 创建代理类

    创建一个代理类,并实现前面提到的比较核心的几个虚函数

    // MyAddrDelegate.h
    
    #include "MyAddrDelegate.h"
    #include <QComboBox>
    
    MyAddrDelegate::MyAddrDelegate(QObject *parent)
    {
    
    }
    
    QWidget *MyAddrDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        QComboBox *editor = new QComboBox(parent);
        if (editor == nullptr)
            return nullptr;
    
        QStringList itemList;
        itemList << QString("北京");
        itemList << QString("上海");
        itemList << QString("西安");
    
        editor->addItems(itemList);
        editor->setFrame(false);
        return editor;
    }
    
    void MyAddrDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
    {
        QComboBox *combox = static_cast<QComboBox*>(editor);
        combox->setCurrentIndex(combox->findText(index.model()->data(index, Qt::EditRole).toString()));
    }
    
    void MyAddrDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
    {
        model->blockSignals(true);
        QComboBox *combox = static_cast<QComboBox*>(editor);
        model->setData(index, combox->currentText(), Qt::EditRole);
        emit OnCurrentTextChanged(index.row(), index.column(), combox->currentText());
        model->blockSignals(false);
    }
    
  • 使用代理

    MyAddrDelegate *pAddrDelegate = new MyAddrDelegate();
    ui.m_pTableWidget->setItemDelegateForColumn(1, pAddrDelegate);
    
  • 实现效果

显示全文