crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Обновление отображения базы в QTableView
eXeLe
  опции профиля:
сообщение 24.8.2012, 12:26
Сообщение #1


Новичок


Группа: Новичок
Сообщений: 1
Регистрация: 24.8.2012
Пользователь №: 3493

Спасибо сказали: 0 раз(а)




Репутация:   0  


собссно возник вопрос.
работаю с базой через запросы
QSqlQuery query;
...

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

смотрел в сторону QDataWidgetMapper, но как я понял, оно просто дает работать с тем или иным полем таблицы, а у меня идут запросы в стиле "для строки с таким то имненем, увеличить показатель value на x" или банально добавление новых строк.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
maint
  опции профиля:
сообщение 24.8.2012, 14:42
Сообщение #2


Участник
**

Группа: Участник
Сообщений: 235
Регистрация: 3.8.2009
Из: Иркутск
Пользователь №: 982

Спасибо сказали: 28 раз(а)




Репутация:   2  


model->select();
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
FantasyOr
  опции профиля:
сообщение 12.12.2012, 11:53
Сообщение #3


Студент
*

Группа: Участник
Сообщений: 75
Регистрация: 13.8.2010
Пользователь №: 1956

Спасибо сказали: 4 раз(а)




Репутация:   0  


Простите за некрофилию.

Вопрос, разве модель не должна отслеживать изменения в вверенной ей таблице и обновлять данные.

по model->select() происходит перерисовка всего представления со следующими пакостями:
1) прокрутка в начало.
2) потеря выделений сделанных пользователем
3) потерей уже загруженных записей - когда записей больше чем 250 и пользователь прокрутил скролом далеко вниз

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

Сообщение отредактировал FantasyOr - 12.12.2012, 11:53
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
RazrFalcon
  опции профиля:
сообщение 12.12.2012, 13:38
Сообщение #4


Zombie Mod
*****

Группа: Участник
Сообщений: 1654
Регистрация: 24.5.2010
Из: Харьков
Пользователь №: 1752

Спасибо сказали: 64 раз(а)




Репутация:   212  


Так вроде у всех так и есть. По большей части решается костылями.

А так, такое обновление будет слишком долгим, да и слабо реализуемым (для каждой базы - своя).

Так как:
1) Нужно получать сигналы от базы об обновлении
2) Нужно знать какие именно строки изменились и их забрать и правильно вставить (что уже довольно муторно, а иногда и не реально)
3) Нужно сохранять выделение не по строкам, а по id, так как оно будет сбиватся
4) и тд и тп
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
FantasyOr
  опции профиля:
сообщение 12.12.2012, 15:46
Сообщение #5


Студент
*

Группа: Участник
Сообщений: 75
Регистрация: 13.8.2010
Пользователь №: 1956

Спасибо сказали: 4 раз(а)




Репутация:   0  


Вот это пичалька (Т_Т)

Везде рассматриваются однопользовательские приложения, где юзер сделал изменение и оно у него красиво отобразилось

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

в таком случае нужно постоянно раз в 5-10 секунд делать model->select();
а если этих пользователей скажем 100, какой поток запросов обрушится на базу...

есть какие-нибудь рекомендации?

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 12.12.2012, 17:39
Сообщение #6


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(FantasyOr @ 12.12.2012, 13:53) *
разве модель не должна отслеживать изменения в вверенной ей таблице и обновлять данные.
нет, если, конечно, ты сам такую модель не напишешь


Цитата(FantasyOr @ 12.12.2012, 13:53) *
по model->select() происходит перерисовка всего представления со следующими пакостями:
известная проблема Qt, которую авторы не собираются исправлять


Цитата(FantasyOr @ 12.12.2012, 13:53) *
подскажите какие есть настройки у модели и представления, позволяющие избежать данных неприятностей.
настроек ни каких, нужно всё самому решать


