最近按部就班地寫了QItemDelegate來實現QListView數據的編輯器功能,但運行後發現選中某一行數據編輯時,編輯器卻沒有正常顯示出來。查看了之前寫的代碼才發現是因爲自己漏掉了重寫QAbstractListModel的flags虛函數的步驟,我覺得這是一個很重要的點,分享出來供大家參考。
如下面的代碼,其中一個重寫了flags虛函數,另一個沒有重寫flags虛函數,從後面的運行效果可知,如果沒有重寫flags虛函數返回正確的配置數據,QListView的數據是無法被正常編輯的。
main.cpp
#include <QApplication>
#include <QListView>
#include <QHBoxLayout>
#include <QDebug>
#include <QListView>
#include "mylistviewmodel.h"
#include "useriddelegate.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget *mainWidget=new QWidget;
mainWidget->resize(300, 150);
mainWidget->setLayout(new QHBoxLayout);
MyListViewModel listViewModel1; //注意此處使用了MyListViewModel
QListView listView1;
UserIDDelegate delegate1;
listView1.setModel(&listViewModel1);
listView1.setItemDelegate(&delegate1);
listView1.setEditTriggers(QListView::AllEditTriggers);
MyListViewModelWithFlags listViewModel2; //注意此處使用了MyListViewModelWithFlags
QListView listView2;
UserIDDelegate delegate2;
listView2.setModel(&listViewModel2);
listView2.setItemDelegate(&delegate2);
listView2.setEditTriggers(QListView::AllEditTriggers);
mainWidget->layout()->addWidget(&listView1);
mainWidget->layout()->addWidget(&listView2);
mainWidget->show();
return a.exec();
}
mylistviewmodel.h
#ifndef MYLISTVIEWMODEL_H
#define MYLISTVIEWMODEL_H
#include <QAbstractListModel>
class MyListViewModel : public QAbstractListModel
{
Q_OBJECT
public:
MyListViewModel(QObject *parent = nullptr);
int rowCount(const QModelIndex &parent) const override;
int columnCount(const QModelIndex &parent) const override;
QVariant data(const QModelIndex &index, int role) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role);
protected:
QList<QString*> m_dataList;
};
class MyListViewModelWithFlags : public MyListViewModel
{
Q_OBJECT
public:
MyListViewModelWithFlags(QObject *parent = nullptr);
Qt::ItemFlags flags(const QModelIndex &index) const override;
};
#endif // MYLISTVIEWMODEL_H
mylistviewmodel.cpp
#include "mylistviewmodel.h"
MyListViewModel::MyListViewModel(QObject *parent)
: QAbstractListModel(parent)
{
for(int i=0; i<5; i++)
{
m_dataList.push_back(new QString(QString::number(i)));
}
}
int MyListViewModel::rowCount(const QModelIndex &parent) const
{
return m_dataList.size();
}
int MyListViewModel::columnCount(const QModelIndex &parent) const
{
return 1;
}
QVariant MyListViewModel::data(const QModelIndex &index, int role) const
{
switch (role) {
case Qt::DisplayRole:
case Qt::EditRole:
case Qt::UserRole:
return *(m_dataList.at(index.row()));
break;
default:
break;
}
return QVariant();
}
bool MyListViewModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if(role==Qt::EditRole)
{
*(m_dataList.at(index.row())) = value.toString();
}
return QAbstractListModel::setData(index, value, role);
}
MyListViewModelWithFlags::MyListViewModelWithFlags(QObject *parent)
: MyListViewModel(parent)
{
}
//重載這個flags虛函數,並在其中返回(Qt::ItemIsEditable | Qt::ItemIsEnabled),才能使編輯器生效
Qt::ItemFlags MyListViewModelWithFlags::flags(const QModelIndex &index) const
{
return (Qt::ItemIsEditable | Qt::ItemIsEnabled);
}
useriddelegate.h
#ifndef USERIDDELEGATE_H
#define USERIDDELEGATE_H
#include <QItemDelegate>
#include <QWidget>
class UserIDDelegate : public QItemDelegate
{
Q_OBJECT
public :
UserIDDelegate(QObject *parent = nullptr);
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 updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
};
#endif // USERIDDELEGATE_H
useriddelegate.cpp
#include "useriddelegate.h"
#include <QLineEdit>
UserIDDelegate::UserIDDelegate(QObject *parent)
: QItemDelegate(parent)
{
}
QWidget *UserIDDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QLineEdit *editor = new QLineEdit(parent);
QRegExp regExp( "[0-9]{0,10}" );
editor->setValidator( new QRegExpValidator(regExp, parent));
return editor;
}
void UserIDDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
QString text = index.model()->data(index, Qt::EditRole).toString();
QLineEdit *lineEdit = static_cast <QLineEdit*>(editor);
lineEdit->setText(text);
}
void UserIDDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
QLineEdit *lineEdit = static_cast <QLineEdit*>(editor);
QString text = lineEdit->text();
model->setData(index, text, Qt::EditRole);
}
void UserIDDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
editor->setGeometry(option.rect);
}
運行效果:
(---------------------完-----------------)