Qt - copy a file from one directory to another - c++

I am using QT, I am not able to find out how to copy a file from one directory to another? How can I achieve this?

You can use QFile which provides a copy method.
QFile::copy("/path/file", "/path/copy-of-file");

If destination file exist, QFile::copy will not work. The solution is to verify if destination file exist, then delete it:
if (QFile::exists("/path/copy-of-file"))
{
QFile::remove("/path/copy-of-file");
}
QFile::copy("/path/file", "/path/copy-of-file");

The following code works in windows for specified reasons. This will set the path to specified drive and create the folder you created in Under UI Mode. Then copies the file from source to destination. Here the source is installation directory contained some files which are used for plotting curves. this file are not modified by users. They just use it.
hence this works as copy from installation directory to specified folder
void MainWindow::on_pushButton_2_clicked()
{
QString str5 = ui->lineEdit->text();
QString src = "."; QString setpath;
QDir dir(src);
if(!dir.exists()){
return;
}
dir.cdUp();
//dir.cdUp();
setpath = "E://";
dir.setPath(setpath);
QString dst_path = str5 + QDir::separator() ;
dir.mkpath(dst_path);
dir.cd(dst_path);
QString filename = "gnu.plt";
QString filename2 = "Load curve.plt";
QString filename3 = "tube temp.plt";
QFile file(filename);
QFile file1(filename2);
QFile file2(filename3);
file.copy(src+QDir::separator()+filename, setpath+QDir::separator()+str5+QDir::separator()+filename);
file1.copy(src+QDir::separator()+filename2, setpath+QDir::separator()+str5+QDir::separator()+filename2);
file2.copy(src+QDir::separator()+filename3, setpath+QDir::separator()+str5+QDir::separator()+filename3);
}

Related

How to separate file name and file path in QT

