Search code examples
c++qtqt4

Reading large Files


I want to read a 50MB file and send it over tcp. The file contains only floats. First I created only a Mainwindow, witch reads one line and sends it to the Server, but the gui got frozen. So I created a class that depends on QThread called QSendThread. Here is the Code for the class QThread:

#ifndef QSENDTHREAD_H
#define QSENDTHREAD_H

#include <QThread>
#include <QLabel>
#include <QFile>
#include <QMessageBox>
#include <QtNetwork/QTcpSocket>
#include <QtNetwork/QHostAddress>

class QSendThread : public QThread
{
 Q_OBJECT

public:
 QSendThread(QTcpSocket* qtcpso, QLabel* qlbl, QFile* qfiel, QObject *parent = NULL);
 ~QSendThread();

protected:
 void run(void);

private:
 QTcpSocket* qtcpsoDest;
 QLabel* qlblRef;
 QFile* qfileRef;

signals:
 void error(QString qstrError);
};

#endif // QSENDTHREAD_H

#include "qsendthread.h"

QSendThread::QSendThread(QTcpSocket* qtcpso, QLabel* qlbl, QFile* qfile, QObject *parent)
 : QThread(parent)
{
 qtcpsoDest = qtcpso;
 qlblRef = qlbl;
 qfileRef = qfile;
}

QSendThread::~QSendThread()
{
}

void QSendThread::run(void)
{
 int iLine = 0;

 do
 {
  QByteArray qbarrBlock;
  QDataStream qdstrmOut(&qbarrBlock, QIODevice::WriteOnly);

            // show witch line is read
  qlblRef->setText(tr("Reading Line: %1").arg(++iLine));

  qdstrmOut.setVersion(QDataStream::Qt_4_6);
  qdstrmOut << (quint16)0;
  qdstrmOut << qfileRef->readLine().data();
  qdstrmOut.device()->seek(0);
  qdstrmOut << (quint16)(qbarrBlock.size() - sizeof(quint16));

  qtcpsoDest->write(qbarrBlock);
  qtcpsoDest->flush();

  qbarrBlock.clear();
 } while(!qfileRef->atEnd());
}

But the program crashing in the method qregion::qt_region_strictContains(const QRegion &region, const QRect &rect)

Is the method to read the file like I am doing wrong?

Thanks for Help.


Solution

  • First, you shouldn't really need to subclass QThread. The Qt documentation is misleading on this point. See this accepted answer for a similar question for lots of good info.

    Second, you can only correctly access the gui from the main thread so your call qlblRef->setText() would be a problem. Accessing the gui from a thread other than the main one can be done using signals and slots or postEvent(). You can read up on events here.

    Finally, this documentation is really required reading for working with threads in Qt. Pay particular attention to the section on threads and QObjects.

    Addition:

    To follow the advice above, you could certainly wrap your file reading code in a QObject subclass. An alternative (which I have little experience with myself) may be to try putting your code in QtConcurrent::run() and getting the result with a QFuture.