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

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

Страниц: 1 [2]   Вниз
  Печать  
Автор Тема: Модель-представление, работа через сеть  (Прочитано 10592 раз)
BRE
Гость
« Ответ #15 : Июль 01, 2011, 16:05 »

По скорости будет тоже самое. Весь код, который был бы в модели переноситься в другой класс "типа модели", который делает все тоже самое.
Кешировать данные на стороне клиента конечно придется, где это будет происходить в классе модели или в специальном отдельном классе псевдомодели не важно.

Записан
ieroglif
Гость
« Ответ #16 : Июль 01, 2011, 17:58 »

Тогда у меня ещё вопрос: каким образом подобный подход отразится на быстродействии модели?
с моей точки зрения это отразится только в лучшую сторону.
если за работу с сетью отвечает сама модель, то тормоза в сети вызовут тормоза в модели и, опасаюсь (исходники не смотрел, так что 100% сказать не могу) что это может вызвать тормоза в гуе.
если же за сетевое взаимодействие отвечает отдельный класс, то можно его вынести в отдельный поток, и даже если сеть будет тормозить - на гуе это никак не скажется.
Записан
Kolobok
Гость
« Ответ #17 : Июль 01, 2011, 18:25 »

Вот код слота получения ответа от сервера
Код:
oid NetworkModelRO::slotReadyRead(){
    QDataStream in(socket);
    in.setVersion(QDataStream::Qt_4_7);

    for(;;){
        if(!nextBlockSize){
            if(socket->bytesAvailable() < sizeof(quint16))
                break;

            in >> nextBlockSize;
            }

        if(socket->bytesAvailable() < nextBlockSize)
            break;

        in >> stringNetworkMessage; // <---

        nextBlockSize = 0;
        }
}

Модель не знает, что число строк изменилось. Посмотри методы
void QAbstractItemModel::beginInsertRows ( const QModelIndex & parent, int first, int last ) [protected]
void QAbstractItemModel::endInsertRows () [protected]
Записан
BRE
Гость
« Ответ #18 : Июль 01, 2011, 20:26 »

с моей точки зрения это отразится только в лучшую сторону.
если за работу с сетью отвечает сама модель, то тормоза в сети вызовут тормоза в модели и, опасаюсь (исходники не смотрел, так что 100% сказать не могу) что это может вызвать тормоза в гуе.
если же за сетевое взаимодействие отвечает отдельный класс, то можно его вынести в отдельный поток, и даже если сеть будет тормозить - на гуе это никак не скажется.
Если view нужно получить данные, которых нет в кеше модели и их нужно забирать с сервера, то совершенно не важно кто и в каком потоке их будет выкачивать. Модель на этот момент все равно должна быть заморожена, вместе с обслуживающим view ну и со всем gui.
Как вариант, можно вместо требуемых, но отсутствующих данных, возвращать строку "loading..." и грузить строку с сервера, но это все частности реализации.
« Последнее редактирование: Июль 01, 2011, 22:29 от BRE » Записан
ieroglif
Гость
« Ответ #19 : Июль 02, 2011, 04:07 »

Как вариант, можно вместо требуемых, но отсутствующих данных, возвращать строку "loading..." и грузить строку с сервера, но это все частности реализации.
ну лично я бы так и сделал - только возвращал бы пустой QVariant(), а "загрузка" писал бы в статус-баре
Записан
AlphaGh0St
Гость
« Ответ #20 : Июль 02, 2011, 19:29 »

Фуууууух, как я уже задолбался... Вожусь-вожусь с этим делом, а почти ничего не выходит...

Нет, нет, уведомлений о загрузке и всего прочего не надо. Я пишу не на показ, а для себя, из практических соображений. Чем проще, тем лучше...для начала...
Но Ваша идея мне понравилась, возьму на заметку.

Ну так в итоге, стоит ли использовать промежуточный "сетевой" класс?
И, если "да", то сетевой класс должен работать на прямую, запрашивая данные у сервера и тут же передавать модели, или запрашивать данные, сохранять их у себя, а модели предоставлять уже сохранённые данные?
Записан
ieroglif
Гость
« Ответ #21 : Июль 03, 2011, 10:06 »

Фуууууух, как я уже задолбался... Вожусь-вожусь с этим делом, а почти ничего не выходит...

Нет, нет, уведомлений о загрузке и всего прочего не надо. Я пишу не на показ, а для себя, из практических соображений. Чем проще, тем лучше...для начала...
Но Ваша идея мне понравилась, возьму на заметку.

