Russian Qt Forum

Qt => Model-View (MV) => Тема начата: boruh от Март 19, 2010, 10:54



Название: [РЕШЕНО] Обновление данных модели во вьюхе
Отправлено: boruh от Март 19, 2010, 10:54
Добрый день.
Столкнулся с непонятной проблемой: есть табличная модель и QTableView. В модели произвожу изменения структурного характера, которые в сущности сводятся к обычной сортировке данных с небольшими изменениями самих данных. И вот проблема - не обновляется вьюха. Т.е. она обновляет содержимое - меняются, например, цвета фона строк в соответствии с тем, как поменялись данные, но порядок строк остается неизменным. Посыл сигналов dataChanged и layoutChanged стоит, вызов методов beginRemoveRows/endRemoveRows и beginInsertRows/endInsertRows стоит - все вроде сделано по правильному. Однако ничего не помогает.

Подскажите пожалуйста, что делать? Может быть я все таки что-то упустил из виду? Работаю с MVC не первый день, но раньше никогда не сталкивался с такой проблемой.


Название: Re: Обновление данных модели во вьюхе
Отправлено: alexman от Март 19, 2010, 10:59
QSortFilterProxyModel?


Название: Re: Обновление данных модели во вьюхе
Отправлено: boruh от Март 19, 2010, 11:25
Нет, QSortFilterProxyModel не подходит потому, что как я уже написал помимо сортировки происходит и изменение данных. Т.е. могут добавиться/удалиться строки например.


Название: Re: Обновление данных модели во вьюхе
Отправлено: MoPDoBoPoT от Март 19, 2010, 11:55
помимо сортировки происходит и изменение данных. Т.е. могут добавиться/удалиться строки например.
При больших изменениях в модели, чтобы не дергать за dataChanged(), вызывают QAbstractItemModel::reset().


Название: Re: Обновление данных модели во вьюхе
Отправлено: boruh от Март 19, 2010, 12:18
да, знаю. Его тоже попробовал - не помогло.


Название: Re: Обновление данных модели во вьюхе
Отправлено: voronElf от Март 19, 2010, 12:43
Очень странно. насколько я понимаю в MVC помимо добавления-удаления строк есть 3 способа для модели оповещать об изменениях данных: dataChanged() при изменении диапазона ячеек, layoutChanged при сильных изменениях (в том числе по структуре) , reset() - полная перезагрузка вида.
Делал несколько раз, все работает, подхватывается.

Покажи код, можт чтото прояснится ....


Название: Re: Обновление данных модели во вьюхе
Отправлено: boruh от Март 19, 2010, 13:23
Вот я тоже в точности так думал и думаю, но код увы не работает.

Вот код метода, который производит изменение данных:

Код:
// формируем список групп и товаров
QVector<TableDataRow*> groups;
QVector<TableDataRow*> elements;
for (int i = 0; i < m_rows.count(); i++)
if (m_rows[i]->primaryId() == 0)
groups.append(m_rows[i]);
else
elements.append(m_rows[i]);


// чистим строки
beginRemoveRows(QModelIndex(), 0, m_rows.count());
m_rows.clear();
endRemoveRows();


// формируем список строк таблицы с новой группировкой
beginInsertRows(QModelIndex(), 0, groups.count() + elements.count());
for (int i = 0; i < groups.count(); i++)
{
m_rows.append(groups[i]);
for (int j = 0; j < elements.count(); j++)
{
if (elements[j]->secondaryId() == groups[i]->secondaryId())
{
m_rows.append(elements[j]);
elements.remove(j);
j--;
}
}
}
endInsertRows();

// посылаем все возможные сигналы об обновлении данных
//emit dataChanged(index(0, 0), index(columnCount(), rowCount()));
reset();
emit layoutChanged();



Вот еще скриншот окна, на котором лежит вьюха, чтобы было еще лучше понятно что это за хозяйство.
(http://img151.imageshack.us/img151/2830/screenshotbs.jpg)


Название: Re: Обновление данных модели во вьюхе
Отправлено: voronElf от Март 19, 2010, 14:10
для layoutChanged нужен еще layoutAboutToBeChanged() вначале, но эт не должно повлиять по идее.

Версия Qt - ?
я так понял обсуждаемая вьюха слева ?

вот пример моего рабочего кода:
Код:
void CTovTbModel::reloadData() {
    //emit isLoadEndProgress(false);
    emit layoutAboutToBeChanged();
    //QApplication::processEvents();

    QList<CTovar*> tovs = m_sourceData->getAllTovs();
    m_tovs.clear();
    for(int i=0; i<tovs.size(); i++) {
        if(m_curGroups.at(0) > 0 && !m_curGroups.contains( tovs.at(i)->groupId )) continue;
        if(m_curBrand > 0 && m_curBrand != tovs.at(i)->brandId) continue;
        if((m_curFilters & filtStock) && tovs.at(i)->in_stock <= 0) continue;
        if((m_curFilters & filtAddDisc) && tovs.at(i)->discAdd <= 0) continue;
        if((m_curFilters & filtMaxDisc) && tovs.at(i)->discMax <= 0) continue;
        if((m_curFilters & filtTovNew) && !tovs.at(i)->isNew) continue;
        m_tovs << tovs.at(i);
    }//for
    if(!m_isLoaded) m_isLoaded = true;
    emit layoutChanged();
}

У меня тож случаются такие запарки, обычно все косячит из-за какой-нить мелочи в стиле: модель связал не с той вьюхой, сигнал отправить или сконектить забыл, в локальную переменную вписал, а не в поле объекта ... Находятся эти косячки в самых неожиданных местах. Проверь на эту тему.


Название: Re: Обновление данных модели во вьюхе
Отправлено: voronElf от Март 19, 2010, 14:24
в m_rows перед reset() нужные данные лежат ?
можно попробовать убрать все сигналы насчет вставки и удаления строк (если не пробовал еще) , оставить только layoutChanged или reset.


Название: Re: Обновление данных модели во вьюхе
Отправлено: boruh от Март 24, 2010, 12:23
Все, решил проблему. Как и предполагалось ошибка была тупейшая и в другом месте :)
Спасибо всем!