How to treat a QString as a file location and get its directory - c++

I gather a list of files into a QStringList from a Qt GUI. Each of these files is a .txt file, with a corresponding video file in same_folder_as_txt/videos/.
Is there an easy way to manipulate QString objects as file paths? For example, given C:/some/path/foo.txt , I want to retrieve C:/some/path/videos/foo.avi

Given your path as a QString s
info = QFileInfo(s)
// Get the name of the file without the extension
base_name = info.baseName()
// Add a ".avi" extension
video_file = QStringList((base_name, "avi")).join(".")
// Get the directory
dir_name = info.path()
// Construct the path to the video file
video_path = QStringList((dir_name, QString("videos"), video_file).join("/")

You can convert them each to QDir, perform your modifications as a path, and then use absolutePath() to get the QString back.

Related

PowerBI: Check if the folder/directory we are loading to exists or not using Power Query

I am a newbie in PowerBi and currently working on a POC where I need to load data from a folder or directory. Before this load, I need to check if
1) the respective folder exists
2) the file under the folder is with.csv extension.
Ex. Let suppose we have a file '/MyDoc2004/myAction.csv'.
Here first we need to check if MyDoc2004 exists and then if myAction file is with.csv extension.
Is there any way we can do this using Power Query?
1. Check if the folder exists
You can apply Folder.Contents function with the absolute path of the folder, and handle the error returned when the folder does not exist with try ... otherwise ... syntax.
let
absoluteFolderPath = "C:/folder/that/may/not/exist",
folderContentsOrError = Folder.Contents(absoluteFolderPath),
alternativeResult = """" & absoluteFolderPath & """ is not a valid folder path",
result = try folderContentsOrError otherwise alternativeResult
in
result
2. Check if the file is with .csv extension
I'm not sure what output you are expecting.
Here is a way to get the content of the file by full path including ".csv", or return an alternative result if not found.
let
absoluteFilePath = "C:/the/path/myAction.csv",
fileContentsOrError = File.Contents(absoluteFilePath),
alternativeResult = """" & absoluteFilePath & """ is not a valid file path",
result = try fileContentsOrError otherwise alternativeResult
in
result
If this is not what you are looking for, please update the question with the expected output.
Hope it helps.

Rename files with same name but differing extensions

If a tickbox is clicked on my application, all files in a specified folder having the same pre-dot name, (eg. TESTCRC32.xxx) will be re-named. If the filename is something else, (eg. Pic.jpg) this file will not be renamed.
How can I go about this? I was thinking a for loop...
void SecondDlg::OnTickBox()
{
// Add code here...
CString oldFile = myPath.Left(myPath.ReverseFind(_T('.')));
rename(oldFile, newFile);
}
You are doing wrong. lets take an example, Suppose myPath is having path "C:\abc\xyz.bmp"
After this line:
CString oldFile = myPath.Left(myPath.ReverseFind(_T('.')));
Now:
oldFile = "C:\\abc\\xyz"; // extension removed
At last you are calling rename
rename(oldFile, newFile); //you can use myPath instead of oldFile
As oldFile = "C:\abc\xyz"; and which is not the correct path, so it is not renamimg the file.
you should pass full path of the file(C:\abc\xyz.bmp).

Setting the name of a text file to a variable in qt

I'm exporting data to a text file in qt every time a run a code. With my current code that file is overwritten each time. My question is how can I set the title to be a variable eg pulse_freq, this way new files will be created based on my variable values. I just can't get the syntax right.
Is there a way to put my files in a folder in the same directory as my build files? I need my code to be cross platform and if I use the full path name it's apparently incompatible with any non-windows OS. If I just name the files there'd be too much clutter in the folder. Relevant code is below:
// Export to data file
QString newname = QString::number(variables.nr_pulses);
QString filename = "C:/Users/BIC User/Documents/BIC Placement Documents/QT_data/Data.txt";
QFile file( filename );
You can just use something along lines:
QString s1 = "something";
QString s2 = " else";
QString s3 = s1 + s2;
QString concatenation with overloaded operator+ works like charm.
And about referencing folder you're in, instead of hardcoding its path, use QDir::currentPath()
Thus, your filename creation should look like the following:
QString folder = QDir::currentPath();
QString file = QString::number(variables.nr_pulses); //or whatever else you want it to be
QString extension = ".txt" // or whatever extension you want it to be
QString full_filename = folder + file + extension;
In order not to mess with appending string after the extension, just separate it into another QString and concatenate those 3 elements as above (folder + file + extension).

How to get a complete path from one with wildcards?

I have a path like:
C:\path\to\my*file\
and I would like to get the corresponding full path (if it exists):
C:\path\to\my1file\
I tried with this Qt code, but the result is the same path I had at the beginning:
QStringList filters;
filters << "C:/path/to/my*file/";
QDir dir;
dir.setNameFilters(filters);
QStringList dirs = dir.entryList(filters);
_path = dirs.at(0); // get the first path only
Shouldn't I get all the files/directories that get through the filter?
Why is _path equal to "C:/path/to/my*file/"?
Is it possible to do the same thing with C++98/STL only? (In this project I cannot use Boost/C++11).
Use filters to filter files/folders, and set the path in QDir object:
QStringList filters;
filters << "my*file";
QDir dir("C:/path/to/");
QStringList dirs = dir.entryList(filters);
if (dirs.size() > 0)
{
qDebug() << dirs.at(0);
}
Expanding file names is called globbing. On Windows the functions FindFirstFile() / FindNextFile() do globbing.

Specify default extension in QFileDialog::getSaveFileName

Is there an equivalent of the lpstrDefExt member of OPENFILENAME struct used in the Win32 function GetSaveFileName?
Here's description from MSDN:
LPCTSTR lpstrDefExt
The default extension. GetOpenFileName and GetSaveFileName append this
extension to the file name if the user fails to type an extension.
This string can be any length, but only the first three characters are
appended. The string should not contain a period (.). If this member
is NULL and the user fails to type an extension, no extension is
appended.
So if lpstrDefExt is set to "txt" and the user types "myfile" instead of "myfile.txt", the function still returns "myfile.txt".
Edit: If this does not work for you look at the answer below by #user52366
Qt will extract the default extension from the "selectedFilter" parameter, if specified.
Here is an example:
QString filter = "Worksheet Files (*.abd)";
QString filePath = QFileDialog::getSaveFileName(GetQtMainFrame(), tr("Save Worksheet"), defaultDir, filter, &filter);
When using this code the getSaveFileName() method will automatically add the ".abd" file extension if the user didn't specify one in the dialog. You can see the implementation of this in the qt_win_get_save_file_name() inside the "qfiledialog_win.cpp" Qt source file.
Unfortunately this doesn't work for the getOpenFileName() method.
As mentioned in the comment above, this does not work, at least for me.
In the end I skipped the static method and used the following:
QFileDialog dialog(this, "Save someting", QString(),
"Comma-separated file (*.csv)");
dialog.setDefaultSuffix(".csv");
dialog.setAcceptMode(QFileDialog::AcceptSave);
if (dialog.exec()) {
const auto fn = dialog.selectedFiles().front();
// a QStringList is returned but it always contains a single file
// do something using filename 'fn' ...
}
Not sure what exactly LPCTSTR lpstrDefExt is trying to do but Qt documentation gives the following example
QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"),
"/home/jana/untitled.png",
tr("Images (*.png *.xpm *.jpg)"));
http://doc.qt.io/qt-5/qfiledialog.html#getSaveFileName