Цитата(FantasyOr @ 12.12.2012, 17:46) *
есть какие-нибудь рекомендации?
писать свою модель, мониторить изменения, не посылать reset(), а обновлять только изменившиеся данные.
Хлопотно, но если один раз напишешь, то потом можешь этой моделью пользоваться во многих случаях
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
FantasyOr
  опции профиля:
сообщение 14.12.2012, 8:54
Сообщение #7


Студент
*

Группа: Участник
Сообщений: 75
Регистрация: 13.8.2010
Пользователь №: 1956

Спасибо сказали: 4 раз(а)




Репутация:   0  


У меня получился такой нехитрый код
Раскрывающийся текст

/// Внимание это нужно делать прежде чем вносить изменения в таблицу: устанавливать фильтр и сортировку, иначе не работает, currentIndex возвращает (-1, -1)

QModelIndex mi = view->currentIndex();    //  запоминаем индекс выделенной ячейки
int sbVal = view->verticalScrollBar()->value();    //  запоминаем значение скрола - это последняя видимая строка
int sub = sbVal - mi.row();            //  разница между послед видимой строкой и выделенной, для восстановления визуального состояния

// запоминаем ID записи, чтоб найти нужную строку
QString _ID = model->data(model->index(mi.row(), idx_ID)).toString();

// устанавливаем фильтр и сортировку
model->setFilter(_sqlWhere);
if (!orderColumn.isEmpty())
{    model->sort(model->fieldIndex(orderColumn), Qt::AscendingOrder);    }

// делаем выборку всех записей - у меня около 300 записей обновляется каждые 10 секунд вроде бы без тормозов
model->select();
while (model->canFetchMore())
{    model->fetchMore();    }

// надеемся, что не было изменений приведших у изменению позиции у выделенной записи - не было добавлений и удаления перед записью или их было одинаковое ко-во
if ((model->data(model->index(mi.row(), idx_ID)).toString() != _ID))
{
    // не повезло
    int idx = 0;
    bool notFount = true;

    // идём сверху вниз пока не найдём нужную запись или не просмотрим все записи        
    while (notFount && idx < model->rowCount())    
    {    
        if (model->data(model->index(idx, idx_ID)).toString() == _ID) &&
        {    notFount = false;    }
        else
        {    ++idx;    }
    }

    // если не нашли, то оставляем скролл на том же месте
    if (notFount)
    {    mi = model->index(sbVal-sub, mi.column());    }
    else
    {    mi = model->index(idx, mi.column());    }      
}

// выделяем ячейку, скролируем таблицу
view->setCurrentIndex(mi);
view->verticalScrollBar()->setValue(mi.row()+sub);



прошу оценить подход, может что посоветуете.
Спасибо.

Сообщение отредактировал FantasyOr - 20.12.2012, 15:17
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
RazrFalcon
  опции профиля:
сообщение 29.1.2013, 19:26
Сообщение #8


Zombie Mod
*****

Группа: Участник
Сообщений: 1654
Регистрация: 24.5.2010
Из: Харьков
Пользователь №: 1752

Спасибо сказали: 64 раз(а)




Репутация:   212  


Цитата(Litkevich Yuriy @ 12.12.2012, 17:39) *
писать свою модель, мониторить изменения, не посылать reset(), а обновлять только изменившиеся данные.
Хлопотно, но если один раз напишешь, то потом можешь этой моделью пользоваться во многих случаях

Вопрос вдогонку: как именно мониторить изменения базы? К примеру в firebird я отсылаю событие и потом в клиенте его ловлю. Но как это сделать для любой базы, средствами Qt? Если ли у Qt свой механизм отслеживания изменений баз?

Как я понимаю QSqlTableModel обновляет сразу всю таблицу, а не частично. И как он вообще понимает что базу пора обновить? Так вот как написать это частичное изменение? По сути пока что у меня проблема как раз в том, как узнать у базы, какие именно строки изменились...
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 20.4.2024, 5:50