Название: [РЕШЕНО] QStandardItemModel QSortFilterProxyModel QThread Отправлено: vintik от Июль 30, 2013, 00:25 Привет!
Столкнулся со следующей проблемой. Есть вьюха и модель. Данные в модель поступают по сигналу, очень часто. Захотел засунуть модель и обработку входных сигналов в отдельный поток. Сделал это примерно так Код: Widget::Widget(QWidget *parent) Это работает. Захотелось применить прокси модель для фильтрации данных. И тут начались проблемы. Программа собирается, не ломается, но фильтрация работает криво. Если модель не мувить в поток, работает как ожидалось. Думаю, что в данной ситуации неправильно использую прокси модель. Но где именно ошибка понять не могу. Код: Widget::Widget(QWidget *parent) Название: Re: QStandardItemModel QSortFilterProxyModel QThread Отправлено: popper от Июль 31, 2013, 13:40 Предлагаю попробовать moveToThread поместить перед connect(...)
Название: Re: QStandardItemModel QSortFilterProxyModel QThread Отправлено: mutineer от Июль 31, 2013, 13:46 Предлагаю попробовать moveToThread поместить перед connect(...) Что это должно дать?Вообще не правильно просто разнести модель и прокси-модель в разные потоки - прокси-модель делает прямые вызовы в основную модель за данными, поэтому нужны будут блокировки. Лучше чтобы модель жила в основном потоке Название: Re: QStandardItemModel QSortFilterProxyModel QThread Отправлено: Old от Июль 31, 2013, 15:07 Что это должно дать? Qt определит, что объект модели должен жить в другой нитке и будет использовать QueuedConnection.Название: Re: QStandardItemModel QSortFilterProxyModel QThread Отправлено: mutineer от Июль 31, 2013, 15:10 Что это должно дать? Qt определит, что объект модели должен жить в другой нитке и будет использовать QueuedConnection.Это проверяется в момент эмита сигнала, а не в момент коннекта Название: Re: QStandardItemModel QSortFilterProxyModel QThread Отправлено: vintik от Июль 31, 2013, 15:49 Предлагаю попробовать moveToThread поместить перед connect(...) Что это должно дать?Вообще не правильно просто разнести модель и прокси-модель в разные потоки - прокси-модель делает прямые вызовы в основную модель за данными, поэтому нужны будут блокировки. Лучше чтобы модель жила в основном потоке Я пробовал сделать так. Создал класс, унаследованный от QSortFilterProxyModel - proxy_model. В этом классе мембером сделал QStandardItemModel и установил её в качестве sourceModel. Потом, установил прокси модель во вьюху. И сделал мув прокси модели в отдельный поток. На маленьком тестовом примере - всё заработало как надо. А когда я попытался перенести такой подход в большой проект - программа начала постоянно валиться. Природа поломки мне осталась не ясна, но происходило это как правило в момент вставки данных в модель. В данном проекте очень часто происходит добавление/удаление данных в модели. Коллеги подсказали, что вообще кутешная model/view НЕ потокобезопасна. и что, видимо, нужно очень внимательно синхронизировать данные. Дальше пока не продвинулся.. как-то так Название: Re: QStandardItemModel QSortFilterProxyModel QThread Отправлено: mutineer от Июль 31, 2013, 16:09 Не мувай модели в треды, пусть живут в главном. Переработай схему добавления данных в модель
Название: Re: QStandardItemModel QSortFilterProxyModel QThread Отправлено: vintik от Июль 31, 2013, 17:29 Не мувай модели в треды, пусть живут в главном. Переработай схему добавления данных в модель Расскажу из-за чего сыр-бор. Есть модель куда очень часто поступают данные. Модель сделана для отображения данных в виде дерева в QTreeView. Есть ещё прокси модель, чтобы была возможность фильтровать данные. Когда данных становится - много приложение тормозит. Я почему-то решил, что если кухню моделей засунуть в отдельный поток, то всё наладится. Отсюда и возник топик. Но теперь, как я понимаю, подобная затея порочна? (т.к. порой из вьюхи происходит обращение к модели непосредственно, без сигналов/слотов и данные могут рассинхронизироваться) следует модель, прокси модель и вьюху содержать в одном потоке. а работу приложения ускорять различными оптимизациями? Название: Re: QStandardItemModel QSortFilterProxyModel QThread Отправлено: mutineer от Июль 31, 2013, 17:31 Если данные поступают очень часто, то нет нужды их пихать в модель по факту прихода - все равно этого не видно будет на экране. Сделай некий буфер, в котором копи поступающие данные, а в модель их передавай раз в некоторое время, например раз в 500 мс
Название: Re: QStandardItemModel QSortFilterProxyModel QThread Отправлено: vintik от Июль 31, 2013, 17:32 Если данные поступают очень часто, то нет нужды их пихать в модель по факту прихода - все равно этого не видно будет на экране. Сделай некий буфер, в котором копи поступающие данные, а в модель их передавай раз в некоторое время, например раз в 500 мс да, это мысль! попробую реализовать) и всё-таки для ясности - о потоках забыть для этого случая? Название: Re: QStandardItemModel QSortFilterProxyModel QThread Отправлено: mutineer от Июль 31, 2013, 17:35 Копить данные можно в потоке, но модель и вью должны жить в одном потоке
Название: Re: QStandardItemModel QSortFilterProxyModel QThread Отправлено: vintik от Июль 31, 2013, 17:41 Копить данные можно в потоке, но модель и вью должны жить в одном потоке я понял, спасибо большое! Название: Re: [РЕШЕНО] QStandardItemModel QSortFilterProxyModel QThread Отправлено: Sasha от Декабрь 10, 2013, 12:53 У меня тоже примерно такая же проблемма. Пошёл под отладчиком и пришёл к выводу, что причина ряда проблемм в том, что, например, прокси-модель следит за изменениями основной модели для чего коннектит сигналы основной модели к своим слотам, НО не все эти сигналы могут быть QueuedConnection. Кажется, такими не могут быть, например, имеющие в параметрах QModelIndex. Вот и получается, что сигналы не доходят. Но там, по-моему, и более серьёзные проблеммы есть, приводящие к падениям, а не просто к неправильному отображению, когда один поток использует данные, которые другой поток уже удалил.
|