使用QFutureWatcher时,函数未运行QtConcurrent :: run()

时间:2015-09-17 13:10:11

标签: multithreading qt qtconcurrent qfuture

我想调用一个函数来从QtConcurrent::run()调用的并行线程中删除系统中的文件和文件夹(Qt for Embedded Linux 4.8)。仅使用QFuture<bool>QFuture::waitForFinished()来获取结果(我需要在操作后立即运行一些代码),我才能使系统正常工作。

但是我想在QProgressBar派生类中显示正在进行的操作结果,其中setValue(int)通过删除函数内部的信号和插槽机制调用,以及我用上面的方法获得的内容操作未完成时是一个冻结的主线程,这是不允许的。

所以我虽然使用QFutureWatcher<bool>并将其finished()信号连接到另一个包含剩余代码的插槽,该代码将在删除操作完成后运行。

我面临的问题是,当我这样做时,删除功能根本不是由QtConcurrent::run()运行的!我检查了打印消息到终端。发生的一切都是QFutureWatcher调用其finished()信号而不执行删除文件功能(如果我使用QFutureWatcher::waitForFinished()也会发生这种情况)。

这是Qt的一些错误吗?

关于代码,它与Qt Assistant完全一样:全局创建QFuture和QFutureWatcher,将finished()信号与插槽连接,将QtConcurrent::run()setFuture()连接到将来。没什么特别的。

任何帮助表示感谢。

修改

根据库巴的要求,以下是代码的相关部分:

//Declared globally in the .cpp
QFuture<bool> future;
QFutureWatcher<bool> watcher;

//
void SelectRecordToDeleteWidget::slotDeleteRecordStateMachine()
{
    switch (deleteRecordStateMachine)
    {
        case PrepareToDelete:
        {
            //...
            connect(&watcher,SIGNAL(finished()),this,SLOT(slotDeleteRecordStateMachine()),Qt::UniqueConnection);
            //...
        }
            break;

        case DeleteRecords:
        {
            //...
            future = QtConcurrent::run(removeFiles, QString(DEFAULT_RECORD_DIR) + "/" + recordList.at(aaa).second.second, poProgressDialog, &itemCounter);

            watcher.setFuture(future);

            qApp->processEvents();
            //...
        }
            break;

        case FinishDelete:
        {
            //Run code after deleting files
        }
            break;

        default:
            break;
    }
}

这是使用QFuture和QFutureWatcher的所有代码。 removeFiles如下(不要忘记它在没有QFutureWatcher的情况下运行良好):

bool removeFiles(const QString dirName, Interface::ProgressDialog* const poProgressDialog, qint32* const itemDeletedCounter)
{
    bool result = true;

    try
    {
        QDir dir(dirName);

        if (dir.exists())
        {
            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);

                    if (!result)
                        return result;
                }
                else
                {
                    result = QFile::remove(info.absoluteFilePath());

                    if (!result)
                        return result;

                    if (!QMetaObject::invokeMethod(poProgressDialog, "setValue",
                                              Qt::BlockingQueuedConnection,
                                              Q_ARG(qint32, *itemDeletedCounter)))
                    {
                        mDebugS(QString("removeFiles: %1QMetaObject::invokeMethod(poProgressDialog, \"setValue\"... failed!"));
                    }

                    ++(*itemDeletedCounter);

//                    mDebugS(QString("removeFiles: %1").arg(*itemDeletedCounter));
                }
            }

            result = dir.rmdir(dirName);
        }
    }
    catch (...)
    {
        const QString strTemp = QString("An error in a call to removeFiles");

        mDebugS(strTemp);
        mLog(strTemp);
    }

    return result;
}

0 个答案:

没有答案