如何用QtConcurrent :: run调用指针作为参数的非类成员函数?

时间:2015-06-09 17:33:31

标签: 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(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;
}

(忘记尝试捕获;它们用于“调试”)

如您所见,此函数接收指向类似QProgressDialog的类的指针以及指向整数的指针作为参数。类似QProgressDialog的类使用删除操作的进度更新接口,整数存储实际删除的文件数。

我遇到的问题是当我使用QtConcurrent :: run:

调用此函数时,我不断得到分段错误,对齐陷阱等
concurrentResp = QtConcurrent::run(removeFiles, QString(DEFAULT_RECORD_DIR), poDialog, &itemCounter);

当我直接调用函数时,同样的情况不会发生,所以我知道它可能不是函数或ProgressDialog类的问题。而且我没有GDB可以访问更仔细的调试(感谢GDB与Python的东西)。

所以我的问题基本上是:我做错了什么?我该如何做到这一点没有错误?

额外信息:

  • 目前,ProgressDialog和整数在.cpp文件中都是全局的,但是它们在前一段时间是本地的,问题已经存在。
  • 有时,只有在main()末尾的“return”函数中关闭应用程序时才会出现seg错误。但就目前而言,即使在完成清除操作之前,问题仍然存在。

3 个答案:

答案 0 :(得分:3)

只能从主线程更新GUI。

您正在尝试从其他主题更新对话框。

试试这个

QMetaObject::invokeMethod(poProgressDialog, "setValue",
                          Qt::AutoConnection,
                          Q_ARG(qint32, *itemDeletedCounter));

而不是:

poProgressDialog->setValue(*itemDeletedCounter);

答案 1 :(得分:1)

最好的方法是为此类任务创建相应的QObject。这样,大多数的变通问题都可以通过信号槽机制来解决。您还将UI与实际工作分开(始终建议使用)。

任务进度应通过发出信号来报告,这些信号将连接到UI对象的各个插槽。

答案 2 :(得分:0)

通常,您不应直接从后台线程修改UI组件,这是您从使用QtConcurrent :: run(...)执行的方法调用poProgressDialog->setValue(*itemDeletedCounter);时所执行的操作。 / p>

有一个教程here on how to use QtConcurrency with QProgressDialog。它主要涉及使用QFutureWatcher类以线程安全的方式使用信号和插槽监视进程。