Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > [QT4] Использование QTimer в QThread


Автор: Mal Hack 14.3.2008, 20:33
Доброе время суток.
Задача - использование QTimer'a в QThread, вариант sleep в самом потоке не желателен... Сейчас работает так, но алгоритмически это - ошибка в решаемой задачи...
Почитал я кое-что... Сделал вывод, что надо поток создавать exec'ом, но вот где ему тогда прописывать то, что он должен делтать по таймеру - вопрос... Я так понимаю, могу обойтись и встроенными в QThread (от QObject): startTimer(int), killTimer...

Спасибо.

Автор: JackYF 14.3.2008, 21:16
Чего-то я не понял вопроса и проблемы...


M
JackYF
Пометочку [QT] в начале темы ставь-то, правила раздела читаем? :)

Автор: Mal Hack 14.3.2008, 22:56
Суть проблемы. Есть QThread, внутри него:
Код

run()
{
 while(true)
{sleep(10 ms);}
}

Но... Мне надо выпонлять операции в цикле не с промежутком в 10 мс, а с тактом в 10 мс.. Т.е.
Грубо говоря, чтобы 10 мс отсчитывались не от времени последней операции, а как в таймере..

Автор: bsa 15.3.2008, 00:00
не уверен, что тебе ОС такую периодичность сможет гарантировать

Автор: JackYF 15.3.2008, 00:56
Цитата(bsa @  14.3.2008,  23:00 Найти цитируемый пост)
не уверен, что тебе ОС такую периодичность сможет гарантировать 

ну, 10 миллисекунд, думаю, сможет


Mal Hack, ну это...
Код

run()
{
  QTimer* timer = new QTimer;
  timer->setInterval(10);
  connect(timer, SIGNAL(timeout()), obj, SLOT(do()));
}

void do()
{
  //делаем, делаем...
}

Оно, нет? У меня стойкое ощущение, что что-то я в вопросе упустил...

Автор: SABROG 15.3.2008, 01:02
Цитата(JackYF @  15.3.2008,  00:56 Найти цитируемый пост)
Оно, нет? У меня стойкое ощущение, что что-то я в вопросе упустил... 


Ни у тебя одного, это уже вторая тема автора где я с трудом понимаю чего хочет человек smile

Немного оффтопика. Глядя на new без delete все-время возникают нехорошие мысли, я конечно понимаю, что в случае с Qt это нормально. А такой вопрос назрел, предположим есть класс, который создается, чтобы выполнится один раз и удалится. Вот как таймер, покрутился 30 минут, истек интервал и должен удалится. Возможно ли удаления класса самим себя где-нибудь в конце метода или даже конструктора, когда он дотуда дойдет ?

Автор: Mal Hack 15.3.2008, 01:35
Задача - опрашивать устройство с частотой 100 Гц, делать это надо в потоке ибо не дай бог что отвалить, основная нить должна жить и с ней надо работать дальше ;)
Цитата(JackYF @  15.3.2008,  00:56 Найти цитируемый пост)
Оно, нет? У меня стойкое ощущение, что что-то я в вопросе упустил... 

Если бы все было так просто ;)
Имею при запуске:
Код

Object::connect: Parentheses expected, signal QTimer::timeout
QObject::startTimer: timers cannot be started from another thread

Код

class thInsRead : public QThread
{
    Q_OBJECT
    public:
        thInsRead();
        void setPort(string);
        bool startCheck();
        void stopping(bool);
    signals:
        void signalStop();
    public slots:
        void callIns();
    protected:
        QTimer *timer;
    private:
        void run();
};
конструктор:
{
    timer = new QTimer();
    connect(timer,SIGNAL(timeout()),this,SLOT(callIns()));
}

run()
{    
    nsIns::insReadStart();
    timer->start(10);
}

void thInsRead::callIns()
{    
do some one
}


Автор: bsa 15.3.2008, 01:53
Mal Hack, вообще-то таймеры созданы в основном для работы с интерфейсом (я их так понимаю). Именно поэтому их нельзя запускать из отдельного потока.
А потом, что значит "отвалится"? Сделай проверку, чтобы не повисало. В любом случае, проку от проги с повисшим потоком - 0, так как его надо убивать, а там ресурсы могут не подчиститься... В общем, плохая идея.
Думаю, тебе придется завязаться на API предоставляемый OS.

Автор: nickless 15.3.2008, 02:58
Цитата(bsa @  14.3.2008,  23:53 Найти цитируемый пост)
поэтому их нельзя запускать из отдельного потока

Ну почему? Можно, если event loop запустить
Цитата
In multithreaded applications, you can use QTimer in any thread that has an event loop.


Код

//Ti.h
#ifndef TI_H
#define TI_H


#include <QThread>
#include <QTimer>
#include "main.h"

