在C++ QT中,可以通过自定义Delegate来实现显示自定义空间的列表。具体步骤如下:
- 定义一个类MyItem,用于存储列表项的数据:
class MyItem
{
public:
QString name;
int age;
};
- 定义一个类MyDelegate,继承QStyledItemDelegate,并重写以下函数:
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
void setEditorData(QWidget *editor, const QModelIndex &index) const;
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
其中,sizeHint返回项的大小,paint负责绘制项的内容,createEditor创建编辑器(用于编辑该项),setEditorData将该项数据设置到编辑器上,setModelData将编辑器上的数据设置到该项上。
- 在MainWindow中创建一个ListView对象,并设置Delegate为MyDelegate:
ListView *listView = new ListView();
MyDelegate *myDelegate = new MyDelegate();
listView->setItemDelegate(myDelegate);
- 在MyDelegate中添加绘制和编辑代码:
QSize MyDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
return QSize(200, 50); // 返回项的大小
}
void MyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
// 绘制项的背景和边框
painter->save();
if (option.state & QStyle::State_Selected)
painter->fillRect(option.rect, option.palette.highlight());
else
painter->fillRect(option.rect, option.palette.background());
painter->setPen(QPen(Qt::black));
painter->drawRect(option.rect);
painter->restore();
// 绘制项的数据(例如,姓名和年龄)
MyItem item = index.data(Qt::UserRole).value<MyItem>();
QString text = QString("%1 (%2)").arg(item.name).arg(item.age);
painter->drawText(option.rect, Qt::AlignCenter, text);
}
QWidget* MyDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
// 创建一个自定义的编辑器,并设置其初始值为该项的数据
QLineEdit *editor = new QLineEdit(parent);
MyItem item = index.data(Qt::UserRole).value<MyItem>();
editor->setText(QString("%1,%2").arg(item.name).arg(item.age));
return editor;
}
void MyDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
// 将该项数据设置到编辑器上
QLineEdit *lineEdit = qobject_cast<QLineEdit*>(editor);
MyItem item = index.data(Qt::UserRole).value<MyItem>();
lineEdit->setText(QString("%1,%2").arg(item.name).arg(item.age));
}
void MyDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
// 将编辑器上的数据设置到该项上,并更新ListView视图
QLineEdit *lineEdit = qobject_cast<QLineEdit*>(editor);
QStringList values = lineEdit->text().split(",");
MyItem item;
item.name = values[0];
item.age = values[1].toInt();
model->setData(index, QVariant::fromValue(item), Qt::UserRole);
}
- 在MainWindow中添加数据到ListView中:
MyItem item1{"Tom", 25};
MyItem item2{"John", 30};
MyItem item3{"Mary", 20};
QStandardItemModel *model = new QStandardItemModel(this);
model->setItemDelegate(myDelegate);
QStandardItem *item = new QStandardItem();
item->setData(QVariant::fromValue(item1), Qt::UserRole);
model->appendRow(item);
item = new QStandardItem();
item->setData(QVariant::fromValue(item2), Qt::UserRole);
model->appendRow(item);
item = new QStandardItem();
item->setData(QVariant::fromValue(item3), Qt::UserRole);
model->appendRow(item);
listView->setModel(model);
- 编译运行程序,就可以看到ListView中已经显示了自定义的列表项。
注意:在使用自定义Delegate时,必须将该Delegate设置到ListView的setItemDelegate方法上。并且,在设置数据时,需要将该项数据保存在Qt::UserRole角色上,以便在Delegate中获取。