【问题标题】:How do you get the icon, MIME type, and application associated with a file in the Linux Desktop?如何获取与 Linux 桌面中的文件关联的图标、MIME 类型和应用程序?
【发布时间】:2010-12-10 09:26:25
【问题描述】:

在 Linux 桌面上使用 C++,获取图标、文档描述和与任意文件/文件路径“关联”的应用程序的最佳方式是什么?

我想使用最“规范”的方式在 KDE 和 gnome 上查找图标、mime 类型/文件类型描述和相关应用程序,并且我想避免任何“炮轰”到命令行和“低级”例程以及避免自己重新发明轮子(不解析mime-types文件等)。

编辑和注释:

嘿,我最初问这个关于 QT 文件信息对象的问题,“没有明确的答案”的答案似乎是正确的。但这是一个搞砸的情况,我打开这个问题寻找更多信息。

我不再特别关心 QT,我只是在寻找通过在 KDE 和 gnome 上的 C++/c 函数调用(尤其是Gnome,因为那是我最困惑的地方)。我希望能够在 Gnome 和 Konquerer/KDE 上显示与 Nautilus 匹配的图标和描述,以及适当地打开文件等。

我想我可以为 KDE 和 Gnome 单独获取这个。最大的问题是为 Linux 桌面获取所有这些信息的最常见/最佳/规范的方法是什么? Gnome 文档尤其不透明。 gnome-vsf 有 mime 例程,但它已被弃用,我找不到 GIO/GFS 的 mime 例程,gnome-vsf 的替代品。有一个模糊的暗示,一个人应该使用开放的桌面应用程序,但使用哪一个是模糊的。 libmagic 和 xdg 适合哪里?

指向一篇总结被欣然接受的问题的文章。同样,我知道三行答案是“没有这样的动物”,但我正在寻找 long 答案。

【问题讨论】:

  • 顺便说一句,没有更详细的答案,我会让答案赏金到期而不给任何人......

标签: c++ linux mime gnome kde


【解决方案1】:

这是一个使用 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;
}

【讨论】:

  • 看起来或不太像我正在寻找的东西。有记录这些功能的链接吗?
  • library.gnome.org/devel/gio/stable 是 GIO 文档的主页,根据名称应该很明显函数所在的部分。
  • 看起来不错:GIO 的目标是“提供一个非常好的 API,让开发人员更喜欢它而不是原始 POSIX 调用”——如果开发人员能找到这个页面的话!没有来自旧 gnomeVFS 页面的链接,也没有使用关键字“Mime”或“文件关联,并且没有出现在相当长的 Google 搜索中 - 好吧,现在我知道了!谢谢
  • 不会只返回 Nautilus/Gnome 的默认应用程序来打开这种类型的文件吗?
  • 不,nautilus 使用标准的跨桌面方法来确定文件的默认应用程序。即使您在 nautilus KDE 应用程序中覆盖了默认值,也应该尊重这一点(虽然还没有测试过)。
【解决方案2】:

您可以为此使用xdg 提供的工具,尤其是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 中似乎没有图标资源的查询功能,但您可以使用pyxdg 编写一个小的 Python 脚本,它也提供大量附加功能。

对于 C 绑定,您可能需要查看链接在 xdg 页面上的 portland 代码。

编辑:

关于libmagic 和朋友,您需要确定您的偏好:虽然 libmagic 在文件类型覆盖方面似乎更完整(和准确),但它根本不在乎关于默认应用程序或图标。它也没有为您提供安装额外 mimetype 的工具。

【讨论】:

  • 1.如何从 c++ 2 调用 xdg。您能否扩展 xdg/libmagic 的差异?
  • 1. xdg-utils 只是 shell 脚本,所以你必须使用 sth。像 popen()。如果您可以使用python写某事。使用 pyxdg 专用(或在 C++ 中重新实现专用部分)。 2. AFAIK xdg-utils 只是处理 KDE 或 GNOME 扩展名->mimetype 数据库的前端,并且只有当这些数据库失败时才会退回到 libmagic/file 以识别 mimetype。 Libmagic 是一个包含二进制文件头的数据库,因此它可以更加准确。使用 xdg 的一大好处是,您可以从代码中委派某些功能的责任,而不是从头开始重写所有内容。
【解决方案3】:

在 Qt >= 4.6 中,有一个针对 X11 系统的新功能

QIcon QIcon::fromTheme ( const QString & name, const QIcon & fallback = QIcon() ) [static]

您可以使用此功能。 Documentation here / (Qt 5)

【讨论】:

    【解决方案4】:

    QFileIconProvider 和 QFileInfo 都不会对 OS mime 数据库做任何事情。要访问与不同 mime 类型关联的图标,您必须使用底层桌面环境的功能。在 Qt 中(还)没有规范的方法。

    考虑您可以在 Gnome、KDE ​​和 Windows 中使用不同的图标。例如,在 KDE 中你会使用KMimeType

    【讨论】:

      【解决方案5】:

      我刚刚找到KFileItem。此类为您提供 KDE 中有关图标、mime 类型和相关内容的一切。我确信在 gnome 中有一个等价物,但这提供了与 QT 应用程序相同级别的访问权限。

      【讨论】:

        【解决方案6】:

        您可能想使用系统的“/etc/mime.types”文件。维护程序的 MIME 类型文件的副本也是一个好主意。这样,您就不会依赖系统,但同时您需要保持它相当详尽。不确定图标。

        【讨论】:

          【解决方案7】:

          也许看看这段代码: http://ftp.devil-linux.org/pub/devel/sources/1.2/file-4.23.tar.gz

          这是大多数 Linux/Unix 发行版上的标准文件 util。您将获得 MIME 类型和更多信息。

          我认为 Gnome 和 KDE 都有自己的方法来确定这一点,并为其设置图标和标准应用程序。

          无论如何,该文件工具可能是获取 mime 类型和文档描述的最佳方式。在某些情况下,甚至是有关内容的一些细节。

          这将为您提供 mime 类型。无论如何,这就是您需要知道如何打开文件的内容。这些是分开的步骤。文件没有说明图标或打开文件的应用程序。

          【讨论】:

          • 能否提供更多解释?我已经浏览了很多代码。
          • 另外下载的时候存档无效
          • 您到底想知道什么?你不知道'file'命令吗?只需打开一个终端,然后输入“file $somefile”。这个工具非常适合自动检测文件的类型。这是相当标准的。我更新了链接,好像失效了。
          • 我认为我的问题涉及到我想要什么的细节
          • file 可能是获取 mime 类型和文档描述的最佳方式。 Ofc 这只是一步。查看我的编辑。
          【解决方案8】:

          晚了大约 8 年,但仍然有用。

          要在 KDE 中获取相关应用程序,您可以按照 Joe 的建议进行操作(使用 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 文档的链接:

          【讨论】:

            【解决方案9】:

            复制/粘贴上面的好示例(使用 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;
            
                g_autoptr(GError) error;
                GFile* file = g_file_new_for_path (argv[1]);
                GFileInfo* file_info = g_file_query_info (file,
                                                          "standard::*",
                                                          G_FILE_QUERY_INFO_NONE,
                                                          NULL,
                                                          &error);
            
                const char* content_type = g_file_info_get_content_type (file_info);
                g_autofree gchar* 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));
            
                g_object_unref(file_info);
                g_object_unref(file);
                return 0;
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-02-03
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2018-02-25
              • 1970-01-01
              相关资源
              最近更新 更多