I've got a path like "C:\Users\Rick\html.txt". So how can I separate the file path and filename? My main aim is to extract the file path and obtain "C:\Users\Rick" for a text editor app. I'm receiving the path as a QString from QFileDialog::getSaveFileName(). So I want to use that path as the window title and next path if the user tries to open a file
if(!checkTextField()){
QMessageBox::StandardButton reply = QMessageBox::question(this,this->appName,this->document_modified);
if(reply == QMessageBox::Yes){
QString filename = QFileDialog::getSaveFileName(this,"Save the File",QDir::homePath(),this->textFilter);
QFile file(filename);
if(!file.open(QIODevice::ReadWrite | QIODevice::Text))
return;
QTextStream out(&file);
QString text = ui->textEdit->toPlainText();
out << text;
file.flush();
file.close();
}
}```
You should look in to QFileInfo
QFileInfo info("c:/my/path/to/dir/file.txt");
info1.absoluteFilePath(); // returns "c:/my/path/to/dir/file.txt"
info1.dir(); // returns "c:/my/path/to/dir"
info1.filename(); // returns "file.txt"

C++ Transfer Files From Qt to External USB Drive

I am new in Qt and I need help in transferring all files from a specific path of the local machine to an external USB Drive.
Copying a single file
You can use QFile::copy.
QFile::copy(srcPath, dstPath);
Note: this function doesn't overwrite files, so you must delete previous files if they exist:
if (QFile::exist(dstPath)) QFile::remove(dstPath);
If you need to show an user interface to get the source and destination paths, you can use QFileDialog's methods to do that. Example:
bool copyFiles() {
const QString srcPath = QFileDialog::getOpenFileName(this, "Source file", "",
"All files (*.*)");
if (srcPath.isNull()) return false; // QFileDialog dialogs return null if user canceled
const QString dstPath = QFileDialog::getSaveFileName(this, "Destination file", "",
"All files (*.*)"); // it asks the user for overwriting existing files
if (dstPath.isNull()) return false;
if (QFile::exist(dstPath))
if (!QFile::remove(dstPath)) return false; // couldn't delete file
// probably write-protected or insufficient privileges
return QFile::copy(srcPath, dstPath);
}
Copying the whole content of a directory
I'm extending the answer to the case srcPath is a directory. It must be done manually and recursively. Here is the code to do it, without error checking for simplicity. You must be in charge of choosing the right method (take a look at QFileInfo::isFile for some ideas.
void recursiveCopy(const QString& srcPath, const QString& dstPath) {
QDir().mkpath(dstPath); // be sure path exists
const QDir srcDir(srcPath);
Q_FOREACH (const auto& dirName, srcDir.entryList(QStringList(), QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name)) {
recursiveCopy(srcPath + "/" + dirName, dstPath + "/" + dirName);
}
Q_FOREACH (const auto& fileName, srcDir.entryList(QStringList(), QDir::Files, QDir::Name)) {
QFile::copy(srcPath + "/" + fileName, dstPath + "/" + fileName);
}
}
If you need to ask for the directory, you can use QFileDialog::getExistingDirectory.
Final remarks
Both methods assume srcPath exists. If you used the QFileDialog methods it is highly probable that it exists (highly probable because it is not an atomic operation and the directory or file may be deleted or renamed between the dialog and the copy operation, but this is a different issue).
I have solved the problem with the QStorageInfo::mountedVolumes() which return the list of the devices that are connected to the Machine. But all of them won't have a name except the Pendrive or HDD. So (!(storage.name()).isEmpty())) it will return the path to only those devices.
QString location;
QString path1= "/Report/1.txt";
QString locationoffolder="/Report";
foreach (const QStorageInfo &storage, QStorageInfo::mountedVolumes()) {
if (storage.isValid() && storage.isReady() && (!(storage.name()).isEmpty())) {
if (!storage.isReadOnly()) {
qDebug() << "path:" << storage.rootPath();
//WILL CREATE A FILE IN A BUILD FOLDER
location = storage.rootPath();
QString srcPath = "writable.txt";
//PATH OF THE FOLDER IN PENDRIVE
QString destPath = location+path1;
QString folderdir = location+locationoffolder;
//IF FOLDER IS NOT IN PENDRIVE THEN IT WILL CREATE A FOLDER NAME REPORT
QDir dir(folderdir);
if(!dir.exists()){
dir.mkpath(".");
}
qDebug() << "Usbpath:" <<destPath;
if (QFile::exists(destPath)) QFile::remove(destPath);
QFile::copy(srcPath,destPath);
qDebug("copied");
}
}
}
I had to create a folder as well as in USB because of my requirements and I have given a static name for the files. Then I just copied the data from file of the local machine to the file which I have created in USB with the help of QFile::copy(srcPath, dstPath). I hope it will help someone.

Qt - How to copy file with QFile::copy using QFileDialog?

QString filename = QFileDialog::getOpenFileName(this,tr("Pdf files"), "C:/", "books(*.pdf)");
I want to get the selected file from QFileDialog and copy it to my desktop. Can I use something like this?
QFile::copy(filename,"desktop");
You need to get the path to the desktop using QStandardPaths, and then use that path in your call to QFile::copy.
Assuming you want to preserve the file name while copying, your code will look something like this:
QString filePath = QFileDialog::getOpenFileName(this ,
QObject::tr("Pdf files"),
"C:/", "books(*.pdf)");
QFileInfo fi(filePath);
QString fileName= fi.fileName();
QString desktopPath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
QString destinationPath= desktopPath+QDir::separator()+fileName;
if(QFile::copy(filePath, destinationPath))
qDebug() << "success";
else
qDebug() << "failed";

Select file/directory path using QFileDialog in Qt

I want to show a dialog to user to select a file/directory in qt.
I tried using QFileDialog methods to get it, but either i can set file mode or directory mode, could not able to set both. if I set QFileDialog::Directory as file mode it shows directories as well as files, but could not able to select any file.
Here is the example code I tried...
QFileDialog dialog;
dialog.setFileMode(QFileDialog::Directory);
dialog.setOption(QFileDialog::DontUseNativeDialog,true);
dialog.setOption(QFileDialog::DontResolveSymlinks);
dialog.setNameFilterDetailsVisible(true);
dialog.setViewMode(QFileDialog::Detail);
QStringList filters;
filters <<"Any files (*)"
<<"Text files (*.txt)"
<<"Image files (*.png *.xpm *.jpg)";
dialog.setOption(QFileDialog::HideNameFilterDetails,false);
dialog.setNameFilters(filters);
int res = dialog.exec();
QDir directory;
QString file = directory.currentPath();
if (res)
{
directory = dialog.selectedFiles()[0];
QStringList filesList = directory.entryList(QDir::Files);
QString fileName;
foreach(fileName, filesList)
{
qDebug() << "FileName " << fileName;
}
}
Is there is any way get the path of selected file or directory ?

Can't create a .db file in assets folder

I am trying to create a quizz.db file in assets folder by first creating a temporary quizz.db in data folder and then creating tables inside it and then copy it to the assets folder. By debugging the code it shows that the folder is created. But I can't find it in assets folder. Here is the code,
#include <bb/cascades/Application>
#include <bb/cascades/QmlDocument>
#include <bb/cascades/AbstractPane>
#include <bb/data/SqlDataAccess>
using namespace bb::cascades;
using namespace bb::data;
SQLTest::SQLTest(bb::cascades::Application *app): QObject(app)
{
const QString fileName = QString("quizz.db");
QString dataFolder = QDir::homePath();
QString newFileName = dataFolder + "/" + fileName;
QTemporaryFile file(newFileName);
// Open the file that was created
if (file.open())
{
// Create an SqlDataAccess object
SqlDataAccess sda(newFileName);
// Create a table called Employee in the database file
sda.execute("CREATE TABLE Employee( firstName VARCHAR(50),lastName VARCHAR(50), salary INT);");
// Insert employee records into the table
sda.execute("INSERT INTO Employee (firstName, lastName, salary) VALUES (\"Mike\", \"Chepesky\", 42000);");
sda.execute("INSERT INTO Employee (firstName, lastName, salary) VALUES (\"Westlee\", \"Barichak\", 55000);");
sda.execute("INSERT INTO Employee (firstName, lastName, salary) VALUES (\"Ian\", \"Dundas\", 47000);");
if(sda.hasError())
{
}
else
copyFileToAssetsFolder("quizz.db");
}
}
void SQLTest::copyFileToAssetsFolder(const QString fileName)
{
QString appFolder(QDir::homePath());
appFolder.chop(4);
QString originalFileName = appFolder + "app/native/assets/" + fileName;
QFile newFile(originalFileName);
// If I enable this `if` condition the code satisfies it and removes the quizz.db file and then it satisfies the next `if` condition and successfully copies the quizz.db file from `data` folder to `assets` folder.
/*if(newFile.exists())
QDir().remove(originalFileName);*/
// this `if` condition is not satisfied. Which should mean the quizz.db file has been created on assets folder.
if (!newFile.exists())
{
// If the file is not already in the assets folder, we copy it from the
// data folder (read and write) to the assets folder (read only).
QString dataFolder = QDir::homePath();
QString newFileName = dataFolder + "/" + fileName;
QFile originalFile(newFileName);
if (originalFile.exists())
{
// Create sub folders if any creates the SQL folder for a file path like e.g. sql/quotesdb
QFileInfo fileInfo(originalFileName);
QDir().mkpath (fileInfo.dir().path());
if(!originalFile.copy(originalFileName)) {
qDebug() << "Failed to copy file to path: " << originalFileName;
}
} else {
qDebug() << "Failed to copy file data base file does not exists.";
}
}
// mSourceInDataFolder = newFileName;
}
If I enable the commented if condition of copyFileToAssetsFolder function it removes already created quizz.db file in assets folder (which Im unable to find) and goes inside the next if condition and copies the quizz.db created on the data folder to assets fodler. But in any case I can't find the quizz.db in assets folder. I really need help with this quickly. Thanks.
Files in asset can not be modified
It seems its not possible to modify assets folder mentioned in here Now I am creating my db file in the data folder as it is writable.