Russian Qt Forum

Qt => Многопоточное программирование, процессы => Тема начата: Edynchik от Ноябрь 10, 2011, 12:40



Название: QTimer и потоки
Отправлено: Edynchik от Ноябрь 10, 2011, 12:40
Я понимаю, что тема поднималась миллион раз, но все таки скажите в чем ошибка?
Код
C
#include <QtGui/QApplication>
#include "mainwindow.h"
#include "thread.h"
#include <QTimer>
 
//bool func();
bool b;
//QTimer t;
 
void MyThread::run()
{
   QTimer t;
   //t = new QTimer(this);
   connect(&t,SIGNAL(timeout()),this,SLOT(func()));
   //t.start(10);
   exec();
}
 
int main(int argc, char *argv[])
{
   QApplication a(argc, argv);
   MainWindow w;
   MyThread thread;
   thread.start();
           if(thread.func() == true)
           int i=0;
   w.show();
   return a.exec();
}
bool MyThread::func()
{
   bool b=true;
   return b;
}

Код
C
#ifndef THREAD_H
#define THREAD_H
#include <QThread>
 
class MyThread : public QThread
{
public:
    void run();
public slots:
    bool func();
};
 
#endif // THREAD_H
Почему по таймеру не вызывается функция func()?


Название: Re: QTimer и потоки
Отправлено: kambala от Ноябрь 10, 2011, 12:45
потому что таймер - локальная переменная?


Название: Re: QTimer и потоки
Отправлено: Edynchik от Ноябрь 10, 2011, 13:21
а тогда почему b не равно true, в таком случае:
Код
C
#include <QtGui/QApplication>
#include "mainwindow.h"
#include "thread.h"
#include <QTimer>
 
//bool func();
bool b;
QTimer t;
 
void MyThread::run()
{
   //QTimer t;
   //t = new QTimer(this);
   connect(&t,SIGNAL(timeout()),this,SLOT(func()));
   t.start(10);
   exec();
}
 
int main(int argc, char *argv[])
{
   QApplication a(argc, argv);
   MainWindow w;
   MyThread thread;
   thread.start();
   if(b == true)
       int i=0;
   w.show();
   return a.exec();
}
bool MyThread::func()
{
   bool b=true;
   return b;
}


Название: Re: QTimer и потоки
Отправлено: ddrtn от Ноябрь 10, 2011, 13:28
Попробуйте так.
Код:
connect(&t,SIGNAL(timeout()),this,SLOT(func()), Qt::QueuedConnection);


Название: Re: QTimer и потоки
Отправлено: LisandreL от Ноябрь 10, 2011, 13:31
а тогда почему b не равно true, в таком случае
Где вы проверяете?
К
Код:
if(b == true)
        int i=0;
func() просто может не успеть выполниться.
Ну и b для уверенности лучше инициализировать явно false'ом.


Название: Re: QTimer и потоки
Отправлено: twp от Ноябрь 10, 2011, 13:34
Попробуйте так.
Код:
connect(&t,SIGNAL(timeout()),this,SLOT(func()), Qt::QueuedConnection);
у ТС используется соединение по умолчанию что избавляет от необходимости явно задавать тип соединения. Конечно же func() вызывается до старта потока


Название: Re: QTimer и потоки
Отправлено: Edynchik от Ноябрь 10, 2011, 14:57
у ТС используется соединение по умолчанию что избавляет от необходимости явно задавать тип соединения. Конечно же func() вызывается до старта потока
То есть как,раньше потока??


Название: Re: QTimer и потоки
Отправлено: twp от Ноябрь 10, 2011, 15:54
вызов thread.start(); запускает поток, и потом выполняется его метод run() который выполняется параллельно с основным потоком. И естественно на это уйдет немного времени. Основной поток после вызова thread.start(); сразу же переходит к следующему коду т.е. if(thread.func() == true)
А что собственно нужно сделать?


Название: Re: QTimer и потоки
Отправлено: Edynchik от Ноябрь 10, 2011, 16:11
нужно чтобы с интервалом выполнялась функция func, параллельно с основным потоком.
Код
C
#include <QtGui/QApplication>
#include "mainwindow.h"
#include "thread.h"
#include <QTimer>
 
 
bool b = false;
QTimer t;
 
void MyThread::run()
{
 
   connect(&t,SIGNAL(timeout()),this,SLOT(func()));
   t.start(100);
   //func();
   exec();
}
 
int main(int argc, char *argv[])
{
   QApplication a(argc, argv);
   MainWindow w;
 
   MyThread thread;
   thread.start();
   for(int i =0;i<1000000;i++)
   {
   int x = i*i*i*i*i*i;
   if(b == true)
       i=0;
   }
   w.show();
   return a.exec();
}
bool MyThread::func()
{
   b = true;
   return b;
}

получается что b не становится true, т.е. в функцию func не заходит...


Название: Re: QTimer и потоки
Отправлено: twp от Ноябрь 10, 2011, 16:19
заходит, просто цикл выполняется быстрее чем за 100 мс  :) а какой сакральный сысл во всем этом? Задежать на 100 мс w.show() правильно?


Название: Re: QTimer и потоки
Отправлено: Edynchik от Ноябрь 10, 2011, 16:22
заходит, просто цикл выполняется быстрее чем за 100 мс  :) а какой сакральный сысл во всем этом? Задежать на 100 мс w.show() правильно?
нет,просто тренируюсь с потоками и таймером...понять как механизм вообще работает...
и кстати, если поставить точку останова w.show(), b не становится true...


