8

Well I'm using the following code to get the filename for a file that needs to be stored ..

QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"),"/home/user/MyDocs/",tr("JPG files (*.jpg);;BMP files (*.bmp);;PNG files (*.png)"));

I'm providing the user with a number of options regarding the file format in which the file is to be saved. However, the returned QString only gives me the prefix filename the user have chosen, not the suffix and thus I don't know which file format the user chose. How can I detect such a file format?

BaCaRoZzo
  • 7,502
  • 6
  • 51
  • 82
Ahmad
  • 12,886
  • 30
  • 93
  • 146

3 Answers3

2

Have a look to this discussion. It uses QFileInfo on the string that was entered in a QFileDialog.

BaCaRoZzo
  • 7,502
  • 6
  • 51
  • 82
rubenvb
  • 74,642
  • 33
  • 187
  • 332
  • Sure i'll accept an answer here once I get the answer I need .. Uh, this is not not working too .. QFileInfo will only work if the string passed into it (namely 's' in the example you linked to) contains a filename which has a suffix already .. for example, if the string was "file.ext", the suffix would return "ext" .. My problem is that the filename in the first place does NOT have a suffix in it .. That is, the fileName I get is coming like "/home/user/MyDocs/filename" ... no suffix .. – Ahmad Jul 04 '10 at 15:58
2

You need to use the 5th optional string
I usually do it like this:

#define JPEG_FILES "JPG files (*.jpg)"
#define BMP_FILES "BMP files (*.bmp)"
#define PNG_FILES "PNG files (*.png)"

QString selectedFilter;
QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"),
        "/home/user/MyDocs/",
        JPEG_FILES ";;" BMP_FILES ";;" PNG_FILES, &selectedFilter);

if (fileName.isNull())
  return;
if (selectedFilter == JPEG_FILES) {
  ...
} else if (selectedFilter == BMP_FILES) { 
  ...
} else if (selectedFilter == PNG_FILES) {
  ...
} else {  
    // something strange happened 
}

The compiler takes care to concatenate the literal strings in the argument.

I'm not sure how the returned string interacts with tr(). You'll have to test and find out. probably need to un-translate it.
It could have been nicer if the function would return the index of the selected filter but alas, it does not.

A nicer solution would be to put the filters in a list, create a string from it and then compare to the returned selected filter string to the ones in the list. This would also solve the tr() problem.

Tom Fenech
  • 72,334
  • 12
  • 107
  • 141
shoosh
  • 76,898
  • 55
  • 205
  • 325
  • I just tried this and it didn't work for me .. the returning selectedString is empty .. – Ahmad Jul 04 '10 at 15:53
  • @Ahmad: you say "returning selectedString" are you testing `selectedFilter` from the example here or `filename`? – Evan Teran Jul 04 '10 at 16:31
  • This is the code I was using: QString sf; QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"),"/home/user/MyDocs/",tr("JPG files (*.jpg);;BMP files (*.bmp);;PNG files (*.png)"),&sf); sf does not contain anything after the above two lines have been executed .. its empty .. – Ahmad Jul 04 '10 at 16:37
  • sf is going to have something only if you press "ok" and not cancel the dialog. – shoosh Jul 04 '10 at 23:14
  • As I read these docs (http://doc.qt.nokia.com/4.6/qfiledialog.html#getSaveFileName), it appears that selectedFilter is used to set the default filter shown when the dialog appears. It might be set to the filter the user selected on return from the function, but the docs don't clearly state that it will be. – Caleb Huitt - cjhuitt Jul 06 '10 at 16:50
  • That filtering is ugly - one filter per extension and there is a typo in the call to `getSaveFileName()`. You're not translating your filters so you wouldn't need to un-translate, but you should translate them even if you concatenate them because "files" will be different in other languages. – koan Apr 29 '11 at 15:57
2

The code in the question works in Windows (Qt 4.6.2 and Win XP). fileName contains the selected extension. But you are obviously using something else Windows, so you could try this workaround:

QFileDialog dialog(this, tr("Save as ..."), "/home/user/MyDocs/");
dialog.setAcceptMode(QFileDialog::AcceptSave);
QStringList filters;
filters << "JPG files (*.jpg)" << "BMP files (*.bmp)" << "PNG files (*.png)";
dialog.setNameFilters(filters);
if (dialog.exec() == QDialog::Accepted)
{
    QString selectedFilter = dialog.selectedNameFilter();
    QString fileName = dialog.selectedFiles()[0];
}

That is a slighty modified code from here.

  • This doesn't do the same as the OPs code. it opens QTs file dialog instead of the platforms file dialog. – shoosh Jul 04 '10 at 23:15
  • Thank you for this example. It was the answer for my issue... but I have a little follow up question. The dialog.selectedNameFilter() would return "something (*.ext)", is there a way to just get the .ext ? So I can add it to the file if user did not? – Dariusz Jul 18 '17 at 09:38