Ver Mensaje Individual
  #1 (permalink)  
Antiguo 15/05/2015, 06:54
susi141
 
Fecha de Ingreso: agosto-2011
Mensajes: 73
Antigüedad: 12 años, 9 meses
Puntos: 0
Pregunta Error en Qt/C++ trabajando con hilos

Hola,

Estoy trabajando en Qt Creator con C++, tengo tres hilos, por ahora,el principal, uno para tomar una data y otro para subir al servidor.

Utilizo un Api para conectarme a la base de datos, por lo que cree una clase en c++, Api, donde delcaro todos los metodos que necesito, por ahora esto ha funcionado muy bien, pero ahora requiero hacer el llamado de un metodo en los otros hilos.

Entonces primero intente pasar por parametro la instancia api, que tiene toda la información de la session, cuando intento hacer esto me da un error que finaliza el programa inexperadamene justo cuando hace el llamdo del metodo con el request a la api de crear un registro.

Luego intente otra forma, con signals y slots, funciona para el primera llamado que hago, que al inicial el hilo, tengo un while que se repite constantemente, hay un delay de 1 minuto, luego hace lo que tiene que hacer y vuelve a hacer otro llamado un metodo de la Api, cuando hace esto me genera este error:

Código Qt:
Ver original
  1. QEventLoop::exec: instance 0x15719fb0 has already called exec()

Estoy super estancada en este error y no he podido avanzar mas. Dejo por aqui el codigo de donde se me presenta el error:

task es la clase principal que muestra una ventana, al precionar un boton en task comienza a correr un hilo CaptureThread, y desde CaptureThread llamo al tercer hilo UploadS3.

task.h

Código Qt:
Ver original
  1. #ifndef TASK_H
  2. #define TASK_H
  3.  
  4. #include <QMainWindow>
  5. #include <QSystemTrayIcon>
  6. #include "capturethread.h"
  7. #include "api.h"
  8. #include <QJsonArray>
  9.  
  10. namespace Ui {
  11. class Task;
  12. }
  13.  
  14. class Task : public QMainWindow
  15. {
  16.     Q_OBJECT
  17.  
  18. public:
  19.     explicit Task(Api* api, int projectid, QWidget *parent = 0);
  20.     ~Task();
  21.      Api* currentapi;
  22.      QJsonArray tasks;
  23. public slots:
  24.       void iconActivated(QSystemTrayIcon::ActivationReason reason);
  25. private slots:
  26.       void on_btn_SwitchProject_clicked();
  27.  
  28.       void on_btnStart_clicked();
  29.  
  30.       void on_btnStop_clicked();
  31.  
  32.       // slots for the trayicon
  33.       void logout();
  34.       void resume();
  35.       void suspend();
  36.       void update();
  37.       void log();
  38.       void clog();
  39.  
  40. private:
  41.     Ui::Task *ui;
  42.     QSystemTrayIcon* trayIcon;
  43.     QMenu* trayIconMenu;
  44.     QAction* resumeAction;
  45.     QAction* suspendAction;
  46.     QAction* logoutAction;
  47.     QAction* openTask;
  48.     QAction* timeLoggedAction;
  49.     CaptureThread* capThread;
  50.  
  51. };
  52.  
  53. #endif // TASK_H

task.cpp

Código Qt:
Ver original
  1. #include "task.h"
  2. #include "ui_task.h"
  3. #include "projects.h"
  4. #include <QMessageBox>
  5. #include <QMenu>
  6. #include <QDebug>
  7. #include <QJSonArray>
  8. #include <QDesktopWidget>
  9. #include <QNetworkCookieJar>
  10.  
  11. Task::Task(Api *api, int projectid, QWidget *parent) :
  12.     QMainWindow(parent),
  13.     ui(new Ui::Task)
  14. {
  15.    .........
  16.  
  17.     capThread = new CaptureThread(0);
  18. }
  19.  
  20.  
  21. void Task::on_btnStart_clicked()
  22. {
  23.     .....
  24.         connect (capThread, SIGNAL(createLog()),this,SLOT(log()));
  25.         connect (capThread->uploads3, SIGNAL(closelog()),this,SLOT(clog()));
  26.  
  27.         hide();
  28.        
  29.         capThread->flagpause = false;
  30.         capThread->resume();
  31.         capThread->start();
  32.     }
  33. }
  34.  
  35. ....
  36.  
  37. void Task::update(){
  38.     timeLoggedAction->setText("Time Logged: "+QString::number(capThread->countTime)+" min");
  39. }
  40.  
  41. void Task::log(){
  42.     currentapi->createLog(currentapi->jsonUser["id"].toInt(),currentapi->jsonSession["id"].toInt());
  43. }
  44.  
  45. void Task::clog(){
  46.     currentapi->closeLog(currentapi->jsonUser["id"].toInt(),currentapi->jsonLog["id"].toInt(),"capThread->url", "capThread->url");
  47. }

CaptureThread.cpp

Código Qt:
Ver original
  1. CaptureThread::CaptureThread(QObject *parent):
  2.     QThread(parent)
  3. {
  4.     this->countTime = 0;
  5.     this->url = " ";
  6.     this->uploads3 = new UploadToS3();
  7. }
  8.  
  9. void CaptureThread::run(){
  10.  
  11.     while (true) {
  12.            if (!flagpause){
  13.                emit createLog();
  14.             }
  15.            this->msleep(60000);
  16.            QDesktopWidget* dw = QApplication::desktop();
  17.            QPixmap pixmap = QPixmap::grabWindow( dw->winId(), 0, 0, dw->width(), dw->height() );
  18.  
  19.            QDir mDir(QDir::homePath());
  20.            QString format = "jpg";
  21.            QString filename = "/screenshot_" + QString::number(QDate::currentDate().year())+ "_"
  22.                    +QString::number(QDate::currentDate().month())+ "_"
  23.                    +QString::number(QDate::currentDate().day())+ "_"
  24.                    +QString::number(QTime::currentTime().hour())+ "_"
  25.                    +QString::number(QTime::currentTime().minute())+ "_"
  26.                    +QString::number(QTime::currentTime().second());
  27.            QString mPath = QDir::homePath() + "/user";
  28.            if (!mDir.exists(mPath))
  29.                 mDir.mkpath(mPath);
  30.            pixmap.save(mPath+filename+".jpg", format.toLatin1().constData());
  31.            this->url = mPath+filename+".jpg";
  32.            uploads3->start();
  33.            sync.lock();
  34.            this->countTime ++;
  35.            emit counTimeChange(this->countTime);
  36.            if(flagpause)
  37.                  pauseCond.wait(&sync);
  38.            sync.unlock();
  39.        }
  40. }
  41.  
  42. void CaptureThread::pause() {
  43.         sync.lock();
  44.         flagpause = true;
  45.         sync.unlock();
  46. }
  47.  
  48. void CaptureThread::resume() {
  49.         sync.lock();
  50.         flagpause = false;
  51.         sync.unlock();
  52.         pauseCond.wakeAll();
  53. }

Por ultimo UploadToS3.cpp solo hace emit closelog(); en el run().

No veo a que se debe ese error de Eventloop, por favor si alguien pudiera orientarme un poco, para resolver este error o si es que lo estoy haciendo mal, me pudieran indicar la forma correcta de manejar hilos en Qt.