最近遇到一個需求,即需要將文件夾A裏的圖片一部分移動到文件夾B,另一部分移動到文件夾C。
而需要移動到B和C的圖片的名稱分別保存在兩個txt文本中,每個圖片名稱佔一行。
txt文本如下:
因爲圖片的名稱比較複雜,對着找比較麻煩,因此做一個小工具來自動化完成。只需三步:
1 加載txt文本
2 選擇圖片所在文件夾
3 選擇目標文件夾
4 點擊移動
這樣就完成了一次移動。
效果如下:
思路很簡單,就是讀取txt中的文件名存到列表裏,移動時使用QFile::copy()函數就可以了,如果想剪切過去
可以在複製後加載QFile::remove()函數。
主要代碼:
#include "fileMove.h"
#include <QFileDialog>
#include <QMessageBox>
#include <QProgressDialog>
#include <QTimer>
#include <QEventLoop>
#include "windows.h"
#include "qwaiting.h"
QProgressDialog *progDlg = NULL;
int currentValue = 0;
fileMove::fileMove(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
this->setWindowTitle(QString::fromLocal8Bit("文件移動"));
}
void fileMove::selectText()
{
m_fileList.clear();
QString filePath = QFileDialog::getOpenFileName(this);
if (filePath.isEmpty())
{
QMessageBox::warning(this, QStringLiteral("提示"), QString::fromLocal8Bit("加載失敗!"));
return;
}
QFile file(filePath);
if (file.open(QIODevice::ReadOnly | QIODevice::Text))
{
while (!file.atEnd())
{
QByteArray line = file.readLine();
QString str(line);
m_fileList.append(str);
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
}
file.close();
}
int iSize = m_fileList.size();
QMessageBox::warning(this, QStringLiteral("提示"), QString::fromLocal8Bit("共加載%1個圖片!").arg(iSize));
}
void fileMove::selectSrc()
{
m_Src = QFileDialog::getExistingDirectory(this, QStringLiteral("選擇源目錄"), "/");
//m_Src = QString::fromLocal8Bit(temp.toStdString().c_str());
}
void fileMove::selectDest()
{
m_Dest = QFileDialog::getExistingDirectory(this, QStringLiteral("選擇目標目錄"), "/");
//m_Dest = QString::fromLocal8Bit(temp.toStdString().c_str());
}
void fileMove::startMove()
{
if (m_Dest.isEmpty() || m_Src.isEmpty() || m_fileList.isEmpty())
{
QMessageBox::warning(this, QStringLiteral("提示"), QString::fromLocal8Bit("請先選擇必要參數!"));
return;
}
QString srcFileName;
QString destFileName;
int iSucceed = 0;
/*動圖顯示*/
/*QWaiting *pQwait = new QWaiting(this);
pQwait->show();
for (int i = 0; i < m_fileList.size(); i++)
{
srcFileName = m_Src + "/" + m_fileList.at(i);
destFileName = m_Dest + "/" + m_fileList.at(i);
if (QFile::copy(srcFileName.simplified(), destFileName.simplified()))
{
iSucceed = iSucceed + 1;
}
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
}
pQwait->close();*/
QApplication::setOverrideCursor(Qt::WaitCursor);//設置鼠標爲等待狀態
QProgressDialog progress;
progress.setWindowTitle(QString::fromLocal8Bit("提示"));
progress.setLabelText(QString::fromLocal8Bit("正在移動中..."));
progress.setCancelButtonText(QString::fromLocal8Bit("取消"));
progress.setRange(0, m_fileList.size());//設置範圍
progress.setModal(true);//設置爲模態對話框
progress.show();
for (int i = 0; i < m_fileList.size(); i++)
{
srcFileName = m_Src + "/" + m_fileList.at(i);
destFileName = m_Dest + "/" + m_fileList.at(i);
if (QFile::copy(srcFileName.simplified(), destFileName.simplified()))
{
progress.setValue(i);
iSucceed = iSucceed + 1;
}
//用戶取消的話則中止
if (progress.wasCanceled())
{
break;
}
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
//QCoreApplication::processEvents();
}
QApplication::restoreOverrideCursor();
progress.close();
QMessageBox::warning(this, QStringLiteral("提示"), QString::fromLocal8Bit("共移動%1個文件!").arg(iSucceed));
}
這裏的進度條可以參考我的上一篇博客:
https://blog.csdn.net/qq_24282081/article/details/95782291
這裏遇到一個問題,就是QFile::copy總是失敗,GetLastError()返回值是123.
錯誤是:文件名、目錄名或卷標語法不正確。
找了很久,發現原因是自己拼接的文件名稱後面多了一個"\n"符,因此要用simplified()去掉它。
這就提醒我調試時要細心,看一下字符的每一個字節。
例子下載:
https://download.csdn.net/download/qq_24282081/11344372
最後附上一段同事用python寫的文件移動腳本,注意路徑爲雙反斜槓,且不支持中文
import os, shutil
srcDir = "I:\\trigger0701\\12cheTrigger"
dstDir = "I:\\trigger0701\\12che"
lst = os.listdir(srcDir)
for i in range(0, len(lst)):
fileName = lst[i]
filePath = os.path.join(srcDir, fileName)
if os.path.isdir(filePath):
subLst = os.listdir(filePath)
for j in range(0, len(subLst)):
subfileName = subLst[j]
subfilePath = os.path.join(srcDir, fileName, subfileName)
if os.path.isfile(subfilePath):
newFilePath = os.path.join(dstDir, subfileName)
if os.path.exists(newFilePath):
print(" ")
else:
shutil.move(subfilePath, newFilePath)