PDA

View Full Version : Eventloop does not quit properly



MrAnderson1983
1st June 2014, 13:51
Hello guys,

i have a question relating QEventloop class. During my initialisation routine some functions should be started sequentially. To gaurantee that i wrote this peace of code:



//mainwindow.cpp

void MainWindow::doInit()
{
QEventLoop loop;
connect(this, SIGNAL(Function1Complete()), &loop, SLOT(quit()));

qDebug() << "Step1";
StartFuntion1();
loop.exec();
qDebug() << "Step2";
StartFuntion2();
}

void MainWindow::StartFuntion1()
{
...
emit Function1Complete();
}

//mainwindow.h
...
signals:
void Function1Complete();


But when i run my code "Step2" is never reached. When i emit "Function1Complete" with an additional button like this


void MainWindow::handle_btnTest()
{
emit Function1Complete();
}


my eventloop quits properly and everything works fine. Any ideas about that?

Lesiok
1st June 2014, 14:00
First of all You are emmiting signal Function1Complete() before starting internal event loop. In default mode emit signal to object in this same thread
is equivalent to direct call slot method . So QEventLoop::quit is called before QEventLoop::exec.
Second in this example StartFunction2() is started sequentially after StartFunction1(). What is real problem ?

MrAnderson1983
1st June 2014, 15:45
First of all You are emmiting signal Function1Complete() before starting internal event loop. In default mode emit signal to object in this same thread
is equivalent to direct call slot method . So QEventLoop::quit is called before QEventLoop::exec.

I just followed this example:
http://stackoverflow.com/questions/3556421/blocked-waiting-for-a-asynchronous-qt-signal
As far as i know "StartFuntion1" will never be reached when you call it after QEventLoop::exec, because the quit condition is called within "StartFuntion1".


Second in this example StartFunction2() is started sequentially after StartFunction1(). What is real problem ?

I have the same issue which is described in the url above. StartFuntion1 is an asychronous call.

StartFunction1 downlaod several *.csv files and StartFunction2 should analyze them. The problem is that StartFunction2 starts to read the files before they are completely downloaded. Sorry, i should mentioned it earlier.

Lesiok
2nd June 2014, 07:23
Show real StartFunction1.

MrAnderson1983
3rd June 2014, 20:05
Show real StartFunction1.

Sure.



void MainWindow::StartFunction1()
{
//Actualize
m_dataPath.setFilter(QDir::Files);
m_dataPath.setNameFilters(QStringList() << "*.csv");
QString strID;
DownloaderDLL *d = new DownloaderDLL;

foreach (QString filename, m_dataPath.entryList())
{
strID = QFileInfo(filename).baseName();
strID.replace("_",".");

d->doDownload(strID);
}
m_DownloadComplete = true;
}




void DownloaderDLL::doDownload(QString str_ID)
{
m_strID=str_ID;
m_strValues="nabl1c1p2t1d1";

url = "http://download.finance.yahoo.com/d/quotes.csv?s=" + m_strID + "&f=" + m_strValues + "&e=.csv";


reply = manager.get(QNetworkRequest(url));
connect(reply, SIGNAL(finished()),
this, SLOT(replyFinished()));
}

void DownloaderDLL::replyFinished ()
{
if(reply->error())
{
file->remove();
QMessageBox::warning(NULL, tr("Download data"),
tr("Download failed: %1.")
.arg(reply->errorString()));
}
else
{
QByteArray strContent;
strContent = reply->readAll();
if (strContent.contains("N/A"))
{
QMessageBox::warning(NULL, tr("Download data"),
tr("Could not find ID: %1. \nPlease try again")
.arg(m_strID));
}
else
{
m_strID.replace(".","_");
file = new QFile(QDir::currentPath() + "\\data\\watchlist\\stocks\\" + m_strID + ".csv");


if(file->open(QFile::Append))
{
file->write(strContent);
QMessageBox::information(NULL, tr("Download data"),
tr("Download finished to following path: %1.")
.arg(file->fileName()));

file->flush();
file->close();
}


}
}

reply->deleteLater();
reply = 0;
delete file;
file = 0;
}


StartFunction1 scans for *.csv files with special ID filenames. This IDs can be used to determine and extract stock values from yahoo. I append actual data to the *.csv files. In the next step i want to scan all *.csv files and extract actual data to show them in a gui. The problem is that the second scan is proceeded before downloading is finished.

Maybe i could implement the second step within "replyFinished" for each value avoid that problem.

Lesiok
4th June 2014, 06:58
In the function StartFunction1 you initiate the download of data but nowhere waiting for its completion.

MrAnderson1983
4th June 2014, 08:57
How i can wait for its completion?

yeye_olive
4th June 2014, 10:31
Instead of immediately emitting the signal notifying that Function1 has finished, do it in replyFinished() when the last reply has finished.