返回

c++如何停止QThread上的长操作?

发布时间:2022-05-29 09:54:00 272
# golang

我做了一些研究,但我找不到为什么我的解决方案不起作用的答案。但切中要害。

我的应用程序中有QWidget作为单独的对话框。我使用这个QWidget类来收集文件的路径,并使用ZipLib将它们压缩到一个文件中。为了给用户提供一些关于压缩进度的反馈,我添加了QProgressBar,它在压缩过程中更新。但我发现,在某些情况下,当文件太大时,压缩文件会花费很长时间,使我的应用程序在此期间无法响应。所以我的想法是使用QThread将压缩的长操作移动到另一个线程,一切正常,压缩工作正常,进度条更新,但当我想取消压缩操作时出现问题。在我目前的方法中,zipping操作就是不要听我任何中断线程的请求,即使在我关闭对话框后,线程仍在执行zipping操作。我会告诉你我的方法,也许有一些非常琐碎的事情,但我就是不能取消这个压缩操作。

tl;博士版本:我不能用requestInterruption()或者其他任何方式。

这是我的WorkerThread类:

class WorkerThread : public QThread
{
Q_OBJECT

public:
    void setup(std::string zip, std::vector file)
    {
        mZip = zip;
        mFiles = file;
        mActionStopped = false;
    }

    void run() override {
        size_t progressValue = (100 / mFiles.size());

        try
        {
            for (const auto& file : mFiles)
            {
                if (not isInterruptionRequested())
                {
                    Q_EMIT updateTheProgress(progressValue);
                    ZipFile::AddFile(mZip, file);
                }
                else
                {
                    return;
                }
            }
        }
        catch(const std::exception& e)
        {
            Q_EMIT resultReady(false);
        }

        if (not mActionStopped)
        {
            Q_EMIT updateTheProgress(100 - actualProgress); // To set 100%
            Q_EMIT resultReady(true);
        }
    }

    std::string mZip;
    std::vector mFiles;
    size_t actualProgress = 0;
    bool mActionStopped;

Q_SIGNALS:
    void resultReady(bool dupa);
    void updateProgress(int value);

public Q_SLOTS:
    void updateTheProgress(int value)
    {
        actualProgress += value;
        Q_EMIT updateProgress(actualProgress);
    }

    void stopWork()
    {
        mActionStopped = true;
    }
};

在我的 QWidget 类中,我有这样的东西:

workerThread = new WorkerThread();
connect(workerThread, &WorkerThread::resultReady, this, &ZipProjectDialog::zipDone);
connect(workerThread, SIGNAL(updateProgress(int)), progressBar, SLOT(setValue(int)));

connect(btnBox, &QDialogButtonBox::rejected, workerThread, &WorkerThread::requestInterruption);
connect(btnBox, &QDialogButtonBox::rejected, workerThread, &WorkerThread::stopWork);

workerThread->setup(zipFilename, filePathList);
workerThread->start();
connect(workerThread, &WorkerThread::finished, workerThread, &QObject::deleteLater);

我已经关注了QThread文档,但是requestInterruption()仍然不起作用。

如果有人知道如何解决这个问题,我将不胜感激。

 

特别声明:以上内容(图片及文字)均为互联网收集或者用户上传发布,本站仅提供信息存储服务!如有侵权或有涉及法律问题请联系我们。
举报
评论区(1)
按点赞数排序
用户头像