How to get Qt icon (QIcon) given a file extension - qt

I am developing an application that needs to display icons associated with different file types.
Eg for .doc extensions, i need it to be able to display the Microsoft Word icon.
QUESTION:
How can I somehow get a QIcon from the system using QT sdk
Thanks.

Use the QtGui.QFileIconProvider class.

Since Qt5, use QMimeDatabase for that:
QMimeDatabase mime_database;
QIcon icon_for_filename(const QString &filename)
{
QIcon icon;
QList<QMimeType> mime_types = mime_database.mimeTypesForFileName(filename);
for (int i=0; i < mime_types.count() && icon.isNull(); i++)
icon = QIcon::fromTheme(mime_types[i].iconName());
if (icon.isNull())
return QApplication::style()->standardIcon(QStyle::SP_FileIcon);
else
return icon;
}

If you don't have special requirement, QMimeDatabase is a better choice for your need. I recommend you try #nitro2005's answer. You can still do this work by your hand by using QFileIconProvider.
If you want to do this work by your hand but you can't use QMimeDatabase for some reason, there is a solution works for Linux/X11. You can use QFileInfo(const QString &file) to get the file's suffix / extension (It's not necessary about the QString you passed to the QFileInfo constructor is a exist path or not), and then get the MIME type form that suffix, at last you can get the QIcon by using QIcon::fromTheme and it's done.
For example, the following code will check if file's suffix is ".bin", if is, the give it a icon from the system theme with "application-x-executable" MIME type. In fact it's just maintaining a MIME database by your self.
QString fileName("example.bin");
QFileInfo fi(fileName);
if (fi.suffix().compare(QString("bin")) == 0) {
item->setIcon(QIcon::fromTheme("application-x-executable",
provider.icon(QFileIconProvider::File)));
}
To get the MIME type string reference for your "MIME database", please checkout the freedesktop icon naming spec.

Related

Pre-compile QML files under Qt Quick Controls

I am importing 2 QML files that come with Qt Controls - ScrollBar.qml and Button.qml in my project. I pre-compile all .qml files that I wrote to reduce application launch time. Is there a way to pre-compile these 2 QML files that come as part of the package?
I tried to remove these files from the qml/QtQuick/Controls/ path and placed them in the same folder as my .qml files but it still failed to load. When I reference ScrollBar in my code, it always tries to load ScrollBar.qml from qml/QtQuick/Controls/ path.
Does any one know if it is possible to pre-compile these QMLs at all? If yes, has any one successfully done it?
Appreciate any help. Thank you.
I'm assuming that you're referring to the Qt Quick Compiler as pre-compiling. The simplest way would just be to build the entire Qt Quick Controls module with the Qt Quick Compiler.
If you need to have it within your project, you could try adding an import that contains the Qt Quick Controls import. QQmlEngine::addImportPath() says:
The newly added path will be first in the importPathList().
That statement seems to imply that order matters, and the code confirms it:
QStringList localImportPaths = database->importPathList(QQmlImportDatabase::Local);
// Search local import paths for a matching version
const QStringList qmlDirPaths = QQmlImports::completeQmldirPaths(uri, localImportPaths, vmaj, vmin);
for (const QString &qmldirPath : qmlDirPaths) {
QString absoluteFilePath = typeLoader.absoluteFilePath(qmldirPath);
if (!absoluteFilePath.isEmpty()) {
QString url;
const QStringRef absolutePath = absoluteFilePath.leftRef(absoluteFilePath.lastIndexOf(Slash) + 1);
if (absolutePath.at(0) == Colon)
url = QLatin1String("qrc://") + absolutePath.mid(1);
else
url = QUrl::fromLocalFile(absolutePath.toString()).toString();
QQmlImportDatabase::QmldirCache *cache = new QQmlImportDatabase::QmldirCache;
cache->versionMajor = vmaj;
cache->versionMinor = vmin;
cache->qmldirFilePath = absoluteFilePath;
cache->qmldirPathUrl = url;
cache->next = cacheHead;
database->qmldirCache.insert(uri, cache);
*outQmldirFilePath = absoluteFilePath;
*outQmldirPathUrl = url;
return true;
}
}
Your project structure might look something like this:
myproject/
qml/
main.qml
QtQuick/
Controls/
Button.qml
ScrollBar.qml
qmldir
In main.cpp you'd set the path to the qml directory (note that the path will be different depending on whether you're doing an in-source build or a shadow build of your project, so you may want to use a resource file to simplify things):
engine.addImportPath("path/to/qml");
Note that the controls import other types. For example, Button uses the Settings singleton, which comes from the QtQuick.Controls.Private import, so you'd need to copy that into the qml directory, too. Settings loads a certain style for the button (ButtonStyle), which could be any of the styles in this folder, depending on which style is in use.
In short, you need to copy all of the potential dependencies of the QML files you're using.

