2016-08-07 2 views
0

J'ai sous-classé QAbstractTableModel avec QJsonDocument comme source de données. Voici le fichier d'en-tête:Mise à jour programmatique du modèle QAbstractTableModel sous-classé et rafraîchissant sous-classé QTableView

#ifndef UEJSONPLACESTABLEMODEL_H 
#define UEJSONPLACESTABLEMODEL_H 

#include <QAbstractTableModel> 
#include <QJsonDocument> 
#include <QJsonArray> 
#include <QJsonObject> 
#include <QJsonValue> 
#include <QVariant> 
#include <QVariantMap> 
#include <QVariantList> 

class UeJsonPlacesTableModel : public QAbstractTableModel 
{ 
private: 
    /** 
    * @brief m_ueJsonData 
    */ 
    QJsonDocument m_ueJsonData; 

/*protected:*/ 
public: 
    /** 
    * @brief ueSetJsonData 
    * @param jsonData 
    */ 
    void ueSetJsonData(const QJsonDocument& jsonData); 

public: 
    /** 
    * @brief UeJsonPlacesTableModel 
    * @param parent 
    */ 
    UeJsonPlacesTableModel(QObject* parent=Q_NULLPTR); 

    /** 
    * @brief ueJsonData 
    * @return pointer to object representing JSON document 
    */ 
    const QJsonDocument& ueJsonData() 
     { return this->m_ueJsonData; } 

    /** 
    * @brief rowCount 
    * @param parent 
    * @return number of rows 
    */ 
    int rowCount(const QModelIndex& parent=QModelIndex()) const; 

    /** 
    * @brief columnCount 
    * @param parent 
    * @return number of columns 
    */ 
    int columnCount(const QModelIndex& parent=QModelIndex()) const; 

    /** 
    * @brief data 
    * @param index 
    * @param role 
    * @return data 
    */ 
    QVariant data(const QModelIndex& index, 
        int role=Qt::DisplayRole) const; 

    /** 
    * @brief headerData 
    * @param section 
    * @param orientation 
    * @param role 
    * @return header data 
    */ 
    QVariant headerData(int section, 
         Qt::Orientation orientation, 
         int role=Qt::DisplayRole) const; 

    /** 
    * @brief flags 
    * @param index 
    * @return flags for index's cell 
    */ 
    Qt::ItemFlags flags(const QModelIndex& index) const; 

    /** 
    * @brief setData 
    * @param index 
    * @param value 
    * @param role 
    * @return true if succesfull, otherwise false 
    */ 
    bool setData(const QModelIndex& index, 
       const QVariant& value, 
       int role=Qt::EditRole); 

    /** 
    * @brief insertRows 
    * @param row 
    * @param count 
    * @param parent 
    * @return true if succesfull, otherwise false 
    */ 
    bool insertRows(int row, 
        int count, 
        const QModelIndex& parent=QModelIndex()); 

    /** 
    * @brief removeRows 
    * @param row 
    * @param count 
    * @param parent 
    * @return true if succesfull, otherwise false 
    */ 
    bool removeRows(int row, 
        int count, 
        const QModelIndex& parent=QModelIndex()); 
}; 

#endif // UEJSONPLACESTABLEMODEL_H 

et voici son implemenation:

#include "uejsonplacestablemodel.h" 

UeJsonPlacesTableModel::UeJsonPlacesTableModel(QObject* parent) 
    : QAbstractTableModel(parent) 
{ 
} // constructor 

int UeJsonPlacesTableModel::rowCount(const QModelIndex &parent) const 
{ 
    Q_UNUSED(parent) 

    return this->m_ueJsonData.isArray()?this->m_ueJsonData.array().size():this->m_ueJsonData.isObject()?this->m_ueJsonData.object().size():0; 
} // rowCount 

void UeJsonPlacesTableModel::ueSetJsonData(const QJsonDocument& jsonData) 
{ 
    this->beginResetModel(); 

    this->m_ueJsonData=jsonData; 
    emit dataChanged(QModelIndex(), 
        QModelIndex()); 

    this->endResetModel(); 
} // ueSetJsonData 

int UeJsonPlacesTableModel::columnCount(const QModelIndex &parent) const 
{ 
    Q_UNUSED(parent) 

    return this->m_ueJsonData.isArray()?this->m_ueJsonData.array().at(0).toObject().keys().size():this->m_ueJsonData.isObject()?this->m_ueJsonData.object().keys().size():0; 
} // columnCount 

QVariant UeJsonPlacesTableModel::data(const QModelIndex& index, 
             int role) const 
{ 
    if(role!=Qt::DisplayRole|| 
      index.row()<0|| 
      index.row()>=this->m_ueJsonData.isArray()?this->m_ueJsonData.array().size():this->m_ueJsonData.isObject()?this->m_ueJsonData.object().size():0|| 
      index.column()<0|| 
      index.column()>=this->m_ueJsonData.isArray()?this->m_ueJsonData.array().at(0).toObject().keys().size():this->m_ueJsonData.isObject()?this->m_ueJsonData.object().keys().size():0) 
    { 
     return QVariant(); 
    } // if 

    return this->m_ueJsonData.isArray()?this->m_ueJsonData.array().at(index.row()).toObject().value(this->m_ueJsonData.array().at(index.row()).toObject().keys().at(index.column())).toString(): 
             this->m_ueJsonData.isObject()?this->m_ueJsonData.object().value(this->m_ueJsonData.array().at(index.row()).toObject().keys().at(index.column())).toString(): 
             QVariant(); 
} // data 

