I'm trying to download a page from a server to my QT program, but I've been searching ways to do it and they don't really work a lot. I'm not an expert in QT/C++, so be kind :)
Well.. So far I come with this code:
[OLD CODE] - Check the updated code bellow!
http.cpp
#include "http.h"
http::http(QObject *parent) :
QObject(parent)
{
qDebug() << "HTTP ST";
http1 = new QHttp(this);
connect(http1, SIGNAL(done(bool)), this, SLOT(httpdown())); // Correction 1.
http1->setHost("localhost");
http1->get("/test.php");
qDebug() << "HTTP END";
}
void http::httpdown()
{
qDebug() << "completed!";
qDebug() << http1->readAll();
}
http.h
#ifndef HTTP_H
#define HTTP_H
#include <QtNetwork>
#include <QHttp>
#include <QDebug>
#include <QObject>
class http : public QObject
{
Q_OBJECT
public:
explicit http(QObject *parent = 0);
signals:
public slots:
void httpdown();
private:
QHttp *http1;
};
#endif // HTTP_H
Well the problem is that httpdown() is never called, and I've tried anything I know :( Probably I'm not doing this correctly.
Help will be much appreciated.
Thanks.
QUESTION UPDATE
I've ear the suggestion of alexisdm and to check QNetworkAccessManager. So here it is new code working on the main() correctly.
When I run it from another class I never get the signal.
[NEW CODE]
http2.cpp
#include "http2.h"
http2::http2(QObject *parent) :
QObject(parent)
{
m_manager = new QNetworkAccessManager(this);
connect(m_manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(httpdown(QNetworkReply*)));
QNetworkRequest request;
request.setUrl(QUrl("http://localhost/test.php"));
request.setRawHeader("User-Agent", "MyOwnBrowser 1.0");
m_manager->get(request);
}
void http2::httpdown(QNetworkReply* result)
{
QByteArray data= result->readAll();
QString str(data);
qDebug() << str;
}
http2.h
#ifndef HTTP2_H
#define HTTP2_H
#include <QObject>
#include <QDebug>
#include <QtNetwork>
#include <QNetworkReply>
class http2 : public QObject
{
Q_OBJECT
public:
explicit http2(QObject *parent = 0);
signals:
public slots:
void httpdown(QNetworkReply* result);
private:
QNetworkAccessManager* m_manager;
};
#endif // HTTP2_H
Now if I call it directly under main.cpp like this:
main.cpp
#include <QtCore/QCoreApplication>
#include "tcpserver.h"
#include "http2.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
http2 h; // --> Working!!
tcpserver mServer;
return a.exec();
}
It works fine. However if I call it inside the tcpserver class like this:
tcpserver.cpp
#include "tcpserver.h"
#include "protocol.h"
#include "http2.h"
QTextStream in(stdin);
tcpserver::tcpserver(QObject *parent) :
QObject(parent)
{
server = new QTcpServer(this);
[ ... Other Server Stuff ... ]
// http2 h; // --> OLD CODE - Not Working :(
http2 *h = new http2(this); // **--> NEW CODE working provided by alexisdm**
}
The signal never happens... What's wrong? I'm new here! :P
Anyway, alexisdm said: "Maybe the http object gets destroyed before the signal can be emitted (if it was allocated on the stack for example)" - Solution accepted, code bellow corrected Read this: QT C++ - QNetworkAccessManager help needed! Class problem (link to answer)
What should I do to avoid that?
Thanks! ;)
Your http or http2 object is destroyed at the end of the constructor, because it is allocated locally.
You should at least allocate it dynamically:
http2 *h = new http2(this);
If you want to reuse it, you can also declare it as a member of tcpserver, instead of using a local variable. If not, you should destroy it somehow when it is not needed anymore.
Edit
If the destruction is done within the slot and/or in response to a signal from h, you should use QObject::deleteLater rather than an immediate delete, because the object might still be referenced somewhere at the time the signal is emitted. So either deleteLater(); in httpdown() or h->deleteLater(); in a tcpserver slot.
To know if you have an answer or an error you could use that code and forward either the data or the error to your tcpserver class with custom signal(s) and slot(s).
The line:
SIGNAL(bool)
really doesn't look right; did you mean
SIGNAL(done(bool))
?
In debug mode, there should be some debug output saying that it could not connect the signals.
Related
I have been new to the Qt environment. I recently started with a QtCreator project for a simple chat application (QMainWindow). I have nearly completed the project but stuck with the SIGNAL/SLOT problem.
Let me explain my problem in brief :
Due to the length of the code I am not able to paste it here.
I have two classes MainWindow and NetworkFile.
The function newServerConn() in NetworkFile connects the signal readyRead() to the slot readFromClient().
The string returned by client is stored in a QString in readFromClient() SLOT.
Problem:
I have to return the QString in the slot to the newServerConn() function and from there to a function in MainWindow class because only then I would be able to print the string to the plainLineEdit widget pointed by the ui object.
Question 1:
How can I return a value from the slot?
Question 2:
Or is there any way I could get a copy of the ui instance in the NetworkFile class so that I could use the widgets from there?
Thanks.
I would just emit the data as a signal and wire up the connection between that new signal and a slot where you add then string to your ui.
A quick self-contained example (which btw. "Due to the length of the code I am not able to paste it here." is just an excuse, you can pretty much always cut down your relevant code)
Header:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTcpServer>
#include <QTcpSocket>
#include <QTextEdit>
class NetworkFile;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow(){}
public slots:
void addText(QString str)
{
edit->append(str);
}
private:
QTextEdit* edit;
NetworkFile* net;
};
class NetworkFile : public QObject
{
Q_OBJECT
public:
NetworkFile(QObject *parent = 0):
QObject(parent)
{
connect(&server, &QTcpServer::newConnection,
this, &NetworkFile::newConnection);
//TODO: check return value
server.listen(QHostAddress::Any,16001);
}
signals:
void dataRead(QString);
public slots:
void newConnection(){
//TODO: wire up socket disconnect with deleteLater, also check for null
QTcpSocket* socket = server.nextPendingConnection();
connect(socket, &QTcpSocket::readyRead,
this, &NetworkFile::dataAvailable);
}
void dataAvailable(){
//HACK: only for brevity, create a connection wrapper that contains the socket in real code
QTcpSocket* source = (QTcpSocket*)sender();
auto bytes = source->readAll();
if(bytes.size())
{
emit dataRead(QString(bytes));
}
}
private:
QTcpServer server;
};
#endif // MAINWINDOW_H
cpp file
#include "mainwindow.h"
#include <QApplication>
MainWindow::MainWindow(QWidget *parent ):
QMainWindow(parent)
{
edit = new QTextEdit(this);
net = new NetworkFile(this);
connect(net, &NetworkFile::dataRead,
this, &MainWindow::addText );
setCentralWidget(edit);
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
As from the documentation:
Signals [...] can never have return types (i.e. use void).
Therefore slot return types are useless when invoked through a signal (even though you can still use them when you invoke a slot directly, ie if it's a member function).
That being said, you can capture ui or even better plainLineEdit by reference or by address in your slot (ie if it's a lambda) and set correctly the string from there.
I Started learning Qt (5.5) a couple of days ago, and I recently got stuck on something when working with the connect function, specifically the SLOT parameter. I'm calling a member function from the same class that the connect function is called in, but when the SLOT function is triggered it acts like it's creating a new class object. It worked initially when I kept everything in the same class, but this problem popped up when I tried implementing a hierarchy. I wrote a short program to demonstrate my problem.
Main.cpp
#include <QApplication>
#include "MainWindow.h"
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
MainWindow QtWindow;
QtWindow.show();
return app.exec();
}
MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QWidget>
#include <QGridLayout>
#include "TopWidget.h"
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QMainWindow *parent = 0);
private:
QWidget *mainWidget;
QGridLayout *mainLayout;
};
#endif // MAINWINDOW_H
MainWindow.cpp
#include "MainWindow.h"
MainWindow::MainWindow(QMainWindow *parent) : QMainWindow(parent){
mainWidget = new QWidget(this);
mainLayout = new QGridLayout(mainWidget);
setCentralWidget(mainWidget);
TopWidget tWidget(this);
mainLayout->addWidget(tWidget.topWidget, 0, 0);
}
TopWidget.h
#ifndef TOPWIDGET_H
#define TOPWIDGET_H
#include <stdlib.h>
#include <QWidget>
#include <QPushButton>
#include <QGridLayout>
#include <QDebug>
#include <QErrorMessage>
class TopWidget : public QWidget
{
Q_OBJECT
public:
TopWidget(QWidget *parent);
QWidget *topWidget;
private:
QGridLayout *wLayout;
QPushButton *Button;
int memVar1;
int memVar2;
private slots:
void testConnect();
//void SlotWithParams(int a, int b);
};
#endif // TOPWIDGET_H
TopWidget.cpp
#include "TopWidget.h"
TopWidget::TopWidget(QWidget *parent) : QWidget(parent){
topWidget = new QWidget(parent);
wLayout = new QGridLayout(topWidget);
memVar1 = 123;
memVar2 = 321;
Button = new QPushButton("Click Me", topWidget);
connect(Button, &QPushButton::clicked, [=](){ TopWidget::testConnect(); });
}
void TopWidget::testConnect(){
qDebug("Button worked");
if(memVar1 != 123 || memVar2 != 321){
qDebug("Linking failed");
}else{
qDebug("Linking success");
}
}
Since I just started with Qt, I don't have a good feel for what's "proper" Qt code, and what I should avoid, so tips in that direction are also appreciated. The following is the qmake file, if that's important.
CONFIG += c++11
CONFIG += debug
CONFIG += console
QT += widgets
QT += testlib
SOURCES += main.cpp
SOURCES += MainWindow.cpp
SOURCES += TopWidget.cpp
HEADERS += MainWindow.h
HEADERS += TopWidget.h
Release:DESTDIR = bin/Release
Release:OBJECTS_DIR = obj/Release
Release:MOC_DIR = extra/Release
Release:RCC_DIR = extra/Release
Release:UI_DIR = extra/Release
Debug:DESTDIR = bin/Debug
Debug:OBJECTS_DIR = obj/Debug
Debug:MOC_DIR = extra/Debug
Debug:RCC_DIR = extra/Debug
Debug:UI_DIR = extra/Debug
When I run the program in debug mode and press the button, it outputs "Button worked" indicating the link to the function was successful, but then outputs "Linking failed" indicating that a new object was created rather than taking the old one. My knowledge of C++ is patchy, since I only pick up what I need to, and I spent hours yesterday trying to fix this, so forgive me if the fix is something ridiculously easy, but I've mentally exhausted myself over this.
The problem comes from this line:
TopWidget tWidget(this);
You are allocating tWidget on the stack, and it gets destroyed just at the end of the MainWindow constructor.
Replace by:
TopWidget * tWidget = new TopWidget(this);
Also, you should replace your connect line by this one
connect(Button, &QPushButton::clicked, this, &TopWidget::testConnect);
It appears that your slot is called even after the TopWidget is destroyed. Qt normally disconnects connections when sender or receiver are destructed, but it's not able to do that when you connect to a lambda.
And finally, you are doing something weird. What is the purpose of your TopWidget class besides just creating another widget and receiving signals on its slot? You never add the TopWidget to any layout, but just its child. TopWidget is never shown, so it should rather derive from QObject only.
I'm working with Qt, using the latest version of Qt Creator on windows 8.1. Once I finished my GUI, I tried to communicate some of my QML elements in C ++ and vice versa, i.e. send data from the two sides.
Example I've tried
I had no idea how to do this, then I have forwarded to read the official documentation and examples from this site, but no one works for me.
Code:
#include <QQmlApplicationEngine>
#include <QDebug>
#include <QObject>
#include <QGuiApplication>
#include <QQuickView>
class MyClass : public QObject
{
Q_OBJECT
public slots:
void cppSlot(const QString &msg) {
qDebug() << "Called the C++ slot with message:" << msg;
}
};
int main(int argc, char *argv[]) {
QGuiApplication app(argc, argv);
QQuickView view(QUrl::fromLocalFile("MyItem.qml"));
QObject *item = view.rootObject();
MyClass myClass;
QObject::connect(item, SIGNAL(qmlSignal(QString)),
&myClass, SLOT(cppSlot(QString)));
view.show();
return app.exec();
}
But i'm getting an error:
C:\Users\Tomi\qml\main.cpp:20: error: cannot convert 'QQuickItem*' to 'QObject*' in initialization
QObject *item = view.rootObject();
What I want
All I need is that when a button is pressed from QML, certain data to C++ are requested and when they are ready to be sent to QML. Is this possible?, could you show me a simplistic and functional example?
Thanks!
The error is because the compiler isn't aware of what a QQuickItem is. You need to include it:
#include <QQuickItem>
QQuickItem is only forward-declared in QQuickView's header, for example, so you can't rely on it to include QQuickItem for you, and shouldn't anyway.
Also, the comment about moc not working with classes defined in main.cpp is wrong; you just need to include main.moc after your class definition for the QObject stuff to work:
#include "main.moc"
I dislike this myth, because it turns short snippets and examples into three files, when they could be contained in just one, which is much more useful on Stack Overflow, bug trackers, etc. :)
Updated-2
I have interesting combination of warnings & errors.
Firstly, when debugging, i get warnings:
can't find linker symbol for virtual table for `QFile' value
found `WebCore::JSDocument::JSDocument(JSC::Structure*, WebCore::JSDOMGlobalObject*, WTF::PassRefPtr<WebCore::Document>)' instead
RTTI symbol not found for class 'WebCore::JSHTMLDocument'
RTTI symbol not found for class 'WebCore::JSHTMLDocument'
RTTI symbol not found for class 'WebCore::JSHTMLDocument'
secondly, i have runtime error:
QIODevice::open: File access not specified
and momently
*** glibc detected *** <path>: double free or corruption (out): 0x081f9d00 ***
Here's the minimal code that causes that errors (i've minimized it):
Files
In result folder created folder "resources" and in it file "vk.cookie" (everything without quotes).
Bug.pro
QT += core gui webkit network xml
TARGET = Bug
TEMPLATE = app
SOURCES += main.cpp \
api_vk.cpp \
printer.cpp
HEADERS += \
api_vk.h \
printer.h
main.cpp
#include <QtGui/QApplication>
#include "api_vk.h"
#include "printer.h"
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
API_VK *apivk = new API_VK;
apivk->authorise();
Printer *printer = new Printer;
QObject::connect(apivk, SIGNAL(authorisationSucceed()), printer, SLOT(printOK()));
QObject::connect(apivk, SIGNAL(authorisationFailed(QString,QString)), printer, SLOT(printFail()));
return a.exec(); }
api_vk.h
#ifndef API_VK_H
#define API_VK_H
#include <QObject>
#include <QTimer>
#include <QUrl>
#include <QtNetwork/QNetworkCookieJar>
class QWebView;
class QString;
class QNetworkReply;
class QXmlInputSource;
class QTimer;
class QNetworkCookie;
class API_VK : public QObject
{
Q_OBJECT
public:
explicit API_VK(QObject *parent = 0);
signals:
void authorisationFailed(QString error, QString error_description);
void authorisationSucceed();
public slots:
void authorise();
protected:
void readCookies();
void writeCookies();
protected slots:
void newAuthoriseRequest();
void processUrl(QUrl url);
private:
static const QString app_id;
static QString access_token;
static qint32 expires_in;
QWebView *messagesPage;
QList<QNetworkCookie> cookies;
QNetworkCookieJar jar;
static bool authorised;
};
#endif
api_vk.cpp
#include "api_vk.h"
#include <QtGui>
#include <QWebView>
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkReply>
#include <QtNetwork/QNetworkCookie>
#include <QtNetwork/QNetworkCookieJar>
#include <QString>
#include <QStringList>
#include <QFile>
#include <QTextStream>
#include <QTimer>
#include <QUrl>
#include <QtXml>
#include <QVariant>
#include <QDateTime>
#include <QDebug>
bool API_VK::authorised = false;
const QString API_VK::app_id = "2783286";
QString API_VK::access_token = "";
int API_VK::expires_in = 0;
// defining class methods
API_VK::API_VK(QObject *parent) :
QObject(parent)
{
}
void API_VK::authorise() {
newAuthoriseRequest(); // 1. going here
}
void API_VK::newAuthoriseRequest() {
// gets new access_token
// 2. going here
messagesPage = new QWebView;
readCookies();
jar.setCookiesFromUrl(cookies, QUrl("http://vk.com"));
messagesPage->page()->networkAccessManager()->setCookieJar(&jar);
QUrl url("http://oauth.vk.com/authorize");
url.addQueryItem("client_id", app_id);
url.addQueryItem("scope", "messages");
url.addQueryItem("redirect_uri","http://api.vk.com/blank.html");
url.addQueryItem("display","page");
url.addQueryItem("response_type","token");
messagesPage->load(QNetworkRequest(url));
connect(messagesPage, SIGNAL(urlChanged(QUrl)), this, SLOT(processUrl(QUrl)));
messagesPage->show();
}
void API_VK::processUrl(QUrl url) { // 3. going here
/* firstly we're here when oath.vk.com redirects us to api.vk.com/login...
* in this case we're exiting at 4.
* secondly, user logs in, and api.vk.com/login redirects us back to oath.vk.com,
* where we get access_token, etc
* and when debugging, we start receiving warnings about "can't find linker symbol" secondly, not firstly
*/
// if (!url.hasQueryItem("access_token"))
// return;
/* I commented previous part because most of you doesn't have VK accounts so you can't go
* to the next part of code */
access_token = url.queryItemValue("access_token");
expires_in = url.queryItemValue("expires_in").toInt();
emit authorisationSucceed();
authorised = true;
cookies = messagesPage->page()->networkAccessManager()->cookieJar()->cookiesForUrl(QUrl("http://vk.com"));
messagesPage->deleteLater();
writeCookies();
}
void API_VK::readCookies() {
QFile file("./resouces/vk.cookie");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
return;
}
QTextStream in(&file);
QByteArray name, value;
while (!in.atEnd()) {
in >> name >> value;
cookies.append(QNetworkCookie(name, value));
}
}
void API_VK::writeCookies() {
QFile file("./resouces/vk.cookie"); // note: this file exists
if (!file.open(QIODevice::Truncate | QIODevice::Text)) { // 5. at this line i receive runtime errors
return;
}
QTextStream out(&file);
for (QList<QNetworkCookie>::const_iterator i = cookies.begin(); i != cookies.end(); ++i) {
out << (*i).name() << ' ' << (*i).value() << '\n';
}
}
printer.h
#ifndef PRINTER_H
#define PRINTER_H
#include <QObject>
#include <QDebug>
struct Printer: public QObject {
Q_OBJECT
public slots:
void printOK() { qDebug() << "OK"; }
void printFail() { qDebug() << "Fail"; }
};
#endif // PRINTER_H
printer.cpp
#include "printer.h"
Here's the full output with memory dump: http://pastebin.com/btVNe4nd
At 5 QtCreator says that app received signal from OS (signal: SIGABRT) and decompiles
Disassembler (__kernel_vsyscall)
0x132414 <+0x0000> int $0x80
0x132416 <+0x0002> ret
And valgrind says:
Analysis of memory <path>
QMetaObject::connectSlotsByName: No matching signal for on_cancelButton_clicked()
"sni-qt/23102" WARN 20:28:53.697 void StatusNotifierItemFactory::connectToSnw() Invalid interface to SNW_SERVICE
** Analysis finished **
** Unknown error **
And one more thing. When I added qDebug() output after each line of code in writeCookies() and launched the program in Run (not debug) mode, it have printed all this output. So, the problem is in some Qt class destructor. (code with qDebug output)
So, why I receive that errors?
Your problem is in the line
messagesPage->page()->networkAccessManager()->setCookieJar(&jar);
The documentation for setCookieJar() states:
Note: QNetworkAccessManager takes ownership of the cookieJar object.
That means that when the QNetworkAccessManager gets destroyed, it will execute the following code:
delete cookieJar;
Note that when this happens:
The stack-allocated jar you passed to setCookieJar is long gone. The network manager was likely corrupting things by accessing a destroyed cookie jar -- it got destroyed as soon as newAuthoriseRequest() had exited. Remember that network manager can run some of its functionality in a separate thread.
A deletion is attempted on an object that was not allocated directly on the heap via new.
Simply change the declaration to
QPointer<QNetworkCookieJar> jar;
and allocate a new cookie jar whenever you create a new QWebView.
The use of QPointer will protect you from trying to use a dangling pointer to a cookie jar that got deleted by QWebView's network access manager. If, by mistake, you try to use it, the pointer will be already reset to zero, and you'll get an instant segfault at the line where you try to dereference the pointer. That's easy to debug.
Your major mistake was stopping to further minimize your self-contained example. If you kept at it, you'd have found the problem in the next 10-15 minutes tops.
This is a minimal example that reproduces your problem:
#include <QtGui/QApplication>
#include <QtWebKit/QWebView>
#include <QtNetwork/QNetworkCookieJar>
#include <QtCore/QList>
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
QWebView * view = new QWebView();
QNetworkCookieJar jar;
QList<QNetworkCookie> cookies;
jar.setCookiesFromUrl(cookies, QUrl("http://google.com"));
view->page()->networkAccessManager()->setCookieJar(&jar);
view->load(QUrl("http://www.google.com"));
view->show();
view->connect(view, SIGNAL(loadFinished(bool)), SLOT(deleteLater()));
a.exec();
}
Homework: read up on QPointer, QScopedPointer, QSharedPointer and QWeakPointer. They are very useful, and in most cases you'll find that use of naked pointers as class members in your code is a bug waiting to happen, with exception of child QObjects (such as QWidgets) whose lifetime matches the lifetime of their parent (i.e. they die only when the parent dies).
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 ®ion, const QRect &rect)
Is the method to read the file like I am doing wrong?
Thanks for Help.
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.