解決QListView的編輯器不起作用的問題

最近按部就班地寫了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);
}

運行效果:

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章