Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何使用QtConcurrent::run调用指针作为参数的非类成员函数?_C++_Qt_Pointers_Qtconcurrent - Fatal编程技术网

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

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

我想使用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;
}
(忘记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”函数中关闭应用程序时出现。然而,就目前而言,甚至在完成清除操作之前,问题就出现了

一般来说,您不应该直接从后台线程修改UI组件,这是您在调用
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。谢谢