Russian Qt Forum

Qt => Многопоточное программирование, процессы => Тема начата: bestonix от Март 03, 2011, 10:14



Название: Не срабатывает слот по таймеру
Отправлено: bestonix от Март 03, 2011, 10:14
Доброго здоровья коллеги.

Пишу небольшую программу в качестве изучения QT4. Использую Qt Creator 1.2.1 Based on Qt 4.5.3
Смысл программы состоит в том, чтобы создавать потоки в количестве заданном пользователем.
В поток создается таймер по которому должна отрабатываться функция.
Функция по идее должна писать во внешний файл информацию от потока.
Но по неизвестной мне причине слот не срабатывает по таймеру.
Во вложении весь проект целиком.

Если не трудно укажите, что не так сделано. Заранее благодарен за помощь.

С уважением Дмитрий.


Название: Re: Не срабатывает слот по таймеру
Отправлено: BRE от Март 03, 2011, 10:23
А ты почитай, что у тебя в консоль пишется при нажатии кнопки "Старт".

Поищи по форуму, тем таких было куча, даже одна была конкретно по запуску таймера.  ;)


Название: Re: Не срабатывает слот по таймеру
Отправлено: bestonix от Март 03, 2011, 10:33
Ничего не пишет.
В дебагере вижу, что создание потока проходит нормально. Компоненты благополучно создаются.
А после ничего не происходит, как будто не стартанули таймеры.


Название: Re: Не срабатывает слот по таймеру
Отправлено: bestonix от Март 03, 2011, 10:35
Читаю и делаю по книге - Макс Шлее "Qt 4. Профессиональное программирование на С++"


Название: Re: Не срабатывает слот по таймеру
Отправлено: BRE от Март 03, 2011, 10:39
Ничего не пишет.
Я тебе процитирую:
Цитировать
QObject: Cannot create children for a parent that is in a different thread.
(Parent is uThread(0x1159890), parent's thread is QThread(0xfd2750), current thread is uThread(0x1159890)
Object::connect: Parentheses expected, signal QTimer::timeout
и так для каждого таймера.

1. Не нужно задавать parent для таймера. Все объекты создаваемые в методе run относятся к контексту этого потока, в то время как сам объект uThread находится в контексте главного потока. Отсюда...
2. Нужно переносить объекты класса uThread в контекст этого потока используя moveToThread.

Поищи по форуму, все это уже не раз подробно обсуждалось.


Название: Re: Не срабатывает слот по таймеру
Отправлено: bestonix от Март 03, 2011, 10:53
Ничего не пишет.
Я тебе процитирую:
Цитировать
QObject: Cannot create children for a parent that is in a different thread.
(Parent is uThread(0x1159890), parent's thread is QThread(0xfd2750), current thread is uThread(0x1159890)
Object::connect: Parentheses expected, signal QTimer::timeout
и так для каждого таймера.

1. Не нужно задавать parent для таймера. Все объекты создаваемые в методе run относятся к контексту этого потока, в то время как сам объект uThread находится в контексте главного потока. Отсюда...
2. Нужно переносить объекты класса uThread в контекст этого потока используя moveToThread.

Поищи по форуму, все это уже не раз подробно обсуждалось.


Поищу сейчас обязательно.

Странно, но факт. Переписал строку connect(timer, SIGNAL(timeout()), this, SLOT(slotWriteToFile())); Т.е. вместо timeout написал timeout(), просто поставил скобки и события стали срабатывать.
Правда в файл не пишется вот это - uThread::objectName().
Пустое место выводится и все.


Название: Re: Не срабатывает слот по таймеру
Отправлено: bestonix от Март 03, 2011, 11:08
С именем разобрался. присвоил руками и все.
Думал что при создании какое-никакое имя все же будет присвоено, а они вон как.


Название: Re: Не срабатывает слот по таймеру
Отправлено: BRE от Март 03, 2011, 12:40
Код
C++ (Qt)
uThread::uThread(int vTime, QString vFile)
       : cntTime( vTime ), sFile( vFile )
{
       moveToThread( this );
}
 
void uThread::run()
{
 QTimer timer;
 connect( &timer, SIGNAL( timeout() ), SLOT( slotWriteFile() ) );
 timer.start( cntTime * 1000 );
 
 exec();
}
 


Название: Re: Не срабатывает слот по таймеру
Отправлено: bestonix от Март 03, 2011, 14:26
Прочитал в доке про moveToThread и в форумах.   :-[
Что-то не совсем понял смысл этой функции.
Вроде понял только то, что это нужно для того чтоб нить была полноценным процессом и не грузила основной поток.
Хотя может я и тут не прав  :-\


Название: Re: Не срабатывает слот по таймеру
Отправлено: bestonix от Март 03, 2011, 16:37
Перечитал еще раз и вот что я понял из всего этого.
Применительно к моему коду.
uThread::uThread(int vTime, QString vFile)
{
    cntTime = vTime;
    sFile   = vFile;
    //moveToThread( this );
}

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

А если писать так как предложено

uThread::uThread(int vTime, QString vFile): cntTime( vTime ), sFile( vFile )
{
     moveToThread( this );
}

Получается, что проинициализированные переменные "перенесены" в порожденный поток и теперь есть чем
установить время таймаута.

Если я не прав буду благодарен если поправите.


Название: Re: Не срабатывает слот по таймеру
Отправлено: Авварон от Март 07, 2011, 01:15
переменные никуда не переносятся...


Название: Re: Не срабатывает слот по таймеру
Отправлено: bestonix от Март 09, 2011, 09:21
переменные никуда не переносятся...
Наверно не правильно выразился. Хотя и прописал слово в кавычках.
Я имел ввиду, что они сменили родителя и теперь видны только одному потоку


Название: Re: Не срабатывает слот по таймеру
Отправлено: Авварон от Март 10, 2011, 11:52
и это неверно. мув ту тред нужен чтобы правильно отрабатывали сигналы/слоты - исходя из указателя на тред данные сигнала кладутся в верный эвент луп.
данные треды ваще ни причем, они видны отовсюду и их надо мьютексить ручками если нужен доступ из разных потоков.