How specify file filter in QFileDialog::getExistingDirectory?

I need to choose a directory with files "*.in".
But if i use getExistingDirectory, i can't specify file filter, so i can't see files.
But i need to see ONLY "*.in" files, i could be only choose a directory, not a file.
Now i use this code:
qDebug() << QFileDialog::getExistingDirectory(this, tr("Выберите папку с файлами устройств"), "", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
And i can't see any files in chosen directory (in dialog).
How i can do this?
You need to pass QFileDialog::DontUseNativeDialog option. From the documentation of getExistingDirectory:
On Windows and OS X, this static function will use the native file
dialog and not a QFileDialog. However, the native Windows file dialog
does not support displaying files in the directory chooser. You need
to pass DontUseNativeDialog to display files using a QFileDialog. On
Windows CE, if the device has no native file dialog, a QFileDialog
will be used.
To filter displayed files by extension you will have to do slightly more:
QFileDialog dlg(nullptr, tr("Choose Directory"));
dlg.setOptions(QFileDialog::DontUseNativeDialog | QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
dlg.setFileMode(QFileDialog::Directory);
dlg.setNameFilter(tr("Directories with device files (*.in)"));
if (dlg.exec())
qDebug() << dlg.selectedFiles();
When I tried this, the files that don't match the filter were still displayed, but in grey color (I tried on MacOS, maybe you will have more luck on Windows).
There is no standard way to prevent user from selecting a folder which contains no files matching the filter. A solution is to derive your own class from QFileDialog and override the accept function (not calling QFileDialog::accept from your override will prevent the dialog from closing).
I think it doesn't work with get-dir method. Would it be also acceptable to let the user select any of the *.in files and then getting the directory of that in-file using QFileInfo::path?
QString inFile = QFileDialog::getOpenFileName(
this,
tr( "Выберите папку с файлами устройств "
"выделив какой-либо из файлов устройств :-)"
),
lastSelectedDir,
"*.in"
);
QString dirName = QFileInfo(inFile ).absolutePath();

QTranslator checking

How to check which file with translation was loaded ? (Current loaded translation)
I load translation in main.c and I would like to check in MainWindow Class which translation was loaded.
I don't think you can do it, using Qt's methods.
The best way of doing it would be to write a wrapper around QTranslator and store all loaded translation files in it (you can load more than one translation file at a time).
Much worse, but easier way is to use a fake translation. Something like this:
const QString check = tr("lang");
if (check == "en") {
// it's english
} else if (check == "fr") {
// it's french
}
...
According to Internationalization with Qt, you anyway get the system locale to load the appropriate translation file. Just check the value of the locale string:
#include <QLocale>
QString locale = QLocale::system().name();
For example, for English, it is "en", for German - "de".

QFileDialog View Files and Folders when choosing a Directory

I'm new to learning the Qt library, and I'm having a hard time getting QFileDialog to work properly. I want the user to be able to select a directory but also be able to view the files and folders so they know which directory they should pick. I have seen things similar to this being posted elsewhere but everything I've tried hasn't made any difference in the output.
I've tried creating my own dialog and setting the mode to directory, which says that it should display both files and folders:
QFileDialog myDialog(this);
myFileExplorer.setFileMode(QFileDialog::Directory);
myFileExplorer.setDirectory("C:/");
QString file = myFileExplorer.exec();
And I've tried using getExistingDirectory as well, but with that function it always only shows the directory as well.
Thanks
QString getExistingDirectory ( QWidget * parent = 0, const QString & caption = QString(),
const QString & dir = QString(), Options options = ShowDirsOnly )
The default options parameter is set to show dirs only, you have to change it to
QFileDialog::DontUseNativeDialog
But unfortunately you won't be able to use native dialog.

Save the screenshot of a widget

I want to save a screenshot of a widget in Qt.
I created the following code that should work:
QWidget* activeWidget = getActiveWidget();//a function that returns the current widget.
if (activeWidget == NULL)
{
return;
}
QPixmap screenshot;
screenshot = QPixmap::grabWidget(activeWidget,activeWidget->rect());
if(screenshot.isNull()){
printf("ERROR");
}
bool a= screenshot.save("c:\\temp\\asd.jpg", "JPG", 50);
But unfortunately this does not seem to work.
Does anyone know what the problem is?
In this answer and this forum post, people suggest the following:
Most likely, the plugin which is required to handle .jpg files is not found by your application. In order to resolve this issue, do one of the following things:
If you are doing a static build, add QTPLUGIN += qjpeg to your .pro file or
if you are doing a dynamic build, put the imageformats folder from %QTDIR%\plugins next to your .exe

Resources