PDA

View Full Version : Loading QTableWidget using QTimer like batch processing, but application holds



rawfool
24th June 2013, 13:14
I'm parsing a XML file (size varies between 500K & 90 M) and the output of parse is a QStringList. Each index in the stringlist is split based on a seperator & the data is loaded into the table.
So when I try to load the data into table, the application doesn't respond till the loading is complete. So I decided to do the processing in QTimer. But still the application behaves the same way while the table gets loaded with data. I tried to debug this, but the debugger isn't stopping at the break-point.

This is how I've done -

// cresultstable.h
class CResultsTable : public QTableWidget
{
Q_OBJECT
public:
CResultsTable(QString fName, QWidget *parent = 0);

private:
QTimer *batchTimer;

.... // other widgets

private slots:
void batchLoadRecords(string str, int nRow);

public slots:
void loadTable(); // This will be called on signal
};

This is how I'm calling timer, timeout() to process data -

// cresultstable.cpp
CResultsTable::CResultsTable(QString fName, QWidget *parent) :
QTableWidget(parent)
{
... // other initializations
...

batchTimer = new QTimer(this);
connect(batchTimer, SIGNAL(timeout()), this, SLOT(batchLoadRecords(string, int)));
};

void CResultsTable::loadTable()
{
XMLParser *xmlParse;
xmlParse= new XMLParser();

xmlParse->Parse();
std::vector<std::string> info = xmlParse->GetInfo(); // info contains the data of parsed XML document

int numOfItems = info.size();
setRowCount(numOfItems);
batchTimer->start(); // Starting the timer here;
// Giving timeout of 0 because Qt doc says : "QTimer with a timeout of 0 will time out as soon as all the events
//in the window system's event queue have been processed. This can be used to do heavy work while
//providing a snappy user interface"


for(it = info.begin(); it != info.end(); it++)
{
std::string str = *it;
// Here I'm trying to load
batchLoadRecords(str, nRow); // Put a break-point here but it's not stopping
nRow++;
}
batchTimer->stop();
emit sig_LoadComplete();
delete xmlParse;

How do I make the application to behave normally without holding the application event, even while loading data ? Kindly help me with this.
Thank you.

rawfool
25th June 2013, 07:12
I found a mistake in my code that I was calling batch function again in loop apart from timeout's SLOT. So, I modified my approach, but now the application is crashing.


// cresultstable.h
class CResultsTable : public QTableWidget
{
Q_OBJECT
public:
CResultsTable(QString fName, QWidget *parent = 0);

private:
QTimer *batchTimer;
std::vector<std::string>::iterator it;
std::vector<std::string>::iterator endOfFile;
int rowIterator;

.... // other widgets

private slots:
void batchLoadRecords();

public slots:
void loadTable(); // This will be called on signal
};

Now I'm not using loop to iterate for each index of the string vector. Instead, I'm calling the batchLoadRecords() in timer's timeout slot only.


// cresultstable.cpp
CResultsTable::CResultsTable(QString fName, QWidget *parent) :
QTableWidget(parent)
{
... // other initializations
...

batchTimer = new QTimer(this);
connect(batchTimer, SIGNAL(timeout()), this, SLOT(batchLoadRecords()));
};

void CResultsTable::loadTable()
{
XMLParser *xmlParse;
xmlParse= new XMLParser();

xmlParse->Parse();
std::vector<std::string> info = xmlParse->GetInfo(); // info contains the data of parsed XML document

int numOfItems = info.size();
setRowCount(numOfItems);

rowIterator = 0;
it = info.begin();
endOfFile = info.end();

batchTimer->start(); // Starting the timer here;

delete resultParse;
resultParse = NULL;
}

void CResultsTable::batchLoadRecords()
{
int temp = 0;
QStringList txt;
QString s;

if(it == endOfFile)
{
batchTimer->stop();
emit loadComplete();
return;
}
std::string str = *it; // Break-point here

// --------- vv
// Adding the data into table rows here
// --------- ^^

it++;
rowNumber++;
}

I put break-point, but the application crashes and shows some dissembler code.
The stack points at 0

0 RaiseException KERNELBASE 0x75a1812f
1 CxxThrowException MSVCR100 0x6ee8872d
2 fcloseall MSVCR100 0x6ee9f30f
3 com_ximpleware::VTDNav::getXPathStringVal MyApp 0xfb1c88
4 com_ximpleware::VTDNav::getXPathStringVal MyApp 0xfb1f7e
5 com_ximpleware::VTDNav::getXPathStringVal MyApp 0xfc3e6a

rawfool
25th June 2013, 11:19
It's solved. I had to make my std::vector<std::string> info as member variable, so that the data in that is not lost after the traverse of the function.
Thank you.