C++ 如何使用QtConcurrent::run调用指针作为参数的非类成员函数?
我想使用Qt 4.8 for Embedded Linux调用递归非类成员函数,该函数用于擦除给定文件夹及其所有文件:C++ 如何使用QtConcurrent::run调用指针作为参数的非类成员函数?,c++,qt,pointers,qtconcurrent,C++,Qt,Pointers,Qtconcurrent,我想使用Qt 4.8 for Embedded Linux调用递归非类成员函数,该函数用于擦除给定文件夹及其所有文件: bool removeFiles(const QString & dirName, Interface::ProgressDialog* const poProgressDialog, qint32* const itemDeletedCounter) { bool result = true; try { QDir dir(d
bool removeFiles(const QString & dirName, Interface::ProgressDialog* const poProgressDialog, qint32* const itemDeletedCounter)
{
bool result = true;
try
{
QDir dir(dirName);
if (dir.exists(dirName))
{
Q_FOREACH (QFileInfo info, dir.entryInfoList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst))
{
// if (Q_UNLIKELY(poProgressDialog->wasCanceled()))
// break;
if (info.isDir())
result = removeFiles(info.absoluteFilePath(),poProgressDialog,itemDeletedCounter);
else
{
result = QFile::remove(info.absoluteFilePath());
try
{
poProgressDialog->setValue(*itemDeletedCounter);
}
catch (...)
{
const QString strTemp = QString("Error in removeFiles::poProgressDialog->setValue(*itemDeletedCounter); !!!");
mDebugS(strTemp);
mLog(strTemp);
}
++(*itemDeletedCounter);
// mDebugS(QString("%1").arg(itemDeletedCounter));
}
if (!result)
return result;
}
result = dir.rmdir(dirName);
}
}
catch (...)
{
const QString strTemp = QString("General error in removeFiles");
mDebugS(strTemp);
mLog(strTemp);
}
return result;
}
(忘记try捕捉;它们用于“调试”)
如您所见,此函数接收指向QProgressDialog类的指针以及指向整数的指针作为参数。QProgressDialog类根据删除操作的进度更新接口,整数存储实际删除的文件数
我遇到的问题是,当我使用QtConcurrent::run调用此函数时,我经常会遇到分段错误、对齐陷阱等问题:
concurrentResp = QtConcurrent::run(removeFiles, QString(DEFAULT_RECORD_DIR), poDialog, &itemCounter);
当我直接调用函数时,不会发生同样的情况,因此我知道这可能不是函数或ProgressDialog类的问题。我没有GDB可以更仔细地调试它(多亏了带有Python的GDB)
所以我的问题本质上是:我做错了什么?我应该如何做到这一点而不出错
额外信息:
- 到目前为止,ProgressDialog和integer在.cpp文件中都是全局的,但它们在一段时间前是局部的,问题已经存在
- 有时,seg故障仅在main()末尾的“return”函数中关闭应用程序时出现。然而,就目前而言,甚至在完成清除操作之前,问题就出现了
poProgressDialog->setValue(*itemDeletedCounter)时所做的操作代码>来自使用QtConcurrent::run(…)执行的方法
有一个教程。它基本上涉及使用QFutureWatcher类使用信号和插槽以线程安全的方式监视进程。GUI只能从主线程更新
您正试图从另一个线程更新对话框
试试这个
QMetaObject::invokeMethod(poProgressDialog, "setValue",
Qt::AutoConnection,
Q_ARG(qint32, *itemDeletedCounter));
与此相反:
poProgressDialog->setValue(*itemDeletedCounter);
最好的方法是为这些任务创建相应的QObject
。这样,大多数叛变问题可以通过信号槽机制解决。此外,您还将把UI与实际工作分开(这是始终推荐的)
您应该通过发送信号来报告任务进度,您将连接到相应的UI对象插槽。谢谢您的提示,Marek。我以前确实考虑过这种方法,但是我想让deleter函数不基于类,所以我放弃了这个解决方案。感谢你的提示,Murat,但是你的建议没有解决分段错误问题(尽管这是一个明显的改进)。最后,你的解决方案是正确的。分段故障是由于Qt::AutoConnection
参数的竞争条件而发生的。在将其更改为“排队”并使用记录器之后,我设法删除了一些delete
操作和对QCoreApplication::processEvents()
的不必要调用,这些调用纠正了segv。谢谢