c++ - 在线程中复制文件以防止卡住应用程序

标签 c++ multithreading qt copy freeze

我编写了一个具有“安装程序”功能的 C++/QT 应用程序。一切正常,但是当我在程序处于“复制过程”时单击窗口外时,它以某种方式失去焦点并卡住直到复制过程结束,然后一切都正常显示 < strong>QProgressBar 值为 100%。

我是这样复制的:

void Installer_C::copy(QString aSrcPath, QString aDstPath)
{    
  //handles
  hSrc = CreateFileW(..); //source file
  hDst = CreateFileW(..); //destination
  //copy
  ReadFile(...);
  LockFile(...);
  WriteFile(...); //->returnes bytesWritten
  UnlockFile(...);
  updateQProgressBar(bytesWritten); //updates progressbar in my application
  CloseHandle(...);
}

此函数在 foreach 循环中调用,循环遍历带有文件的 QStringList(位于我的 launchInstall() 函数中)。
由于我的问题,我考虑为这个复制过程创建Threads。是为每个 Installer_C::copy() 调用创建一个新线程更有效,还是只创建一个线程来调用 launchInstall() 函数(我认为不会有太大帮助)。
或者更好的问题:它甚至可以解决我的应用程序卡住问题吗?我应该怎么做才能让 ProgressBar 仍然从这个线程更新?

最佳答案

我认为,解决您的问题的最佳方法是创建一个附加线程来复制进程。您可以使用 QThread(Qt 文档:QThread)类创建一个线程,该线程将复制文件。主线程将执行您的 GUI,它将在文件复制期间可用。

复制线程的小例子:

class CopyThread : public QThread
{
    Q_OBJECT
private:
    QStringList oldfiles_;
    QStringList newfiles_;
public:
    CopyThread(const QStringList& oldfiles,
               const QStringList& newfiles,
               QObject * parent = 0)
        : QThread(parent)
        , oldfiles_(oldfiles)
        , newfiles_(newfiles)
    {}

    void run() Q_DECL_OVERRIDE 
    {
        int min = qMin(oldfiles_.count(), newFiles.count());
        for(int i=0; i<min; ++i)
        {
            copyFile(oldfiles_.at(i), newFiles_.at(i));
            emit signalCopyFile(oldfiles_.at(i), newFiles_.at(i));
        }
    }
signals:
    void signalCopyFile(const QString&, const QString&);
private:
    void copyFile(QString aSrcPath, QString aDstPath)
    {
        QFile::copy(aSrcPath, aDstPath);
    }
};

当然,您必须在您的小部件上为 signalCopyFile(const QString&, const QString&) 实现插槽并建立连接。一小段代码(例如)启动复制线程并建立连接:

QStringList oldFiles;
oldfiles.append("C:/1.txt");
QStringList newFiles;
newFiles.append("C:/2.txt");
yourProgressBar.setMaximum(oldFiles.count());
yourProgressBar.setMinimum(0);
yourProgressBar.setValue(0);
CopyThread *copyThread = new CopyThread(oldFiles, newFiles, this);
connect(copyThread, &CopyThread::finished, copyThread, &QObject::deleteLater);
connect(copyThread, &CopyThread::signalCopyFile, youWidget, &YouWidget::yourSlot);
copyThread->start();

yourSlot 中,您可以更新 QProgressBar 的值:

void yourSlot(const QString& oldFile, const QString& newFile)
{
    // your actions when one file was copied
    yourProgressBar->setValue(yourProgressBar.value() + 1);
}

没有卡住,一切都会好起来的!

关于c++ - 在线程中复制文件以防止卡住应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38047810/

相关文章:

python没有获取环境变量,但它是在mac os上设置的

c++ - 如何在我的 Opensuse 中安装 qt 演示/示例?

c++ - Qt5 VS 2010 - QtSerialPort 库失败

c++ - 在 VC++ 2019 中释放 std::vector 的内存

c++ - 我怎样才能初始化一个对象

c# - ThreadPool.SetMinThreads 在 IIS 托管应用程序中不起作用

javascript web workers多线程字符串搜索比单线程慢?

c++ - VIM:执行脚本并显示复杂文件类型的结果

c++ - 允许重新申报?

multithreading - 线程之间共享哪些资源?