When I start a thread second time my app is freezing
Hello! I'm trying to get title of a YouTube video and display it on main window. This operation is blocking my app second time when I press the button from main window so I created a class that represents a QObject and I moved it to another thread. But the same happens, when I start the thread second time my app is not responding.
My code:
title.h
Code:
#ifndef TITLE_H
#define TITLE_H
#include <QUrl>
#include <QWidget>
#include <QTextDocument>
#include <QFile>
{
Q_OBJECT
public:
~Title();
void searchTile
(const QUrl &);
void htmlGet
(const QUrl &);
signals:
private:
};
#endif // TITLE_H
title.cpp
Code:
#include <title.h>
#include <QScopedPointer>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QRegularExpression>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
}
Title::~Title(){
}
void Title
::searchTile(const QUrl &url
){ if(file.exists() && file.size() != 0){
file.
open(QIODevice::ReadOnly |
QIODevice::Text);
//I have a json file where I save data like title and url of a video file.close();
QJsonDocument d = QJsonDocument::fromJson(val.toUtf8());
QJsonArray list = d.array();
bool checkUrl = this->find(list, "url", url);
if(checkUrl)
emit True("URL is already in download list!"); //this is for showing an error message box
else
this->htmlGet(url);
}
else
this->htmlGet(url);
}
void Title
::htmlGet(const QUrl &url
) { QScopedPointer<QNetworkAccessManager> manager(new QNetworkAccessManager);
QNetworkReply *response = manager->get(QNetworkRequest(url));
qDebug() << "titluuuu";
connect(response, &QNetworkReply::finished, [response, this]{
response->deleteLater();
response->manager()->deleteLater();
if (response->error() != QNetworkReply::NoError) return;
auto const contentType =
response->header(QNetworkRequest::ContentTypeHeader).toString();
static QRegularExpression re("charset=([!-~]+)");
auto const match = re.match(contentType);
if (!match.hasMatch() || 0 != match.captured(1).compare("utf-8", Qt::CaseInsensitive)) {
qWarning() << "Content charsets other than utf-8 are not implemented yet:" << contentType;
return;
}
auto const html
= QString::fromUtf8(response
->readAll
());
QRegularExpression rg("eow-title.*>");
auto const m = rg.match(html);
auto s = m.captured(0);
QRegularExpression n("title=.*");
auto a = n.match(s);
h.setHtml(a.captured(0).split("\"")[1]);
}) && manager.take();
}
bool Title
::find(QJsonArray arr,
QString key,
const QUrl &url
){ //this function is for searching if a url is already in the json file
for(const auto obj : arr){
if(obj.toObject().value(key) == url.toString().split("&")[0])
return true;
}
return false;
}
mainwindow.h
Code:
#include <QWidget>
#include <QThread>
#include <QJsonArray>
{
Q_OBJECT
signals:
private:
int i = 0;
QJsonArray json;
void startWork();
void buttonPushed();
}
mainwindow.cpp
Code:
#include "mainwindow.h"
#include "title.h"
mainWindow
::mainWindow(QWidget *parent
) :{
title = new Title();
title->moveToThread(&th);
connect(title, &Title::True, this, &mainWindow::errorDialog);
connect(&th, &QThread::finished, title, [this] {qDebug() << "finished"; });
connect(this, &mainWindow::titleReady, title, &Title::searchTile);
connect(&th, &QThread::started, this, &mainWindow::startWork);
connect(title, &Title::titleReady, this, &mainWindow::displayTitle);
}
void mainWindow::buttonPushed(){
th.start()
}
void mainWindow::startWork(){
qDebug() << "Started";
emit titleReady
(QUrl(txt
->text
()));
}
void mainWindow
::displayTitle(QString html
){ QJsonObject info;
//I have a QComboBox modified with a QTreeView
QModelIndex index_type
= type_box
->currentView
()->rootIndex
();
QVariant data_type
= type_box
->currentView
()->model
()->data
(index_type
);
info.insert("type", data_type.toString());
QModelIndex index_ext
= type_box
->currentView
()->currentIndex
();
QVariant data_ext
= type_box
->currentView
()->model
()->data
(index_ext
);
info.insert("ext", data_ext.toString());
info.insert("loc", loc_txt->text());
info.insert("title", QJsonValue(html));
info.insert("url", txt->text().split("&")[0]);
json.push_back(info);
QJsonDocument doc(json);
text << doc.toJson();
file.close();
//On main window I have a table widget where I want to display some data in it
item1->setTextAlignment(Qt::AlignCenter);
item2->setTextAlignment(Qt::AlignCenter);
item3->setTextAlignment(Qt::AlignCenter);
tem4->setTextAlignment(Qt::AlignCenter);
table->setItem(i, 0, item);
table->setItem(i, 1, item1);
table->setItem(i, 2, item2);
table->setItem(i, 3, item3);
table->setItem(i, 4, item4);
i++;
title->thread()->quit();
}
How can I solve this? Only the second time I start the thread, the GUI is freezing and I'm wondering why this happens. I also tried displayTitle() like this:
Code:
void mainWindow:: displayTitle (){
qDebug << "test";
title->thread()->quit();
}
but it's the same.
I'm glad if you give me advice for optimization of my code if it's something wrong. Thank you!
Re: When I start a thread second time my app is freezing
QTextDocument is a GUI class which should imo not be used inside a thread. I don't see a reason why a thread is needed here at all. Starting a thread a second time is also imo not supported (and also not needed for your task).
Re: When I start a thread second time my app is freezing
Quote:
Originally Posted by
ChristianEhrlicher
QTextDocument is a GUI class which should imo not be used inside a thread. I don't see a reason why a thread is needed here at all. Starting a thread a second time is also imo not supported (and also not needed for your task).
I agree with you but what can I do to make my gui not freezing because I also tried without another thread and when I clicked the button second time after starting the application always my gui freezed?