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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Не срабатывает слот по таймеру  (Прочитано 8078 раз)
bestonix
Гость
« : Март 03, 2011, 10:14 »

Доброго здоровья коллеги.

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

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

С уважением Дмитрий.
Записан
BRE
Гость
« Ответ #1 : Март 03, 2011, 10:23 »

А ты почитай, что у тебя в консоль пишется при нажатии кнопки "Старт".

Поищи по форуму, тем таких было куча, даже одна была конкретно по запуску таймера.  Подмигивающий
Записан
bestonix
Гость
« Ответ #2 : Март 03, 2011, 10:33 »

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

Читаю и делаю по книге - Макс Шлее "Qt 4. Профессиональное программирование на С++"
Записан
BRE
Гость
« Ответ #4 : Март 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.

Поищи по форуму, все это уже не раз подробно обсуждалось.
Записан
bestonix
Гость
« Ответ #5 : Март 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().
Пустое место выводится и все.
Записан
bestonix
Гость
« Ответ #6 : Март 03, 2011, 11:08 »

С именем разобрался. присвоил руками и все.
Думал что при создании какое-никакое имя все же будет присвоено, а они вон как.
Записан
BRE
Гость
« Ответ #7 : Март 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();
}
 
Записан
bestonix
Гость
« Ответ #8 : Март 03, 2011, 14:26 »

Прочитал в доке про moveToThread и в форумах.   Обеспокоенный
Что-то не совсем понял смысл этой функции.
Вроде понял только то, что это нужно для того чтоб нить была полноценным процессом и не грузила основной поток.
Хотя может я и тут не прав  В замешательстве
« Последнее редактирование: Март 03, 2011, 14:40 от bestonix » Записан
bestonix
Гость
« Ответ #9 : Март 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 );
}

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

Если я не прав буду благодарен если поправите.
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #10 : Март 07, 2011, 01:15 »

переменные никуда не переносятся...
Записан
bestonix
Гость
« Ответ #11 : Март 09, 2011, 09:21 »

переменные никуда не переносятся...
Наверно не правильно выразился. Хотя и прописал слово в кавычках.
Я имел ввиду, что они сменили родителя и теперь видны только одному потоку
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #12 : Март 10, 2011, 11:52 »

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


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