2016-07-29 110 views
2

我有下面的类,它代表了数据结构记录:QAbstractTableModel :: insertRows追加新的数据到内部的QList

#ifndef UECONNECTEDCLIENTRECORD_H 
#define UECONNECTEDCLIENTRECORD_H 

#include <QtGlobal> 
#include <QObject> 
#include <QHostAddress> 
#include <QString> 

class UeConnectedClientRecord : public QObject 
{ 
    Q_OBJECT 

private: 
    /** 
    * @brief m_ueClientName 
    */ 
    QString m_ueClientName; 

    /** 
    * @brief m_ueClientAddress 
    */ 
    QHostAddress m_ueClientAddress; 

    /** 
    * @brief m_ueClientPort 
    */ 
    QString m_ueClientPort; 

public: 
    /** 
    * @brief UeConnectedClientRecord 
    * @param parent 
    */ 
    explicit UeConnectedClientRecord(const QString& clientName=QString(), 
            const QHostAddress& clientAddress=QHostAddress(), 
            const QString& clientPort=QString()); 

    /** 
    * @brief ueSetClientName 
    * @param name 
    */ 
    inline void ueSetClientName(const QString& name) 
     { this->m_ueClientName=name; } 

    /** 
    * @brief ueSetClientAddress 
    * @param address 
    */ 
    inline void ueSetClientAddress(const QHostAddress& address) 
     { this->m_ueClientAddress=address; } 

    /** 
    * @brief ueSetClientPort 
    * @param port 
    */ 
    inline void ueSetClientPort(const QString& port) 
     { this->m_ueClientPort=port; } 

    /** 
    * @brief ueClientName 
    * @return client name 
    */ 
    inline const QString& ueClientName() const 
     { return this->m_ueClientName; } 

    /** 
    * @brief ueClientAddress 
    * @return client address 
    */ 
    inline const QHostAddress& ueClientAddress() const 
     { return this->m_ueClientAddress; } 

    /** 
    * @brief ueClientPort 
    * @return client port 
    */ 
    inline const QString& ueClientPort() const 
     { return this->m_ueClientPort; } 
}; 

#endif // UECONNECTEDCLIENTRECORD_H 

这是在子类QAbstractTableModel使用:

#ifndef UECONNECTEDCLIENTSTABLEMODEL_H 
#define UECONNECTEDCLIENTSTABLEMODEL_H 

#include <QObject> 
#include <QAbstractTableModel> 
#include <QList> 
#include <QModelIndex> 
#include <QVariant> 
#include <QHash> 
#include <QByteArray> 

#include "ueconnectedclientrecord.h" 

class UeConnectedClientsTableModel : public QAbstractTableModel 
{ 
    Q_OBJECT 

private: 
    /** 
    * @brief m_ueConnectedClientData 
    */ 
    QList<UeConnectedClientRecord*> m_ueConnectedClientData; 

protected: 
    /** 
    * @brief ueSetConnectedClientData 
    * @param clientData 
    */ 
    inline void ueSetConnectedClientData(const QList<UeConnectedClientRecord*>& clientData) 
     { this->m_ueConnectedClientData=clientData; } 

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

    /** 
    * @brief ueConnectedClientData 
    * @return connected client data 
    */ 
    inline const QList<UeConnectedClientRecord*>& ueConnectedClientData() const 
     { return this->m_ueConnectedClientData; } 

    /** 
    * @brief rowCount 
    * @param parent 
    * @return number of rows in model 
    */ 
    inline int rowCount(const QModelIndex& /*parent*/) const 
     { return this->ueConnectedClientData().size(); } 

    /** 
    * @brief columnCount 
    * @return number of columns in model 
    */ 
    inline int columnCount(const QModelIndex& /*parent*/) const 
     { return 3; } 

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

    /** 
    * @brief roleNames 
    * @return role names 
    */ 
    QHash<int, QByteArray> roleNames() 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 insertRows 
    * @param row 
    * @param count 
    * @param parent 
    * @return true if the rows were successfully inserted; otherwise returns false 
    */ 
    bool insertRows(int row, 
        int count, 
        const QModelIndex& parent=QModelIndex()); 

    /** 
    * @brief removeRows 
    * @param row 
    * @param count 
    * @param parent 
    * @return true if the rows were successfully removed; otherwise returns false 
    */ 
    bool removeRows(int row, 
        int count, 
        const QModelIndex& parent=QModelIndex()); 

public: 
    /** 
    * @brief ueRoleClientName 
    */ 
    static const int ueRoleClientName=Qt::UserRole+1; 

    /** 
    * @brief ueRoleClientAddress 
    */ 
    static const int ueRoleClientAddress=Qt::UserRole+2; 

    /** 
    * @brief ueRoleCllientPort 
    */ 
    static const int ueRoleCllientPort=Qt::UserRole+3; 
}; 

#endif // UECONNECTEDCLIENTSTABLEMODEL_H 

及其实施:

#include "ueconnectedclientstablemodel.h" 

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

QVariant UeConnectedClientsTableModel::data(const QModelIndex& index, 
              int role) const 
{ 
    switch(role) 
    { 
     case ueRoleClientName: 
     { 
      return this->ueConnectedClientData().at(index.row())->ueClientName(); 
     } // case 

     case ueRoleClientAddress: 
     { 
      return this->ueConnectedClientData().at(index.row())->ueClientAddress().toString(); 
     } // case 

     case ueRoleCllientPort: 
     { 
      return this->ueConnectedClientData().at(index.row())->ueClientPort().toInt(); 
     } // case 

     default: 
     { 
      return UeConnectedClientsTableModel::data(index, 
                 role); 
     } // default 
    } // switch 
} // data 

QHash<int, QByteArray> UeConnectedClientsTableModel::roleNames() const 
{ 
    QHash<int, QByteArray> roles; 

    const int roleClientName=UeConnectedClientsTableModel::ueRoleClientName; 
    const int roleClientAddress=UeConnectedClientsTableModel::ueRoleClientAddress; 
    const int roleCllientPort=UeConnectedClientsTableModel::ueRoleCllientPort; 

    roles.insert(roleClientName, 
       "roleClientName"); 
    roles.insert(roleClientAddress, 
       "roleClientAddress"); 
    roles.insert(roleCllientPort, 
       "roleCllientPort"); 

    return roles; 
} // roleNames 

QVariant UeConnectedClientsTableModel::headerData(int section, 
                Qt::Orientation orientation, 
                int role) const 
{ 
    Q_UNUSED(orientation) 

    if(role!=Qt::DisplayRole) 
     return QVariant(); 

    switch(section) 
    { 
     case 0: 
     { 
      return tr("Client name"); 
     } // case 

     case 1: 
     { 
      return tr("Client address"); 
     } // case 

     case 2: 
     { 
      return tr("Client port"); 
     } // case 

     default: 
     { 
      return QVariant(); 
     } // default 
    } // switch 
} // headerData 

bool UeConnectedClientsTableModel::insertRows(int row, 
               int count, 
               const QModelIndex& parent) 
{ 
    this->beginInsertRows(parent, 
          row, 
          row+count); 

    for(int index=row; index<row+count; index++) 
    { 
     m_ueConnectedClientData.append(new UeConnectedClientRecord()); 
    } // for 

    this->endInsertRows(); 

    return true; 
} // insertRows 

bool UeConnectedClientsTableModel::removeRows(int row, 
               int count, 
               const QModelIndex& parent) 
{ 
    this->beginRemoveRows(parent, 
          row, 
          row+count); 

    for(int index=row; index<row+count; index++) 
    { 
     m_ueConnectedClientData.removeLast(); 
    } // for 

    this->endRemoveRows(); 

    return true; 
} // removeRows 

现在,我该如何从cod中调用insertRows() e向内部QList插入带有实际数据的新的UeConnectedClientRecord(不是new UeConnectedClientRecord() - 默认构造函数)?因为我已经搜查翻过网上看到的例子我发现Qt Address Book Example我问了,但是,insertRows() from official docsinsertRows() from Address Book Example声明不同:

  • bool QAbstractItemModel::insertRows(int row, int count, const QModelIndex &parent = QModelIndex());docs
  • bool insertRows(int position, int rows, const QModelIndex &index = QModelIndex()) Q_DECL_OVERRIDE;Address Book Example

为什么?

+0

'insertRows'函数声明类似。仔细地看。 – ilotXXI

+0

@liotXXl是的,有类似的,好的,但至少有误导性。 – KernelPanic

+1

要将“真实”数据插入到模型中,地址簿示例具有“AddressWidget :: addEntry”,该地址首先调用insertRows将新的默认构造的空行插入到模型中。然后,它接下来为新插入的行设置数据。 – arhzu

回答

2

从技术文档:

如果你实现你自己的模型,你可以,如果你想支持插入重新实现此功能。或者,您可以提供自己的API来更改数据。无论哪种情况,您都需要致电beginInsertRows()endInsertRows()以通知其他组件已通知模型已更改。

方法1.使用insertRows + setData。 Qt假设null记录是可能的,添加行不是添加数据。由于您的内部列表是指针的Qlist,您可以在那里插入nullptr以防止默认的构造函数调用。在这种情况下,您需要对每个data呼叫进行项目检查:如果项目为nullptr,则应返回默认值。

方式2.您可以实现自己的插入功能。据我所知,insertRows函数不被视图使用,通常被手动调用。但“通常”不是“永远”。例如,代理模型可以使用它。

+0

@ilotXXl我决定和** Way 1 **一起去,但是,我还需要重新实现'index()'方法吗? – KernelPanic

+0

@KernelPanic我认为不,'QAbstractTableModel'为你做到了。看看[文档](http://doc.qt.io/qt-5/qabstracttablemodel.html#details),子类化段落。 – ilotXXI