class Ti: public QThread
{
    Q_OBJECT
public:
    Ti(Bla * b, QObject * parent = 0)
        : QThread(parent)
    {
        bb = b;
        QObject::connect(this, SIGNAL(upd()), bb, SLOT(upd2()));
    }

    virtual ~Ti();

    void run();

public slots:
    void doIt()
    {
//        startTimer(100);
        QTimer *timer = new QTimer(this);
        connect(timer, SIGNAL(timeout()), bb, SLOT(upd2()));
        timer->start(100);
    }

signals:
    void upd();

protected:
    void timerEvent(QTimerEvent *event)
    {
        qDebug() << "thread ID: " << this << "timer ID:" << event->timerId();
        emit upd();
    }

private:
    Bla * bb;
};

#endif


Код

//Ti.cpp
#include "Ti.h"

Ti::~Ti()
{
}

void Ti::run()
{
    qDebug() << "entering event loop";
    exec();
    qDebug() << "leaving event loop";
}


Код

//main.h
#ifndef BLA
#define BLA

#include <QPushButton>
#include <QDebug>
#include <QTimerEvent>

class Bla : public QPushButton
{
    Q_OBJECT
public:
    Bla(QWidget * parent = 0)
        : QPushButton(parent)
    {
    }

    virtual ~Bla()
    {
    }

public slots:
    void doIt()
    {
        startTimer(102);
    }

    void upd1()
    {
        move(0, 0);
    }

    void upd2()
    {
        move(60, 0);
    }

protected:
    void timerEvent(QTimerEvent *event)
    {
        qDebug() << "Timer ID:" << event->timerId();
        upd1();
    }
};


#endif


Код

//main.cpp
#include <iostream>
#include <iomanip>

#include "main.h"
#include "Ti.h"
#include <QApplication>
#include <QFrame>
#include <QLineEdit>

using namespace std;

int main(int argc, char ** argv)
{
    QApplication app(argc, argv);
    QFrame * fra = new QFrame();
    fra->resize(200, 100);
    Bla * bla = new Bla(fra);
    bla->setText("Bla");
    QLineEdit * ed = new QLineEdit(fra);
    ed->move(20, 50);
    Ti * thr = new Ti(bla, fra);
    thr->start();

    QObject::connect(bla, SIGNAL(pressed()), bla, SLOT(doIt()));
    QObject::connect(bla, SIGNAL(pressed()), thr, SLOT(doIt()));

    fra->show();
    int r = app.exec();
    thr->quit();
    delete fra;
    return r;
}



ЗЫ
Насчет new без delete, parent надо не забывать передавать, а то вот это
Цитата(JackYF @  14.3.2008,  22:56 Найти цитируемый пост)
QTimer* timer = new QTimer;

не удалится smile 

Цитата(SABROG @  14.3.2008,  23:02 Найти цитируемый пост)
Возможно ли удаления класса самим себя где-нибудь в конце метода или даже конструктора, когда он дотуда дойдет ? 

Посмотри http://doc.trolltech.com/4.2/qobject.html#deleteLater

Автор: Mal Hack 15.3.2008, 19:15
nickless, если честно, не фига не понял, что вы хотели сказать этим постом...
Пробовал сделать по аналогии - результат как и раньше...
метод, который должен выполняться по таймеру лежит в обьекте потока.

Автор: nickless 15.3.2008, 22:32
Цитата(Mal Hack @  15.3.2008,  17:15 Найти цитируемый пост)
nickless, если честно, не фига не понял, что вы хотели сказать этим постом...

Ну это был как-бы пример использования QTimer в QThread...

Цитата(Mal Hack @  15.3.2008,  17:15 Найти цитируемый пост)
Пробовал сделать по аналогии - результат как и раньше...

Код + ошибки в студию.

Автор: Mal Hack 15.3.2008, 23:42
Сделал так:
Код

myth::myth()
{
    timer = new QTimer();
    connect(timer,SIGNAL(timeout()),this,SLOT(callIns()));
    timer->setInterval(10);
}

void myth::threadStart()
{    
    timer->start();
}

void myth::run()
{    exec();    }

void myth::callIns()
{    doSomethingNeed();    }

void myth::stopping(bool clean)
{    
    timer->stop();
}

Автор: nickless 16.3.2008, 00:37
Вот это
Цитата(Mal Hack @  15.3.2008,  21:42 Найти цитируемый пост)
void myth::threadStart()

когда вызывается?

Какие ошибки?

Добавлено через 1 минуту и 46 секунд
Цитата(nickless @  15.3.2008,  22:37 Найти цитируемый пост)
когда вызывается?

Надо чтобы вызывалось после run() 

Автор: Mal Hack 16.3.2008, 13:34
nickless, ошибок нет...
Вызываю после run...
Все работает smile)


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)