Russian Qt Forum

Qt => Model-View (MV) => Тема начата: Авварон от Август 18, 2009, 21:16



Название: itemModel
Отправлено: Авварон от Август 18, 2009, 21:16
в общем не работает item model. Делал по образу и подобию примера simpleTreeModel... вроде кардинально ничего не менял...
в общем внутри модели также дерево - пустой rootItem, у него дети. Дебаггер говорит, что тут все верно.
метод index также отрабатывает верно (ставим брейкпоинт, видим правильные данные). А вот метод data возвращает фигню
Код:
QVariant QMPQModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();

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

    TreeItem *item = static_cast<TreeItem*>(index.internalPointer());

    qDebug() << "QMPQModel::data" << index.row() << index.column() <<  item->data(0).toString();
    return item->data(index.column());
}
дебаг говорит что внутри у item <internal error> вместо данных... что делать? уже 2 часа угробил:( выкладывать компилябельный проект?..


Название: Re: itemModel
Отправлено: denka от Август 18, 2009, 21:22
Желательно, т.к. по сему коду ничего не скажешь.


Название: Re: itemModel
Отправлено: Авварон от Август 18, 2009, 21:41
вот, по идее должно собраться, внешние линки убрал
http://mtgs.clan.su/QMPQ.zip (http://mtgs.clan.su/QMPQ.zip)


Название: Re: itemModel
Отправлено: Авварон от Август 18, 2009, 21:52
ахахах, я идиот))) напоролся на "заглушку"
QVariant TreeItem::data(int column) const
{
//    return itemData.value(column);
    if (column == 1) {
        return name;
    }
    else
        return QVariant();
}
а надо 0, ппц...


Название: Re: itemModel
Отправлено: ритт от Август 19, 2009, 01:36
тему грохать?


Название: Re: itemModel
Отправлено: Авварон от Август 19, 2009, 09:21
Подожди пожалуйста, пара вопросов есть - вернее нужно сказать, в том ли я направлении думаю:)
1) как по айтему в дереве получить индекс? тупо создать его через createIndex(item->row(), 0, item)?
2) пусть дано дерево файлов в архиве. Каждому файлу и папке соответствует TreeItem. Для доступа по пути в модель надо встраивать хэштейбл<путь, TreeItem*> или есть другие более прямые пути?


Название: Re: itemModel
Отправлено: Авварон от Август 23, 2009, 22:57
с вопросами 1 и 2 разобрался, все было легко...
а как сделать такое: есть ветка в дереве модели, нужно ее перекинуть в другое место. Тут идет и удаление и вставка рядов - и как корректно реализовать, не разбивая на 2 действия?
Код:
bool QMPQModel::rename(const QModelIndex & index, const QString & newName)
{
    bool result;
    TreeItem * item = getItem(index); //обертка с проверками вокруг index.internalPointer()
    result = archive->rename(item, newName); //перенос ветки
//    reset(); //так работает, но закрывает все раскрытые ветки - некрасиво
    return result;

}


Название: Re: itemModel
Отправлено: ритт от Август 24, 2009, 00:10
до 4.7 - никак.
можешь реализовать переброску индексов и данных внутри своей модели, но придётся сигнализировать всюхам об изменении *всех* данных. в качестве альтернативы можешь использовать прокси, но тогда ожидай падения производительности.


Название: Re: itemModel
Отправлено: Авварон от Август 24, 2009, 08:19
то есть самый простой способ:
Код:
bool QMPQModel::rename(const QModelIndex & index, const QString & newName)
{
    bool result;
    TreeItem * item = getItem(index); //обертка с проверками вокруг index.internalPointer()
    beginRemoveRows();
    archive->detachTree(item); //отцепляем то, где было
    endRemoveRows();
    beginInsertRows();
    result = archive->attachTree(item, newName); //перенос в новое место
    endInsertRows();
    return result;
}
тут проблема в том, что переименование отдельного элемента может вернуть ошибку - неясно как ее обрабатывать (ибо в текущем варианте переброс идет по 1му до первого внутреннего эррора). То есть теоретически возможен вариант с "полуперенесенной" веткой.
А по поводу прокси - можно поподробнее? Нужно сделать свою проксю, и что в ней?..


Название: Re: itemModel
Отправлено: ритт от Август 24, 2009, 09:12
beginInsertRows() без параметров?

а по поводу прокси - !rtfm: QSortFilterProxyModel


Название: Re: itemModel
Отправлено: Авварон от Август 24, 2009, 09:23
ну параметры само собой необходимые (парента\ряд старые я знаю, а новые нужно вычислить парента, а ряд - последний (вставка в конец идет)). А что, обычная модель сортировки поможет от сворачивания?.. Думал про это, даже подключил модель, но надо было поменять индексы (mapToSource) - стало сразу лениво:) Если поможет, то здорово, тк сортировки у меня тоже пока нет и желания ее писать нету (пока хочу сделать функционал, а об скорости потом подумаю - архив не очень большой)
Спасибо за ответы.


Название: Re: itemModel
Отправлено: ритт от Август 26, 2009, 18:51
поздравляю, в 4.6 у QAbstractItemModel появятся методы
bool beginMoveRows(const QModelIndex &sourceParent, int sourceFirst, int sourceLast, const QModelIndex &destinationParent, int destinationRow) / void endMoveRows()
и
bool beginMoveColumns(const QModelIndex &sourceParent, int sourceFirst, int sourceLast, const QModelIndex &destinationParent, int destinationColumn) / void endMoveColumns()

просто объявляешь 4.6 в минимальных требованиях - и обходишься без костылей...


Название: Re: itemModel
Отправлено: Авварон от Август 26, 2009, 19:46
ну я уже сделал с костылями:) через 2 действия+проки модель над всем этим для красоты. но здорово, что появятся)) буду ждать 4.6))


Название: Re: itemModel
Отправлено: Авварон от Сентябрь 02, 2009, 12:16
сорри, что апаю тему:)
есть код
Код:
bool QMPQModel::close()
{
    qDebug() << "QMPQModel::close";
    bool result = archive->closeArchive();
//    QApplication::processEvents();
    reset();
    return result;
}
Без QApplication::processEvents() модель не резетится под макосью. Ставлю брейкпоинт - список с данными в момент резета пуст. После возобновления программы с брейкпоинта вьюха чиста.
Под виндой QApplication::processEvents() вызывает краш (ибо дерево уже разрушено). Баг под маком или я туплю?
Код:
bool QMPQArchive::closeArchive()
{
    if (!mpq) {
        return true;
    }
    qDebug() << "QMPQArchive::closeArchive";
    updateListFile();

    hash.clear();  //!!
    qDeleteAll(m_rootItem->childItems);  //!!
    m_rootItem->childItems.clear();  //!!

    bool result = SFileCloseArchive(mpq);
    if (!result) {
        m_lastError = GetLastError();
        qDebug() << "can't close archive: "<< m_lastError.errorMessage();
        return false;
    }
    mpq = 0;
    qDebug() << "closed";
    return result;
}
Да, поверх моей модели висит прокси-модель