Название: Re: QTimer и потоки
Отправлено: twp от Ноябрь 10, 2011, 16:46
может и действительно не вызывается, может есть проблемы при коннекте сигнала со слотом, в логе ничего такого нет?


Название: Re: QTimer и потоки
Отправлено: Edynchik от Ноябрь 10, 2011, 16:49
скорее всего, потому что если run явно вызвать func, то все ок....вопрос в том, как это исправить...


Название: Re: QTimer и потоки
Отправлено: twp от Ноябрь 10, 2011, 16:51
забыл Q_OBJECT в thread.h


Название: Re: QTimer и потоки
Отправлено: Edynchik от Ноябрь 11, 2011, 09:55
забыл Q_OBJECT в thread.h
возникли следующие ошибки:
Код:
debug/main.o: In function `MyThread':
F:\QT\thread-build-desktop/../thread//thread.h:6: undefined reference to `vtable for MyThread'
debug/main.o: In function `~MyThread':
F:\QT\thread-build-desktop/../thread//thread.h:6: undefined reference to `vtable for MyThread'
collect2: ld returned 1 exit status


Название: Re: QTimer и потоки
Отправлено: BRE от Ноябрь 11, 2011, 10:17
возникли следующие ошибки:
Нужно перегенерировать проект, запусти qmake.


Название: Re: QTimer и потоки
Отправлено: Edynchik от Ноябрь 11, 2011, 10:54
попробовал,но не вышло: сделал пересобрать все


Название: Re: QTimer и потоки
Отправлено: Edynchik от Ноябрь 21, 2011, 17:17
скажите,при использовании двух таймеров в одном отдельном потоке, по второму таймеру не функция не отрабатывается. Почему так может быть?
Код
C
Thread::run
{
t1.start(10);
connect(&t1,SIGNAL(timeout()),this,SLOT(func1()));
t2.start(1000);
connect(&t2,SIGNAL(timeout()),this,SLOT(func2()));
}
 
в func2 точка останова не срабатывает, а в func1 срабатывает...


Название: Re: QTimer и потоки
Отправлено: Edynchik от Февраль 03, 2012, 09:25
Опять возникла проблема в данной тематике:
QObject::startTimer: timers cannot be started from another thread
в приложение проект:


Название: Re: QTimer и потоки
Отправлено: Bepec от Февраль 03, 2012, 09:56
Таймер не может быть запущен в другом потоке. *дословный перевод*

Поясняю:
Ты создаешь класс потока.
Все поля класса, создаются в основном потоке и принадлежат ему.
Далее, запускаешь функцию start() и отделяешь поток.
Ну а далее, ты пытаешься запустить таймер, который остался в основном потоке.

Обход проблемы - поля класса делать указателями, и создавать таймеры в run()


Название: Re: QTimer и потоки
Отправлено: Edynchik от Февраль 03, 2012, 10:06
это да...только такое чувство что у меня это работало...я же файлы thread.cpp и thread.h взял из другого проекта...
решил спросить,вдруг чего...


Название: Re: QTimer и потоки
Отправлено: Bepec от Февраль 03, 2012, 10:22
А ты приведи работающий проект, прост интересно и самому стало, в каких условиях он не ругается.


Название: Re: QTimer и потоки
Отправлено: LisandreL от Февраль 03, 2012, 10:28
А ты приведи работающий проект, прост интересно и самому стало, в каких условиях он не ругается.
Может быть разница отладка/релиз.


Название: Re: QTimer и потоки
Отправлено: Edynchik от Февраль 03, 2012, 11:05
А ты приведи работающий проект, прост интересно и самому стало, в каких условиях он не ругается.
в том то и дело, что проект под МСВС(которой сейчас нет)..


Название: Re: QTimer и потоки
Отправлено: TaIRou от Февраль 04, 2012, 11:15
Таймер не может быть запущен в другом потоке. *дословный перевод*

Поясняю:
Ты создаешь класс потока.
Все поля класса, создаются в основном потоке и принадлежат ему.
Далее, запускаешь функцию start() и отделяешь поток.
Ну а далее, ты пытаешься запустить таймер, который остался в основном потоке.

Обход проблемы - поля класса делать указателями, и создавать таймеры в run()

А если этим локальным объектам класса, сделать moveToThread(this)?


Название: Re: QTimer и потоки
Отправлено: Bepec от Февраль 04, 2012, 12:33
То они оплюют тебя ^^

Это самая первая мысль, которая мне пришла в голову, но... матерятся они жестоким образом ;)


Название: Re: QTimer и потоки
Отправлено: TaIRou от Февраль 04, 2012, 12:44
То они оплюют тебя ^^

Это самая первая мысль, которая мне пришла в голову, но... матерятся они жестоким образом ;)

Может быть поэтому?
Цитировать
Use the QObject::moveToThread() function to change the thread affinity for an object and its children (the object cannot be moved if it has a parent).


Название: Re: QTimer и потоки
Отправлено: Bepec от Февраль 04, 2012, 17:42
Именно из-за этого.


Название: Re: QTimer и потоки
Отправлено: Edynchik от Февраль 06, 2012, 16:06
вот проект из МСВС...и там все работает...
кстати,тогда как в таком случае (проект somo2) остановить таймер в функции read?