Как получить значок, тип MIME и приложение, связанное с файлом на рабочем столе Linux?
Вопрос
Используя C++ на рабочем столе Linux, как лучше всего получить значок, описание документа и приложение, «связанное» с произвольным путем к файлу/файлу?
Я хотел бы использовать наиболее «канонический» способ поиска значков, описаний типов mime/типов файлов и связанных приложений как в KDE, так и в gnome, и я бы хотел избегайте каких-либо «обстрелов» в командной строке и «низкоуровневые» процедуры, а также избегать самостоятельного изобретения колеса (без анализа файла mime-типов и тому подобного).
Правки и примечания:
Эй, изначально я задал этот вопрос об информационном объекте файла QT, и ответ «нет четкого ответа» кажется правильным, насколько это возможно.НО это настолько запутанная ситуация, что я открываю вопрос в поисках дополнительной информации.
Меня больше не волнует конкретно QT, я просто ищу большинство канонический способ найти тип mime с помощью вызовов функций C++/c как в KDE, так и в gnome (особенно в Gnome, поскольку именно здесь меня больше всего смущает).Я хочу иметь возможность отображать значки и описания, соответствующие Nautilus, в Gnome и Konquerer/что-то еще в KDE, а также правильно открывать файлы и т. д.
Я полагаю, это нормально, что я получу это отдельно для KDE и Gnome.Большой вопрос: какой самый распространенный/лучший/канонический способ получить всю эту информацию для рабочего стола Linux?Документация Gnome особенно непрозрачна.В gnome-vsf есть процедуры mime, но они устарели, и я не могу найти процедуру mime для GIO/GFS, замену gnome-vsf.Существует смутный намек на то, что следует использовать открытые настольные приложения, но какое из них использовать, неясно.И причем тут libmagic и xdg?
Указатели на эссе, в котором резюмируются проблемы, с радостью принимаются.Опять же, я знаю, что ответ в три строки: «Такого животного нет», но я ищу длинный отвечать.
Решение
Вот пример использования GLib / GIO для получения необходимой информации.
#include <gio/gio.h>
#include <stdio.h>
int
main (int argc, char **argv)
{
g_thread_init (NULL);
g_type_init ();
if (argc < 2)
return -1;
GError *error;
GFile *file = g_file_new_for_path (argv[1]);
GFileInfo *file_info = g_file_query_info (file,
"standard::*",
0,
NULL,
&error);
const char *content_type = g_file_info_get_content_type (file_info);
char *desc = g_content_type_get_description (content_type);
GAppInfo *app_info = g_app_info_get_default_for_type (
content_type,
FALSE);
/* you'd have to use g_loadable_icon_load to get the actual icon */
GIcon *icon = g_file_info_get_icon (file_info);
printf ("File: %s\nDescription: %s\nDefault Application: %s\n",
argv[1],
desc,
g_app_info_get_executable (app_info));
return 0;
}
Другие советы
Вы можете использовать инструменты, доступные на хдг для этого, в частности xdg-mime query
.
Чтобы узнать тип файла, например.файл index.html
ты бы
$ xdg-mime query filetype index.html
Это вернет mimetype.Чтобы узнать, какое приложение связано с этим mimetye, используйте, например.
$ xdg-mime query default text/html
Это возвращает epiphany.desktop
здесь, т.е. $APPNAME.desktop
, поэтому из него легко получить имя приложения.Если вы просто хотите открыть файл в приложении по умолчанию, вы, конечно, можете просто запустить
$ xdg-open index.html
что вызвало бы прозрение.
Функции запроса ресурсов значков, похоже, недоступны в xdg-utils
, но вы можете написать небольшой скрипт на Python, используя pyxdg это также предлагает массу дополнительных функций.
Для привязок C вам, вероятно, придется заглянуть в Портленд код, указанный на хдг страница.
РЕДАКТИРОВАТЬ:
Касательно libmagic
и друзья, вам нужно будет определиться со своими предпочтениями:Хотя libmagic кажется более полным (и точным) с точки зрения охвата типов файлов, это вообще не волнует о приложениях или значках по умолчанию.Он также не предоставляет вам инструментов для установки дополнительных типов mime.
В Qt > = 4.6 появилась новая функция для систем X11
QIcon QIcon::fromTheme ( const QString & name, const QIcon & fallback = QIcon() ) [static]
Вы можете использовать эту функцию. Документация здесь / (Qt 5)
Ни QFileIconProvider, ни QFileInfo ничего не будут делать с базой данных Mime ОС. Для доступа к значкам, связанным с различными типами пантомимы, вам придется использовать функции базовой среды рабочего стола. В Qt нет (пока) канонического пути.
Учтите, что у вас может быть другой значок в Gnome, в KDE и в Windows. Так, например, в KDE вы бы использовали KMimeType а>. р>
Я только что нашел KFileItem . Этот класс дает вам все, что вам нужно для значков, типов пантомимы и связанных вещей в KDE Я уверен, что в gnome есть эквивалент, но это дает доступ на том же уровне, что и приложение QT. Р>
Возможно, вы захотите использовать системный файл /etc/mime.types" файл. Это также хорошая идея, чтобы сохранить копию вашей программы файла типа MIME. Таким образом, вы не зависите от системы, но в то же время вы должны держать ее достаточно исчерпывающей. Не уверен насчет иконок.
Может быть, посмотрите на этот код: http: //ftp.devil-linux. орг / паб / Devel / источники / 1.2 / файл-4.23.tar.gz
Это стандартная утилита, используемая в большинстве дистрибутивов Linux / Unix. Вы получите MIME-тип и дополнительную информацию.
Я думаю, что и Gnome, и KDE имеют свои собственные способы определения этого, а также установки значка и стандартного приложения для него.
В любом случае, этот файл-инструмент, вероятно, лучший способ получить тип mime и описание документа. А в некоторых случаях даже некоторые подробности о содержании.
Это даст вам пантомиму. Это то, что вам нужно в любом случае, чтобы знать, как вы можете открыть файл. Это отдельные шаги. В файле не говорится ни о значке, ни о приложении, с помощью которого можно открыть файл.
С опозданием примерно на 8 лет, но все еще полезным.
Чтобы получить связанные приложения в KDE, вы можете сделать то, что предложил Джо (используя KFileItem
).Однако для этого требуется подключение множества библиотек.Код ниже требует меньше.
#include <QCoreApplication>
#include <QMimeDatabase>
#include <QDebug>
#include <KMimeTypeTrader>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
if (argc < 2)
{
qDebug() << "missing argument <filename>";
return 1;
}
QMimeDatabase mimeDb;
QMimeType mimeType = mimeDb.mimeTypeForFile(QString::fromLocal8Bit(argv[1]));
KService::List services = KMimeTypeTrader::self()->query(
mimeType.name(),QStringLiteral("Application"));
foreach(const QExplicitlySharedDataPointer<KService>& svc, services)
{
qDebug() << "service: " << svc->name();
qDebug() << "exec: " << svc->exec();
}
}
Для компиляции кода добавьте QT += KService KCoreAddons
к твоему qmake .pro
файл.
Ссылки на документацию KMimeTypeTrader и KService: