Название: Многопоточный вывод на QGraphicsScene Отправлено: BiTOk от Май 03, 2010, 08:32 Доброе время суток. Пишу эмулятор прохождения по тоннелю людей. Каждый человек должен быть реализован в виде потока. Создаю несколько потоков, в них пытаюсь отрисовать человечков на QGraphicsScene, но они не рисуются и в консоль получаю вывод:
QObject::startTimer: timers cannot be started from another thread QObject::killTimer: timers cannot be stopped from another thread Как лучше реализовать такое, чтобы не было столь большого разделяемого ресурса и было хоть сколько-то плавное движение? Кто выводит в консоль эти сообщения? Название: Re: Многопоточный вывод на QGraphicsScene Отправлено: alexman от Май 03, 2010, 13:01 Рисовка возможна только в главном потоке! Например, посылай сигналы из потоков в главный поток, что требуется отрисоваться!
Название: Re: Многопоточный вывод на QGraphicsScene Отправлено: BiTOk от Май 03, 2010, 13:04 Т.е. фактически Вы мне предлагаете реализовать очередь, куда будут кидаться запросы на различные действия, а в главном потоке эту очередь обрабатывать и отрисовывать? В каком виде реализовать это лучше: руками реализовать очередь и по таймеру её обрабатывать или какой другой механизм?
Название: Re: Многопоточный вывод на QGraphicsScene Отправлено: lit-uriy от Май 03, 2010, 13:15 обрабатывать по мере поступления сигналов из доппотоков
Название: Re: Многопоточный вывод на QGraphicsScene Отправлено: BiTOk от Май 03, 2010, 13:17 А как правильно реализовать саму очередь?
Название: Re: Многопоточный вывод на QGraphicsScene Отправлено: ilyagoo от Май 03, 2010, 13:21 соединяй сигнал-слот с флагом Qt::QueuedConnection
Название: Re: Многопоточный вывод на QGraphicsScene Отправлено: Igors от Май 03, 2010, 14:29 Т.е. фактически Вы мне предлагаете реализовать очередь, куда будут .. Эта очередь давно имеется - eventLoop главной нитки. Все что Вам надо это из дочерних ниток посылать сигналы в главную, а там их обрабатывать/отрисовыватьНазвание: Re: Многопоточный вывод на QGraphicsScene Отправлено: BiTOk от Май 05, 2010, 07:53 Сделал как Вы и сказали, сигналы отправляю главному треду. Реализовал так:
Код: Worker::Worker(int startPlace, QObject *parent):QThread()//позиция, откуда следует начинать путь Название: Re: Многопоточный вывод на QGraphicsScene Отправлено: BRE от Май 05, 2010, 08:02 Попробуй так:
Код
Название: Re: Многопоточный вывод на QGraphicsScene Отправлено: BiTOk от Май 05, 2010, 08:07 Попробуй так: 5840 bla3064 5840 onTimerDown Что означает, что таймер вновь срабатывает в контексте главного потока Название: Re: Многопоточный вывод на QGraphicsScene Отправлено: alexman от Май 05, 2010, 08:08 Можно попробовать sleep делать в run! То есть отказаться от таймера!
Название: Re: Многопоточный вывод на QGraphicsScene Отправлено: BRE от Май 05, 2010, 08:12 Вместо this->currentThreadId(), попробуй писать QThread::currentThreadId()
Название: Re: Многопоточный вывод на QGraphicsScene Отправлено: BiTOk от Май 05, 2010, 08:17 alexman
Пробовал, даёт достаточно скверный результат, ибо слип не совсем эквивалент таймеру, он даст остановку после выполнения (а выполнение может быть не быстрым), а не как таймер.. BRE Это не принципиально, ибо данные результаты верны. Название: Re: Многопоточный вывод на QGraphicsScene Отправлено: Авварон от Май 05, 2010, 08:24 среди меня бытует мнение, что соединясь со слотом у объекта, созданного в главной нитке (Worker) мы таки будем выполнять этот слот в главной нитке, что вам в общем-то и надо. Создайте еще 1 объект внутри run и к неиу уже вешайте коннекты.
могу ошибаться, тк с QThread работал очень давно Название: Re: Многопоточный вывод на QGraphicsScene Отправлено: BiTOk от Май 05, 2010, 08:25 среди меня бытует мнение, что соединясь со слотом у объекта, созданного в главной нитке (Worker) мы таки будем выполнять этот слот в главной нитке, что вам в общем-то и надо. могу ошибаться. тк с QThread работал очень давно Цитировать Qt::BlockingQueuedConnection - при генерации сигнал помещается в очередь обработки событий. Пока слот не получит сигнал текущий поток блокируется. Данный тип соединения следует применять только для получателя в другом потоке Вообще это не так судя по всему.Название: Re: Многопоточный вывод на QGraphicsScene Отправлено: Авварон от Май 05, 2010, 08:32 у вас получатель в мейне. а отправитель - нет.
Название: Re: Многопоточный вывод на QGraphicsScene Отправлено: BiTOk от Май 05, 2010, 08:39 Верно, но в этой же проге я писал, эмит сигнала в главный поток из run() и он отправлялся из run().
Название: Re: Многопоточный вывод на QGraphicsScene Отправлено: Авварон от Май 05, 2010, 08:50 не важно откуда посылать, главное - где принимают. На то очередь и нужна, чтобы тредобезопасно перебросить из 1й нитки в другую. Я вам просто предлагаю проверить случай когда получающий не в главной нитке:) Могу ошибаться, но мне кажется такое обоснование логичным. У самого сейчас Qt далеко...
Название: Re: Многопоточный вывод на QGraphicsScene Отправлено: BRE от Май 05, 2010, 08:59 Могу ошибаться, но мне кажется такое обоснование логичным. У самого сейчас Qt далеко... Все верно, сразу не обратил внимания.Нужно перетащить сам объект Worker в контекст потока: Код
и все заработает. Название: Re: Многопоточный вывод на QGraphicsScene Отправлено: BiTOk от Май 05, 2010, 09:07 Хм.. действительно работает, спасибо, парни.
Название: Re: Многопоточный вывод на QGraphicsScene Отправлено: alexman от Май 05, 2010, 09:16 спс, буду знать!
Название: Re: Многопоточный вывод на QGraphicsScene Отправлено: BiTOk от Май 05, 2010, 13:54 Возник вопрос: как убить правильно поток и удалить созданный объект, если учитывать, что поток, который должен быть остановлен, накидал много-много сообщений главному треду, в одном из параметров сообщения находится указатель, который становится неверным, если прибить поток.. Если в лоб прибить - то упадёт в главном треде, а если не завершать, то будет течь память, да и вообще это как-то некрасиво. Могу выложить код, если кто захочет посмотреть.
Название: Re: Многопоточный вывод на QGraphicsScene Отправлено: BRE от Май 05, 2010, 14:00 Возник вопрос: как убить правильно поток и удалить созданный объект, если учитывать, что поток, который должен быть остановлен, накидал много-много сообщений главному треду, в одном из параметров сообщения находится указатель, который становится неверным, если прибить поток.. Если в лоб прибить - то упадёт в главном треде, а если не завершать, то будет течь память, да и вообще это как-то некрасиво. Могу выложить код, если кто захочет посмотреть. В твоем случае, т.к. используется цикл обработки событий:Код
или Код
Название: Re: Многопоточный вывод на QGraphicsScene Отправлено: BiTOk от Май 05, 2010, 14:50 Но bool QThread::finished () const, разве это можно использовать в качестве сигнала?
Название: Re: Многопоточный вывод на QGraphicsScene Отправлено: BRE от Май 05, 2010, 14:56 Но bool QThread::finished () const, разве это можно использовать в качестве сигнала? Найди два отличия: :)bool QThread::isFinished () const void QThread::finished () [signal] |