Ну так в итоге, стоит ли использовать промежуточный "сетевой" класс?
И, если "да", то сетевой класс должен работать на прямую, запрашивая данные у сервера и тут же передавать модели, или запрашивать данные, сохранять их у себя, а модели предоставлять уже сохранённые данные?
ну какой-то класс по любому должен заниматься кешированием полученых с сервера данных? =) я бы оставил это на сетевой класс.
Записан
AlphaGh0St
Гость
« Ответ #22 : Июль 03, 2011, 13:05 »

С классом модели более-менее понятно. А вот с сетевым классом трудности.

Пусть сетевой касс содержит поле
Код:
private:
    vector<QString> vecS; // для хранения у себя строк с сервера

и методы
Код:
public: 
    int getRowCount() const;
    QVariant getData(const int index) const;

1) Значит, если модель вызывает метод rowCount(), нужно вызвать метод getRowCount() сетевого класса и вернуть размер вектора, верно?
В самом простом виде, получается так:
Код:
int NetworkModelRO::rowCount(const QModelIndex &parent) const { return networkClass->getRowCount(); }

2) Метод сетевого класса getData() возвращает модели (по вызову метода data()) строку из вектора по указанному индексу.
В самом простом виде, без проверок, получается так:
Код:
QVariant NetworkModelRO::data(const QModelIndex &index, int role) const { return networkClass->getData(index.row()); }

Но как быть с заполнением вектора? И как достичь синхронизации данных на сервере и в векторе?
    Если по каждому вызову метода data(), запрашивать указанную строку с сервера, помещать в вектор и возвращать модели, то в векторе будет полно дубликатов.
    Если по каждому вызову метода data(), полностью обновлять вектор... ну это тоже не дело.

3) Если модель вызывает метод rowCount() в тот момент, когда сетевой класс ещё не получил данные с сервера и вектор пуст, то метод вернёт 0. Чуть выше я написал отладочные данные от rowCount(). Как быть с этим?
Записан
ieroglif
Гость
« Ответ #23 : Июль 03, 2011, 19:57 »

мда.. действительно..
значит однозначно, кешированные данные с сервера хранит модель.
в таком случае сетевой класс на какие-то события производит запрос данных с сервера, и сигналит новыми данными модели, которая по этим сигналам уже меняет "кэш" и сообщает вьюхе об обновлении данных.
Записан
AlphaGh0St
Гость
« Ответ #24 : Июль 14, 2011, 11:30 »

Извиняюсь за долгое отсутствие.
Возвращаясь к теме обсуждения, хочу сказать, что вызов метода rowCount() в начале несколько раз возвращает 0, а за тем реальный размер. Эта проблема так и не была решена...
Отладочные данные показали, что с начала модель несколько раз вызывает метод rowCount() и метод возвращает 0, а лишь ПОТОМ приходят реальные данные с сервера.

Вот отладочные данные (в сокращённом виде):

Модель вызывает свой метод rowCount(), который вызывает метод getRowCount() сетевого класса.
Этот метод возвращает 0 и модель получает значение 0.
getRowCount() n =>  0
getRowCount() n =>  0

Затем видно, что ПОСЛЕ того, как модель получила значение 0, от сервера пришли реальные данные.
slotReadyRead() stringNetworkMessage =>  "3"
slotReadyRead() stringNetworkMessage =>  "3"

т.е. получается так, что метод rowCount() вызвался (пусть) 4 раза, 4 раза вернул значение 0, а уже после пришли 4 ответа от сервера...

После этого модель делает очередной вызов метода rowCount() и на этот раз получает реальные данные.
getRowCount() n =>  3
getRowCount() n =>  3
slotReadyRead() stringNetworkMessage =>  "3"
slotReadyRead() stringNetworkMessage =>  "3"

Подскажите, что здесь не правильно и как это исправить?
« Последнее редактирование: Июль 17, 2011, 22:09 от AlphaGh0St » Записан
AlphaGh0St
Гость
« Ответ #25 : Июль 17, 2011, 22:08 »

Стоооят все темы на одном месте, и народ оффлайн... вымер что-ли форум?... Непонимающий
Есть идеи по поводу метода rowCount() ?
Скока вот с ним вожусь, ну ни как не могу понять, в чём дело...
Записан
Странник
Гость
« Ответ #26 : Июль 18, 2011, 11:23 »

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


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