QVariant UeJsonPlacesTableModel::headerData(int section, 
              Qt::Orientation orientation, 
              int role) const 
{ 
    if(role!=Qt::DisplayRole|| 
      section<0|| 
      section>=this->m_ueJsonData.isArray()?this->m_ueJsonData.array().size():this->m_ueJsonData.isObject()?this->m_ueJsonData.object().size()>0?this->m_ueJsonData.object().size():0:0) 
    { 
     return QVariant(); 
    } // if 

    switch(orientation) 
    { 
     case Qt::Horizontal: 
     { 
      return this->m_ueJsonData.isArray()?this->m_ueJsonData.array().size()>0?this->m_ueJsonData.array().at(0).toObject().keys().at(section): 
               this->m_ueJsonData.isObject()?this->m_ueJsonData.object().size()>0?this->m_ueJsonData.object().keys().at(section): 
               QVariant(): 
               QVariant(): 
               QVariant(); 
     } // case 

     case Qt::Vertical: 
     { 
      return QAbstractTableModel::headerData(section, 
                orientation, 
                role); 
     } // case 
    } // switch 

    return QVariant(); 
} // headerData 

Qt::ItemFlags UeJsonPlacesTableModel::flags(const QModelIndex& index) const 
{ 
    return index.column()==0?QAbstractTableModel::flags(index)^Qt::ItemIsEditable:QAbstractTableModel::flags(index); 
} // flags 

bool UeJsonPlacesTableModel::setData(const QModelIndex& index, 
            const QVariant& value, 
            int role) 
{ 
    if(role!=Qt::EditRole|| 
      index.row()<0|| 
      index.row()>=this->m_ueJsonData.isArray()?this->m_ueJsonData.array().size():this->m_ueJsonData.isObject()?this->m_ueJsonData.object().size():0|| 
      index.column()<0|| 
      index.column()>=this->m_ueJsonData.isArray()?this->m_ueJsonData.array().size():this->m_ueJsonData.isObject()?this->m_ueJsonData.object().size()>0?this->m_ueJsonData.object().size():0:0) 
    { 
     return false; 
    } // if 

    QVariantList dataList=this->m_ueJsonData.toVariant().toList(); 
    QVariantMap dataVariantMap=this->m_ueJsonData.toVariant().toList().at(index.row()).toMap(); 
    QVariantMap::const_iterator dataIterator=dataVariantMap.constBegin(); 
    int dataIndex=0; 
    QString keyName=QString(); 
    QString dataValue=QString(); 

    while(dataIterator!=dataVariantMap.constEnd()) 
    { 
     if(dataIndex==index.column()) 
     { 
      keyName=dataVariantMap.keys().at(dataIndex); 
     } 
     else 
     { 
      dataIterator++; 
      dataIndex++; 
     } // if 
    } // while 

    QVariantMap changedData; 

    changedData.insert(keyName, 
         value.toString()); 

    dataList.replace(index.row(), 
        changedData); 

    this->m_ueJsonData=QJsonDocument::fromVariant(dataList); 

    emit(dataChanged(index, 
        index)); 

    return true; 
} // setData 

bool UeJsonPlacesTableModel::insertRows(int row, 
             int count, 
             const QModelIndex& parent) 
{ 
    Q_UNUSED(parent) 

    this->beginInsertRows(QModelIndex(), 
          row, 
          row+count-1); 

    for(int index=row; index<row+count; ++index) 
    { 
     this->m_ueJsonData.toVariant().toList().insert(row, 
                 this->m_ueJsonData.toVariant()); 
    } // for 

    this->endInsertRows(); 

    return true; 
} // insertRows 

bool UeJsonPlacesTableModel::removeRows(int row, 
             int count, 
             const QModelIndex& parent) 
{ 
    Q_UNUSED(parent) 

    this->beginRemoveRows(QModelIndex(), 
          row, 
          row+count-1); 

    for(int index=row; index<row+count; ++index) 
    { 
     this->m_ueJsonData.toVariant().toList().removeAt(index); 
    } // for 

    this->endRemoveRows(); 

    return true; 
} // removeRows 

Maintenant, quand de nouvelles données arrivent, je l'enregistre dans QJsonDocument, mais je ne sais pas comment mettre à jour un modèle. Voici mon essai de l » slotMainWindow, WHIC EST Licenciement (je l'ai vérifié triple), néanmoins, le QTableView, responsable de données de model montrant, est vide:

void MainWindow::ueSlotUpdatePlacesView(const QJsonDocument& newData) 
{ 
    this->uePlacesViewDialog()->uePlacesTableView()->ueTablePlacesModel()->ueSetJsonData(newData); 

// qDebug() << Q_FUNC_INFO 
//    << this->uePlacesViewDialog()->uePlacesTableView()->ueTablePlacesModel()->rowCount(); 
} // ueSlotUpdatePlacesView 

Comment puis-je mettre à jour subclassewd QAbstractTableModel puis actualiser sous-classé QTableView?

+1

Peut-être hors sujet, mais ... pourquoi passez-vous un défaut construit 'QModelIndex()' comme argument '' parent' à QAbstractItemModel: : beginInsertRows' plutôt que le * parent' réel * comme passé à 'insertRows'? –

+0

J'ai raté cela totalement, va vérifier et rediffuser! – KernelPanic

Répondre

1

Assurez-vous d'utiliser le QObject MAcro lors de la déclaration de votre classe

class UeJsonPlacesTableModel : public QAbstractTableModel 
{ 
    Q_OBJECT 

private: 
    QJsonDocument m_ueJsonData;