解决QListView的编辑器不起作用的问题

最近按部就班地写了QItemDelegate来实现QListView数据的编辑器功能,但运行后发现选中某一行数据编辑时,编辑器却没有正常显示出来。查看了之前写的代码才发现是因为自己漏掉了重写QAbstractListModel的flags虚函数的步骤,我觉得这是一个很重要的点,分享出来供大家参考。

如下面的代码,其中一个重写了flags虚函数,另一个没有重写flags虚函数,从后面的运行效果可知,如果没有重写flags虚函数返回正确的配置数据,QListView的数据是无法被正常编辑的。

main.cpp

#include 
#include 
#include 
#include 
#include 

#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 

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 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 
#include 

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 

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 (editor);
    lineEdit->setText(text);
}

void UserIDDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
    QLineEdit *lineEdit =  static_cast (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);
}

运行效果:

解决QListView的编辑器不起作用的问题_第1张图片

(---------------------完-----------------)

你可能感兴趣的:(Qt)