我有一个多线程程序,可以从网站下载并获取信息,然后获取信息,创建一个对象,然后将其添加到带有图像的GridLayout中。
我需要创建数千个对象然后添加到gridlayout,使用8个线程获取信息,然后使用相同的8个线程创建对象并将它们添加到8个不同的网格中。
程序运行约20秒后,我得到了一个 QThread :: start:无法创建线程(访问代码无效。)错误。 再过几秒钟后,我得到了一些挂起的Runtime C ++错误,并且没有显示消息。 这意味着什么? 令我感到困惑的是,在这一点上,我的线程已经创建,我实际上并没有创建更多线程..虽然他们每个都创建Widget对象,然后我将它们发送到主Gridlayout ..
我检查了我运行的线程数量(QThread:idealThreadCount),它只返回8。
我是多线程从站点下载信息,然后每个记录返回我创建的对象的值,以便放入我的GridLayout。
我在想,因为在那一点上,这些对象都属于单个线程,并且在所有网址都完成之前不会发出(finished()),所以它会占用一些东西并导致这个错误?
我应该尝试MoveToThread并在信息被下载并将新对象添加到我的gridlayout后将所有这些对象发送回主线程吗?
是否有任何理解发生了什么,如果你想让我发布代码?
感谢。
编辑:
刚刚尝试在创建后移动线程,但学到了 QObject :: moveToThread:小部件无法移动到新线程
这是我创建的主题
void checkNewArrivals::createWorkers(QString url, QString category, QString subCategory){
QThread* thread = new QThread;
checkNewArrivalWorker* worker = new checkNewArrivalWorker(url, category, subCategory);
worker->moveToThread(thread);
connect(worker, SIGNAL(error(QString)), this, SLOT(errorString(QString)));
connect(thread, SIGNAL(started()), worker, SLOT(process()));
connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
connect(worker, SIGNAL(result(QString,QString,QString,QString,QString,int, int)), this, SLOT(addItem(QString,QString,QString,QString,QString,int, int)));
connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();
}
这是我的工人类函数,它会发出结果
void checkNewArrivalWorker::getHtml(QString url){
html = QString::fromStdString(Curl->getWebsiteHtml(url.toStdString()));
html = html.mid(html.indexOf("Goods List"));
html = html.mid(0, html.indexOf("footer"));
for (int i = 0; i < html.count("GoodsBox"); i++){
//blah blah blah blah
emit result(idLink, picLink, price, category, subCategory, row, col);
col++;
if (col == 5){
col = 0;
row++;
}
html = html.replace(itemRow, "");
}
}
然后我添加结果来创建一个项目并将其添加到gridlayout
void checkNewArrivals::addToGrid(QGridLayout *layout, QString id, QString picUrl, QString usPrice, int row, int col){
checkNewArrivalItem* item = new checkNewArrivalItem;
if (item->setupItem(id, picUrl, usPrice) == true){
layout->addWidget(item, row, col);
};
}
这些项目工作正常,直到我想的项目超载..不太确定为什么我会收到此错误。
答案 0 :(得分:3)
Qt GUI对象不能存在于主线程以外的任何线程中。需要创建GUI对象并将其添加到主线程中的布局中。您仍然可以从后台线程收集数据,但是您需要将其传递回主线程以进行显示。为此,我建议使用信号,因为信号/插槽连接默认是线程安全的。
编辑:您的新线程看起来应该可以正常工作。但是,我认为您最好保持特定数量的线程运行并将工作委托给它们。首先,创建,启动,停止和销毁线程是一个昂贵的过程。但更重要的是,也许是你可能只是创造了太多的线程。
为了清楚起见,QThread :: idealThreadCount()不是您运行的线程数,而是CPU可以最有效处理的线程数。我猜你有一个超线程的四核CPU,使它成为8。
我认为你最有可能创造了太多的线程。这听起来很像我错误地做到了这一点。