在线程中复制文件以防止冻结应用程序
Copying Files in Threads to prevent a freezed application
我用"安装程序"功能编写了 C /QT应用程序。一切都很好,但是当我在程序中在窗口外单击窗口时,当我的程序中在"复制过程"中时,它以某种方式失去焦点并冻结,直到复制过程结束,然后用a <显示了正常的一切strong> qprogressbar 值为100%。
我像这样复制了:显示了正常的一切strong>
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迭代使用文件(位于我的 lainingInstall()函数)。
由于我的问题,我考虑了为此复制过程创建 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);
}
一切都会好起来的,没有冻结!
,我知道有两种可能解决此问题的方法:
- 使用
QCoreApplication::processEvents()
。正如Docs所说,这不是一个不好的解决方案,并且适合处理长期操作。我认为这对您有用。例如,您可以在复制每个文件(或几个文件)后调用它。 - 使用多线程。这是Devide GUI线程和逻辑线程的绝佳方法。您可以将基里尔的解决方案适应您的目标。
所以我的建议是:如果您需要简单快捷工作解决方案,则第一种方法是适合您的。
如果您想制作设计良好的和更复杂的应用程序,并且您已经准备好编码一些,请使用第二种方法。
- 试图在visual studio上用C++创建一个桌面应用程序
- QT应用程序冻结
- QT应用程序接口冻结
- 如何在不冻结线程/应用程序的情况下减慢方法执行速度
- 在线程中复制文件以防止冻结应用程序
- 在C++中读取文件时应用程序冻结
- 监视C++OpenFrameworks应用程序是否冻结或内存泄漏,然后强制退出并重新启动
- 在这个基于对话框的应用程序中,GUI会在几秒钟后冻结
- 故意在 VB.NET 中冻结应用程序
- 如何在不冻结应用程序 1 的情况下从另一个应用程序 1 执行应用程序 2
- 在 android 上向 JNI 类添加私有字段会冻结应用程序
- Qt 应用程序在从 <QUrl>NetworkAccessManager->get() 回调访问 QList<QLlnkedList* >时冻结
- 为什么这个子网类应用程序冻结了
- Qt事件后,长例程冻结了我的应用程序一段时间
- Win32 API:打开对话框窗口后应用程序冻结
- c++ linux时间冻结应用程序
- wxWidgets应用程序在尝试启动新对话框时冻结
- 当添加一个用于监听网络的新线程时,应用程序冻结
- 更新CListCtrl时MFC应用程序冻结
- Linux应用程序在boost::thread::join时冻结