Qt中的代理主要分为两类:
QItemDelegate
和QStyledItemDelegate
。QStyledItemDelegate
是QItemDelegate
的改进版,提供了更好的样式支持,能够与平台的外观和感觉保持一致,因此通常推荐使用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;
创建代理类
创建一个代理类,并实现前面提到的比较核心的几个虚函数
// 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);
实现效果