2

我想调用一个递归非类成员函数,用于使用 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-catch;它们是用于“调试”的)

如您所见,该函数接收一个指向类 QProgressDialog 类的指针和一个指向整数的指针作为参数。类 QProgressDialog 类使用删除操作的进度更新界面,整数存储实际删除的文件数。

我遇到的问题是,当我使用 QtConcurrent::run 调用此函数时,我经常遇到分段错误、对齐陷阱等:

concurrentResp = QtConcurrent::run(removeFiles, QString(DEFAULT_RECORD_DIR), poDialog, &itemCounter);

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

所以我的问题本质上是:我做错了什么?我应该如何做到这一点而不会出错?

额外信息:

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

3 回答 3

3

GUI 只能从主线程更新。

您正在尝试从另一个线程更新您的对话框。

尝试这个

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

而不是这个:

poProgressDialog->setValue(*itemDeletedCounter);
于 2015-06-09T18:19:08.287 回答
1

QObject最好的方法是为此类任务创建相应的。这样,信号槽机制可以解决大部分的突变问题。此外,您还将 UI 与实际工作分开(始终推荐)。

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

于 2015-06-09T20:41:52.363 回答
0

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

这里有一个关于如何将 QtConcurrency 与 QProgressDialog 一起使用的教程。它基本上涉及使用 QFutureWatcher 类使用信号和槽以线程安全的方式监视进程。

于 2015-06-09T18:13:49.730 回答