PDA

View Full Version : emit qt signal is very slow how it can be optimized?



sawerset
28th December 2008, 15:32
I have a such peace of code.

thread that reeds the file



#include <QThread>
#include <QString>
class openner : public QThread
{
Q_OBJECT

public:
openner(QString);
~openner();
void run();
private:
QString file;
signals:
void onStart(int);
void on(int);
void onEnd(int);
};




#include "openner.h"
#include <QFile>
#include <QTextStream>
openner::openner(QString f)
: QThread(0)
{
file=f;
}
void openner::run()
{
QString str;
QFile f(file);
f.open(QIODevice::ReadOnly | QIODevice::Text);
QTextStream in(&f);
emit onStart(f.size());
while(!in.atEnd())
{
str=in.readLine();
emit on(in.pos());
}
emit onEnd(f.size());
f.close();
}
openner::~openner()
{

}



main form



#include <QtGui/QMainWindow>
#include <QProgressBar>
#include "openner.h"
class progressTest : public QMainWindow
{
Q_OBJECT
private:
openner *o;
QProgressBar *pb;
public:
progressTest(QWidget *parent = 0, Qt::WFlags flags = 0);
~progressTest();
protected slots:
void onStart(int);
void onProgres(int);
void onEnd(int);
};





#include "progresstest.h"

progressTest::progressTest(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
pb=new QProgressBar(this);
pb->resize(200,20);
o=new openner("C:\\projects\\umc\\UMC_invoice_.28532.00.00.100000 _id_0793918_part_1.csv");
QObject::connect(o,SIGNAL(onStart(int)),this,SLOT( onStart(int)));
QObject::connect(o,SIGNAL(on(int)),this,SLOT(onPro gres(int)));
QObject::connect(o,SIGNAL(onEnd(int)),this,SLOT(on End(int)));
o->start();
}
void progressTest::onStart(int m)
{
pb->setMaximum(m);

}
void progressTest::onProgres(int l)
{
pb->setValue(l);
}
void progressTest::onEnd(int l)
{
pb->setValue(0);
}
progressTest::~progressTest()
{

}



When I use my program with emit on(in.pos()); then it takes for about three hours to read file. But then I use it without emit on(in.pos()); file is read in the minutes. the size of file is 3000 kb
How the emit of signal can be optimised?
OS - windows XP
IDE - Microsoft Visual Studio 2008?

aamer4yu
29th December 2008, 08:31
What happens if u use Qt::DirectConnection as last argument with connect ?

spirit
29th December 2008, 09:19
it's bad idea to use Qt:: DirectConnection between threads, Qt::QueuedConnection must be used.

sawerset
29th December 2008, 10:03
I tried Qt::QueuedConnection and nothing changed.

spirit
29th December 2008, 10:11
yes, because by default last parameter in 'connect' is Qt::AutoConnection, which means


If the signal is emitted from the thread in which the receiving object lives, the slot is invoked directly, as with Qt:: DirectConnection; otherwise the signal is queued, as with Qt::QueuedConnection.

try to use customs events, but I think result will not change.
ps. if you use thread just for loading information and don't transform it then you can you only main thread and use qApp->processEvents() in long time operations.

caduel
29th December 2008, 10:11
a) Qt::QueuedConnection is the default for threads. So explicitly specifying it won't change anything.

b) simple solutions might be

emit the signal not every time but only every 100th time (or so)
just open the file in a normal function call, update the gui and call QCoreApplication::processEvents() now and then
do not use a thread
use a plain callback (do not forget to synchronize access! and don't forget you must not call gui code from another thread!)


HTH

Lesiok
30th December 2008, 08:48
What happen when You don't emit signal but You call in.pos() ?

jbiloba
30th December 2008, 10:16
#include "openner.h"
#include <QFile>
#include <QTextStream>
openner::openner(QString f)
: QThread(0)
{
file=f;
}
void openner::run()
{
QString str;
QFile f(file);
f.open(QIODevice::ReadOnly | QIODevice::Text);
QTextStream in(&f);
emit onStart(f.size());
while(!in.atEnd())
{
str=in.readLine();
emit on(in.pos());

QApplication::processEvents();

}
emit onEnd(f.size());
f.close();
}
openner::~openner()
{

}



Try the processEvents() function. I think that u emit too much signals, so the GUI its not able to process them during an intensive while loop.

jbiloba
30th December 2008, 10:21
OPPS! Sorry for the mistake

use QCoreApplication::processEvents();