Russian Qt Forum
Ноябрь 01, 2024, 08:24 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: [РЕШЕНО] Обновление данных модели во вьюхе  (Прочитано 7790 раз)
boruh
Гость
« : Март 19, 2010, 10:54 »

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

Подскажите пожалуйста, что делать? Может быть я все таки что-то упустил из виду? Работаю с MVC не первый день, но раньше никогда не сталкивался с такой проблемой.
« Последнее редактирование: Март 24, 2010, 12:23 от boruh » Записан
alexman
Гость
« Ответ #1 : Март 19, 2010, 10:59 »

QSortFilterProxyModel?
Записан
boruh
Гость
« Ответ #2 : Март 19, 2010, 11:25 »

Нет, QSortFilterProxyModel не подходит потому, что как я уже написал помимо сортировки происходит и изменение данных. Т.е. могут добавиться/удалиться строки например.
Записан
MoPDoBoPoT
Гость
« Ответ #3 : Март 19, 2010, 11:55 »

помимо сортировки происходит и изменение данных. Т.е. могут добавиться/удалиться строки например.
При больших изменениях в модели, чтобы не дергать за dataChanged(), вызывают QAbstractItemModel::reset().
Записан
boruh
Гость
« Ответ #4 : Март 19, 2010, 12:18 »

да, знаю. Его тоже попробовал - не помогло.
Записан
voronElf
Гость
« Ответ #5 : Март 19, 2010, 12:43 »

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

Покажи код, можт чтото прояснится ....
« Последнее редактирование: Март 19, 2010, 12:54 от voronElf » Записан
boruh
Гость
« Ответ #6 : Март 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();



Вот еще скриншот окна, на котором лежит вьюха, чтобы было еще лучше понятно что это за хозяйство.

Записан
voronElf
Гость
« Ответ #7 : Март 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();
}

У меня тож случаются такие запарки, обычно все косячит из-за какой-нить мелочи в стиле: модель связал не с той вьюхой, сигнал отправить или сконектить забыл, в локальную переменную вписал, а не в поле объекта ... Находятся эти косячки в самых неожиданных местах. Проверь на эту тему.
Записан
voronElf
Гость
« Ответ #8 : Март 19, 2010, 14:24 »

в m_rows перед reset() нужные данные лежат ?
можно попробовать убрать все сигналы насчет вставки и удаления строк (если не пробовал еще) , оставить только layoutChanged или reset.
Записан
boruh
Гость
« Ответ #9 : Март 24, 2010, 12:23 »

Все, решил проблему. Как и предполагалось ошибка была тупейшая и в другом месте Улыбающийся
Спасибо всем!
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.127 секунд. Запросов: 20.