How to deal with File Path thruogh slots in User Interface? - c++

I want to build a simple interface to my offline Map Project (C++), how can I replace the Path passed to My Function loadFile("G:/QT/Projects/database/city.osm.pbf"); with Open File so The Function Load File takes the path from the map file I'm choosing ?

void MainWindow::on_action_Open_File_triggered()
{
QString FileName = QFileDialog::getOpenFileName(this,tr("Open File"),"C://","OSM File (*.pbf)" );
//cout << "File Name \t"<< FileName.toStdString() <<endl;
string FilePath2 = FileName.toStdString();
loadFile(FilePath2);
}

Related

Qt: empty content of opened QFile for a .txt file from the project resources

I tried this in my project in mainwindow.cpp:
QString dir = ":/nodesDir/nodesDir/";
QFile baseFile(dir + "allNodeNames.txt");
qDebug() << baseFile.exists(); // true
qDebug() << baseFile.readAll(); // ""
but it is wrong, the content of the file is
plusOperator
Why does it say, that there would be nothing written in the file? Or What did I miss in my code?`
Thanks for answers!
In order to read the file you need to open it for it we use open () and we indicate the way we want it to open. We must also bear in mind that the files stored in the resources are read only, so they can not be modified.
QString dir = ":/nodesDir/nodesDir/";
QFile baseFile(dir + "allNodeNames.txt");
qDebug() << baseFile.exists(); // true
qDebug()<< baseFile.open(QFile::ReadOnly);
qDebug() << baseFile.readAll(); // ""
Output:
true
true
"plusOperator"

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.

using QFileSystemWatcher::Files() to get file count of watched folder example? count is always 0?

I have tried to figure this out over the weekend, but to no avail. I cant seem to find an example using QFileSystemWatcher::Files() directly so i thought i would ask.
I have a program that :
lets the user select a 'source' folder.
press a button to start watching that source folder for new files
there is a signal emitted using 'directoryChanged()' where i try to update the count every time a file is added or removed.
I will profess that my implementation of QfileSystemWatcher is probably not correct. but this code is working and does trigger the signal/slot. but the count is always zero...
from mainwindow.cpp...
the signal:
//connect push buttons
QObject::connect(ui->startButton, SIGNAL(clicked()),
this, SLOT(startButtonClicked()));
//link qfilesystemwatcher with signals and slots
QObject::connect(&hotfolder, SIGNAL(directoryChanged(QString)), this, SLOT(hotfolderChanged()));
the slots:
void MainWindow::startButtonClicked(){
//start the file system watcher using the 'source folder button'
//first, get the resulting text from the source folder button
QString sourceText = ui->sourceBtnLineEdit->text();
ui->statusbar->showMessage(sourceText);
//convert the text from source button to a standard string.
string filePath = sourceText.toStdString();
cout << filePath << endl;
//call method to add source path to qfilesystemwatcher
startWatching(sourceText);
}
void MainWindow::hotfolderChanged(){
int fileCount = filesWatched();
ui->statusbar->showMessage(QString::number(fileCount));
}
from magickWatcher.h
#ifndef MAGICKWATCHER_H
#define MAGICKWATCHER_H
#include <QFileSystemWatcher>
#include <mainwindow.h>
//create the qFileSystemWatcher
QFileSystemWatcher hotfolder;
//add folder to qfilesystemwatcher
//starts watching of folder path
int startWatching( QString folder){
hotfolder.addPath(folder);
cout << "hotfolder created!" << endl;
return 0;
}
//get file list of folder being watched
int filesWatched(){
QStringList watchedList = hotfolder.files();
//report out each line of file list
for (int i = 0; i < watchedList.size(); ++i){
cout << watchedList.at(i).toStdString() << endl;
cout << "is this looping?!!" << endl;
}
return watchedList.count();
}
#endif // MAGICKWATCHER_H
How can i use QFileSystemWatcher to get the file count of the watched folder? I know about QDir and its options but want to specifically know how to use QFileSystemWatcher.
I am still wrapping my head around c++ in general so thank you for any advice or tips as well. I think maybe my problem is how i am implementing QFileSystemWatcher.
Some relevant links i have used:
QFileSystemWatcher working only in main()
http://doc.qt.io/qt-5/qfilesystemwatcher.html#files
First let's have a closer look at docs (bold format is mine):
QFileSystemWatcher examines each path added to it. Files that have been added to the QFileSystemWatcher can be accessed using the files() function, and directories using the directories() function.
So, files() only returns a list of files which you have already added to the watcher using addPath() method, NOT a list of files implicitly being watched by adding a directory.
You can get information about files in the watched directory e.g. by using QDir::entryInfoList with filters applicable in your case. At least QDir::Files and possibly QDir::NoDotAndDotDot would make sense.
//get file list of folder being watched
int filesWatched() {
QString folder = "/path/to/hotfolder/";
QDir monitoredFolder(folder);
QFileInfoList watchedList =
monitoredFolder.entryInfoList(QDir::NoDotAndDotDot | QDir::Files);
QListIterator<QFileInfo> iterator(watchedList);
while (iterator.hasNext())
{
QFileInfo file_info = iterator.next();
qDebug() << "File path:" << file_info.absoluteFilePath();
}
return watchedList.count();
}

Changing current path of a Qt Application

I am using Qt Library and I want to set the current path to the path contained in a QString oldConfigFileName and i am using setCurrent() but setCurrent is returning a false value indicating a failure in changing path.
Code:
QString path = QDir::currentPath();
std::string currentpath = path.toStdString();
std::string configPath = oldConfigFileName.toStdString();
bool res = QDir::setCurrent(oldConfigFileName);
if(res)
{
qDebug() << "Path Changed";
}
else
{
qDebug() << "Path not changed";
}
The problem is the path you are using is a full path to a config file containing the file name. When you try to change the directory to this path the command will fail because oldConfigFileName is a file not an existing folder. A simple way to fix this is to use QFileInfo to remove the filename part from the path then use that as the directory.
QFileInfo fi(oldConfigFileName);
bool res = QDir::setCurrent(fi.path());
if(res)
{
qDebug() << "Path Changed";
}
else
{
qDebug() << "Path not changed";
}
Without knowing an actual content of the oldConfigFileName, one reason for failure may be that the path does not exists. It may be good idea to check existance of the path before calling the QDir::setCurrent() -method.
if(!QDir(oldConfigFileName).exists())
{
qDebug() << "Path does not exists.";
// Path does not exists, if needed, it can be created by
// QDir().mkdir(oldConfigFileName);
}
Another reason for the failure may be that oldConfigFileName does not contain valid path string. To check that, I would change debug logs following way:
if(res)
{
qDebug() << "Path Changed";
}
else
{
qDebug() << "Path not changed. Path string = " << oldConfigFileName;
}

change the name file putting the first line of my file C++ & Qt

I want to change the name of my file but I don't know how to do it. I have a .txt with words in two lines,and like to take the first line same as name of my file .txt.
This is my code:
void ventana1::on_ButtonGuardar_clicked()
{
QDir directory("C:/Users/Jaime/Desktop/interfaz/pacientes");
QString mFilename = directory.filePath("paciente.txt");
QFile sFile(mFilename);
if(sFile.open(QFile::WriteOnly | QFile::Text))
{
QTextStream out(&sFile);
out << ui.lineEdit_2->text()<< "\n"
<< ui.lineEdit->text();
sFile.flush();
sFile.close();
}
}
Simply replace
QString mFilename = directory.filePath("paciente.txt");
by
QString mFilename = directory.filePath(ui.lineEdit_2->text());
if you need to have the content of your lineEdit as your filename.