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

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

Страниц: [1] 2 3 4   Вниз
  Печать  
Автор Тема: одновременное обновление активных элементов на центральном виджете приводит к ош  (Прочитано 26021 раз)
iceBear
Гость
« : Июль 17, 2012, 14:32 »

Здравствуйте,

На центральном виджете, который представляет собой экземпляр класса ImageViewer расположены 10 штук QgraphicsSimpleTextItem, которые получают данные из сторонних процессов. Каждый QgraphicsSimpleTextItem прикреплен к своему процессу. Процессы работают с большими скоростями - обновляя данные раз в 10 мс. Для каждого QgraphicsSimpleTextItem вызывается метод setText(), и обновленное состояние текстовок отображается на мониторе.

Приблизительно (каждый раз по разному) на 2000 итерации вся программа благополучно сваливается в ошибку. Возникает ощущение, при выполнении операции setText () для одного экземпляра QgraphicsSimpleTextItem происходит обновление всего центрального виджета,  и, соответственно, когда два потока пытаются одновременно обновить состояние своих QgraphicsSimpleTextItem,   ошибка и возникает.

Правильно ли я себе все представляю? Если да, то можно ли сделать так, чтобы обновление виджета делать принудительно (например вызывая вручную метод update ()), а не автоматически - при вызове QgraphicsSimpleTextItem::setText ()?


спасибо,
Записан
_OLEGator_
Гость
« Ответ #1 : Июль 17, 2012, 14:43 »

Вообще странно работать с GUI из потоков напрямую, должно сразу валиться приложение, с GUI надо работать из одного основного потока.
Записан
iceBear
Гость
« Ответ #2 : Июль 17, 2012, 14:47 »

оно и валится почти сразу,

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

ограничить все одним потоком - рассматривается, но как самый запасной вариант
Записан
_OLEGator_
Гость
« Ответ #3 : Июль 17, 2012, 14:51 »

Данные мониторить можно в разных потоках, нельзя напрямую с GUI работать из не основного потока.
При обновлении данных необходимо информировать основной поток об изменениях, через механизм сигналов и слотов или механизм событий, помоему эта тема обсуждалась на форуме - поищите.
Записан
V1KT0P
Гость
« Ответ #4 : Июль 17, 2012, 15:00 »

Вообще странно работать с GUI из потоков напрямую, должно сразу валиться приложение, с GUI надо работать из одного основного потока.
+1 Никто в здравом уме не будет работать с GUI с левых потоков. К тому же я не думаю что так уж необходимо обновлять визуальное отображение данных 100 раз в секунду. Складывай данные для обновления в буфер и обновляй раз или два в секунду через сигнал.
Записан
Bepec
Гость
« Ответ #5 : Июль 17, 2012, 15:12 »

Чуть поправлю виктора - не так уж необходимо обновлять view раз в 5 мс, достаточно 25 мс Улыбающийся
Записан
V1KT0P
Гость
« Ответ #6 : Июль 17, 2012, 15:16 »

Чуть поправлю виктора - не так уж необходимо обновлять view раз в 5 мс, достаточно 25 мс Улыбающийся
40 раз в секунду? Даже видео 25 кадров в секунду смотрится нормально =).
Записан
iceBear
Гость
« Ответ #7 : Июль 17, 2012, 15:28 »

спасибо большое за ответы,

про скорость - были случаи, когда на промышленных рентгенустановках приходилось регистрировать телеграммы с частотой 5 мс - такая скорость продиктована всего лишь точностью описания процесса,

если обновлять содержимое не 5 а 25 раз в секунду - софтина свалится в ошибку не на 2000,а на 15000 итерации - в данном случае все равно патология остается, как мне кажется, даже не уменьшается вероятность возникновения ошибки

напрямую из потоков, методы компонентов GUI я конечно не вызываю,

Записан
V1KT0P
Гость
« Ответ #8 : Июль 17, 2012, 15:35 »

спасибо большое за ответы,

про скорость - были случаи, когда на промышленных рентгенустановках приходилось регистрировать телеграммы с частотой 5 мс - такая скорость продиктована всего лишь точностью описания процесса,

если обновлять содержимое не 5 а 25 раз в секунду - софтина свалится в ошибку не на 2000,а на 15000 итерации - в данном случае все равно патология остается, как мне кажется, даже не уменьшается вероятность возникновения ошибки

напрямую из потоков, методы компонентов GUI я конечно не вызываю,
Может у тебя память течет и после 2000 не остается свободной? А что бэктрейс пишет?
Записан
_OLEGator_
Гость
« Ответ #9 : Июль 17, 2012, 15:40 »

напрямую из потоков, методы компонентов GUI я конечно не вызываю,
А как же QGraphicsSimpleTextItem::setText() ?!
« Последнее редактирование: Июль 17, 2012, 15:42 от _OLEGator_ » Записан
Bepec
Гость
« Ответ #10 : Июль 17, 2012, 15:42 »

Я за 25 раз в секунду. Меньше смысла нет(человек разницы не заметит), больше - тоже.(кому оно надо, тормоза то)

Вам уже ясно сказали - нельзя работать с gui из разных потоков. Надо использовать сигнал-слотовое соединение.

iceBear - вы видно не можете сообразить.

 Регистрировать телеграммы, обрабатывать сигналы и прочая - вы можете хоть 100 раз в мс. А вот обновлять view достаточно раз в 25 мс.

Человеческий глаз не заметит мельканий раз в 5мс и прочего. Излишняя только работа.


Записан
iceBear
Гость
« Ответ #11 : Июль 17, 2012, 15:59 »

сигнал - слотовое соединение конечно же использую, это очевидно,

QGraphicsSimpleTextItem::setText () вызываю через него - т.е. поток генерирует сигнал, который обрабатывается уже в потоке главного приложения, часть обработки занимает setText (),

"...А вот обновлять view достаточно раз в 25 мс. Человеческий глаз не заметит мельканий раз в 5мс и прочего. Излишняя только работа." - раз в 25 мс тоже много, если ориентироваться на визуальное представление достаточно - 24 раз в секунду
Записан
iceBear
Гость
« Ответ #12 : Июль 17, 2012, 16:05 »

вот еще вопрос в эту же тему - есть ли в QT событие OnIdle () или его аналог?

спасибо
Записан
V1KT0P
Гость
« Ответ #13 : Июль 17, 2012, 16:10 »

Так что пишет бэктрейс при падении? Ибо наугад гадать где ошибка не годится.
Записан
iceBear
Гость
« Ответ #14 : Июль 17, 2012, 16:14 »

это моя ошибка - не трассировал,

вываливает виндовое окно, что приложение выполнило недопустимую операцию и будет закрыто.

Из обработчиков убирал, все, что касается QGraphicsSimpleTextItem и при этом условии все работало надежно (проверял три часа - утечек памяти нет, скорости не уменьшаются)

 
Записан
Страниц: [1] 2 3 4   Вверх
  Печать  
 
Перейти в:  


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