Russian Qt Forum

Qt => Model-View (MV) => Тема начата: Fregloin от Сентябрь 24, 2013, 12:14



Название: Объясните с добавлением строк/столбцов в модель
Отправлено: Fregloin от Сентябрь 24, 2013, 12:14
Привет. Есть простая модель.

Код:
class CServerMessageModel : public QAbstractTableModel
{
    Q_OBJECT

    typedef struct
    {
        CGenericRailObjectStorage   *   storage; //указатель на данные
        CDecodedMessage                 messageData; //по сути набор из строки+времени в qdatetime
    }
    InternalNode;

    QList<InternalNode>     fnodes;

public:
explicit CServerMessageModel(QObject *parent = 0);
    
    enum    {columnStorage,columnTime,columnMessageText,maxColumn};

    int         columnCount(const QModelIndex &parent) const;
    int         rowCount(const QModelIndex &parent) const;
    QVariant    data(const QModelIndex &index, int role) const;
    QVariant    headerData(int section, Qt::Orientation orientation, int role) const;
    bool        insertRows(int row, int count, const QModelIndex &parent);
...

public slots:
    
    void        acceptMessagesFromParser(CGenericRailObjectStorage * storage, const QList<CDecodedMessage> & messagesList);
    void        clear();
};

Объясните, как мне добавить элементы в слоте acceptMessagesFromParser

Сейчас такой код:
Код:
void CServerMessageModel::acceptMessagesFromParser(CGenericRailObjectStorage *storage, const QList<CDecodedMessage> &messagesList)
{
    if(messagesList.isEmpty())
        return;

    beginInsertRows(QModelIndex(),fnodes.size(),messagesList.size());
    foreach (const CDecodedMessage & decodedMessage, messagesList)
    {
        InternalNode    node;
        node.storage = storage;
        node.messageData = decodedMessage;
        fnodes.append(node);
    }
    endInsertRows();
    emit    messagesHasBeenAdded();
}

Проблема в следующем, если окно с таблицей (QTableView с этой моделью) не отображается, то после нескольких добавлений элементов и отображении окна список отображается правильно.
Если окно отображается и в модель добавляю строки, то так же в таблице отображаются пустые строки (вставляются) в арифмитической прогрессии. Разъясните, как правильно добавлять в модель?


Название: Re: Объясните с добавлением строк/столбцов в модель
Отправлено: Fregloin от Сентябрь 24, 2013, 12:42
Вот как сдалал сейчас - артефакт не пропал
Код:
bool CServerMessageModel::insertRows(int row, int count, const QModelIndex &parent)
{
    beginInsertRows(parent, row, row+count);
    for(int i=0;i<count;i++)
    {
        InternalNode node;
        node.storage = NULL;
        fnodes.insert(row,node);
    }
    endInsertRows();
    return  true;
}

bool CServerMessageModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if(index.isValid())
    {
        InternalNode & node = fnodes[index.row()];
        switch (role)
        {
        case StorageRole:
            node.storage = value.value<CGenericRailObjectStorage*>();
            emit    dataChanged(index,index);
            return  true;
        case MessageRole:
            node.messageData = value.value<CDecodedMessage>();
            emit    dataChanged(index,index);
            return  true;
        default:
            break;
        }
    }
    return  false;
}

void CServerMessageModel::acceptMessagesFromParser(CGenericRailObjectStorage *storage, const QList<CDecodedMessage> &messagesList)
{
    if(messagesList.isEmpty())
        return;

    if(insertRows(0,messagesList.size(),QModelIndex()))
    {
        int row = 0;
        foreach (const CDecodedMessage & currentMessage, messagesList)
        {
            QModelIndex currentIndex = index(row,0);
            setData(currentIndex,QVariant::fromValue(storage),StorageRole);
            setData(currentIndex,QVariant::fromValue(currentMessage),MessageRole);
            row++;
        }
        emit    messagesHasBeenAdded();
    }
    else
        qDebug("Couldn't add messages");
}

Суть та же, если виджет не отображается, то после нескольких добавлений все ок, при вызове виджета рисуется столько строк сколько надо.
Если же строки добавлять при отображаемом выиджете таблице, то на каждую добавляему строку также в конце списка добавляется пустая строка. Кто может подсказать, что я упустил из виду?
Строки нужно добавлять в начало списка, т.е. аля стек.


Название: Re: Объясните с добавлением строк/столбцов в модель
Отправлено: Fregloin от Сентябрь 24, 2013, 12:46
Еще ругается вот так QAbstractItemModel::endInsertRows:  Invalid index ( 2 , 0 ) in model CServerMessageModel(0x1231df8)


Название: Re: Объясните с добавлением строк/столбцов в модель
Отправлено: Bepec от Сентябрь 24, 2013, 12:50
// 70% вероятность что написанное ниже - мои домыслы :)

Код:
 beginInsertRows(QModelIndex(),fnodes.size(),messagesList.size());
Я так понимаю у вас сначала идёт размер контейнера с данными.

А у него случаем не с нуля отсчёт начинается? :P Тогда size будет больше на единицу. 
И при каждом добавлении массива данных будет +1 строка.

PS пока чуть занят, вечером посмотрю и вспомню что там надо :D


Название: Re: Объясните с добавлением строк/столбцов в модель
Отправлено: Fregloin от Сентябрь 24, 2013, 12:51
Да, именно так. Блин, немного странно у Qt с добавление/удалением... Спасибо, пока вопрос как бы решен.