Threads,Timer e Atualizar um Campo
-
-
Rodrigocg,
Seguindo seu exemplo minha classe .h ficou assim:
@class MyThread : public QThread
{
public:void run();
};
void MyThread::run()
{
QTimer *timer;
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(ler_arquivos()));
timer->start(1000);
}@Só que agora recebo a seguinte mensagem:
@QThread: Destroyed while thread is still running@
e no Linux ocorre a seguinte mensagem:
@ASSERT failure in QList<T>::at: "index out of range", file /usr/include/qt5/QtCore/qlist.h, line 454
The program has unexpectedly finished.@E o programa trava, alguma ideia do que ocorre?
-
Rodrigocg,
Agradeço pela ajuda e boa sorte na sua prova. Segue em anexo o link:
https://docs.google.com/file/d/0BwQ4G9j5uY1JQWc5OTloU1RvMzg/edit?usp=sharing
-
Desculpe a demora...
tente implementar a classe MThread assim:
@#ifndef MTHREAD_H
#define MTHREAD_H
#include <QThread>
#include <QTimer>class Mthread: public QThread
{Q_OBJECT
public:
explicit Mthread(QObject *parent = 0): QThread(parent){}
void run()
{
QTimer *timer;
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this->parent(), SLOT(leitura()));
timer->start(1000);}
};
#endif // MYTHREAD_H@
Se vc usar o header vc faz do geito que postei assima...
se nao, usa o reader pra prototipar a classe e o arquivo .cpp pra implementar a classe....
-
Vocês precisam tomar cuidado com QObjects (slots) e threads no Qt. Vejam "aqui":http://qt-project.org/doc/qt-4.8/threads-qobject.html.
Em linhas gerais, para que os signal/slots funcionem corretamente, é necessário um "event loop" (um processador de eventos).
É por isso que em todo programa Qt, no main.cpp tem um código parecido com este:
@
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();return a.exec(); //Entra num loop infinito, processando e despachando eventos
}
@"If no event loop is running, events won't be delivered to the object. For example, if you create a QTimer object in a thread but never call exec(), the QTimer will never emit its timeout() signal. Calling deleteLater() won't work either. (These restrictions apply to the main thread as well.)"
Tradução Google:
"Se nenhum ciclo de eventos está sendo executado, os eventos não serão entregues ao objeto. Por exemplo, se você criar um objeto QTimer em uma Thread, mas nunca chamar exec (), o QTimer nunca emitem seu sinal de timeout (). Chamando deleteLater () também não vai funcionar. (Estas restrições aplicam-se a thread principal também.)"
-
Se você olhar para o Windows por exemplo, a função da Win32 para timers é a SetTimer - http://msdn.microsoft.com/en-us/library/windows/desktop/ms644906(v=vs.85).aspx. E ele posta uma mensagem (no caso WM_TIMER) na fila de mensagens da thread. E no Winsock, existe um modo de funcionamento que não trava as chamadas que usa o loop de mensagens WSAASyncSelect - http://msdn.microsoft.com/en-us/library/windows/desktop/ms741540(v=vs.85).aspx .
É por isso, que se vc usa alguns objetos do Qt não visuais (como o QTimer etc) em threads, é recomendado que você tenha um loop em cada thread.
Aqui no forum sempre rola uns problemas desses....
http://qt-project.org/forums/viewthread/15559 -
Rodrigocg/TioRoy,
Desculpa a demora em responder tive uns problemas que me tomaram um tempo danado.
Rodrigo vou usar o header do jeito que vc me passou mas fiquei na duvida de como executar o mesmo.
Estou deixando assim:@MainWindow::MainWindow(QWidget parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QTimer timer = new QTimer;
leitura();
connect(timer, SIGNAL(timeout()), this, SLOT(leitura()));
timer->start(150000);
}@Está correto? Pq não está atualizando os campos que preciso.
O que estou fazendo de errado?