首先在介绍QListView之前,先说一下QListView和QListWidget的区别:
1、QListView是model(模型/视图)表格类型,QListWidget它是Item表格类型。
2、QListView使用较复杂,一般需要配合数据模型QAbstractListModel和item代理QStyledItemDelegate来使用。而QListWidget使用简单,只需要配合QListWidgetItem来使用。
3、QListView在大批量数据操作的场景下比QListTable快很多。原因是QListWidget它的数据都绑定了一个Item控件,数据较多时,对Item操作就较多。而QListView的数据就只绑定了一个代理,大批量数据操作时,只在代理中绘制这些数据。
了解它们的区别后,现在我们来详细了解下QListView它的使用方法。
QListView由于它是模型/视图的结构,所以它的数据交给了QAbstractListModel来处理,它的视图交给了QStyledItemDelegate来处理。
QAbstractListModel常用函数:
//获取指定行列的model项,model项可以用来获取数据。
virtual QModelIndex index(int row, int column,
const QModelIndex &parent = QModelIndex()) const = 0;
//行数
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const = 0;
//列数
virtual int columnCount(const QModelIndex &parent = QModelIndex()) const = 0;
//获取当前index位置的数据
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const = 0;
//设置数据
virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
//标准插入QStandardItem
void QStandardItemModel::appendRow(QStandardItem *aitem);
//插入多行
virtual bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex());
//插入多列
virtual bool insertColumns(int column, int count, const QModelIndex &parent = QModelIndex());
//删除多行
virtual bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex());
//删除多列
virtual bool removeColumns(int column, int count, const QModelIndex &parent = QModelIndex());
//插入行
bool insertRow(int row, const QModelIndex &parent = QModelIndex());
//插入列
bool insertColumn(int column, const QModelIndex &parent = QModelIndex());
//删除行
bool removeRow(int row, const QModelIndex &parent = QModelIndex());
//删除列
bool removeColumn(int column, const QModelIndex &parent = QModelIndex());
//更新数据
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles = QVector());
//指定起始插入位置插入,该方法一般用于重写InsertRows后调用。
// void beginInsertRows(const QModelIndex &parent, int first, int last);
//结束插入
void endInsertRows();
//指定起始插入位置删除,该方法一般用于重写removRows后调用
void beginRemoveRows(const QModelIndex &parent, int first, int last);
//结束删除
void endRemoveRows();
QStyledItemDelegate常用函数
//绘制Index项Ui
void paint(QPainter *painter,
const QStyleOptionViewItem &option, const QModelIndex &index) const;
//设置index项大小
QSize sizeHint(const QStyleOptionViewItem &option,const QModelIndex &index) const override;
//捕获index位置上的事件。
bool editorEvent(QEvent *event, QAbstractItemModel *model,
const QStyleOptionViewItem &option, const QModelIndex &index);
先简单介绍两个不继承QAbstractListModel的使用:
QAbstractListModel是QStringListModel时:
QStringListModel *pModel = new QStringListModel();
m_listView->setModel(pModel);
for (int i=0; i<3; ++i) {
pModel->insertRow(i); //在尾部插入一空行
QModelIndex index= pModel->index(i-1,0);//获取最后一行
pModel->setData(index,"123", Qt::DisplayRole);
pModel->setData(index,"aaa", Qt::DisplayRole);
pModel->setData(index,"ddd", Qt::DisplayRole);
m_listView->setCurrentIndex(index);
}
QAbstractListModel是QStandardItemModel时:
QStandardItemModel *pModel = new QStandardItemModel();
for (int i=0; i<3; ++i) {
QStandardItem *pItem = new QStandardItem;
pItem->setData("123", Qt::UserRole+1);
pItem->setData("aaa", Qt::UserRole+2);
pItem->setData("ddd", Qt::UserRole+3);
pModel->appendRow(pItem);
}
继承QAbstractListModel的使用
QListView使用方法,首先需要加载Model和delegate。
m_listView->setItemDelegate(&m_delegate);
m_listView->setModel(&m_model);
然后继承QStyledItemDelegate进行绘制
//头文件
class MStyleItemDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
MStyleItemDelegate();
void paint(QPainter *painter,
const QStyleOptionViewItem &option, const QModelIndex &index) const;
QSize sizeHint(const QStyleOptionViewItem &option,const QModelIndex &index) const override;
bool editorEvent(QEvent *event, QAbstractItemModel *model,
const QStyleOptionViewItem &option, const QModelIndex &index);
};
//cpp文件
MStyleItemDelegate::MStyleItemDelegate()
{
}
void MStyleItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if (!index.isValid())
return;
//取数据
QString id = index.data(Qt::UserRole + 1).toString();
QString name = index.data(Qt::UserRole + 2).toString();
QString age = index.data(Qt::UserRole + 3).toString();
QStyleOptionViewItem viewoption(option);
initStyleOption(&viewoption, index);
if (option.state.testFlag(QStyle::State_HasFocus))
{
viewoption.state = viewoption.state ^ QStyle::State_HasFocus;
painter->setBrush(QBrush(QColor("#234567")));
painter->drawRect(option.rect);
}
else if (option.state.testFlag(QStyle::State_MouseOver))
{
painter->setBrush(QBrush(QColor("#543234")));
painter->drawRect(option.rect);
}
QStyledItemDelegate::paint(painter, viewoption, index);
//绘制文本
painter->save();
QRectF rect;
rect.setX(option.rect.x());
rect.setY(option.rect.y());
rect.setWidth(option.rect.width() - 1);
rect.setHeight(option.rect.height() - 1);
//设置字体,颜色
QFont font;
font.setFamily("Microsoft YaHei");
font.setPixelSize(12);
painter->setFont(font);
QRect textRect1(rect.left() + 10, rect.top() + TOP_MARGIN, option.widget->width()/3, HEIGHT);
QRect textRect2(option.widget->width()/4, rect.top() + TOP_MARGIN, option.widget->width()/4, rect.height());
QRect textRect3(option.widget-