GtkAppChooser所有应用程序和/或音频混合器的内容类型

时间:2017-01-31 08:54:18

标签: gtk mime-types gtk3 mixer

我希望有一个GtkAppChooserButton,允许用户选择要运行的程序,这很可能是想要成为pavucontrol等音频混音器。尽管有关此问题的文档模糊,我收集应用程序选择器的内容类型是一种MIME类型,但是我找不到合适的MIME类型用于音频混音器,或者更一般地说只是"所有应用程序&#34 ;

application/等某些类型会在Other Application...项启用时提供两个Other...选项,两者都相同,且两者都不包含我拥有的应用程序的一半,包括任何音频混频器。除此之外,我所做的任何其他事情都让我远离我所追求的目标。

对于音频混音器或一般的所有程序,是否存在MIME类型和/或GtkAppChooser内容类型(它们似乎是相同的?)? (即任何在Gnome app launcher / xfce4-whisker-menu /等中都有图标的程序。)

1 个答案:

答案 0 :(得分:1)

好的,所以我提出了一个解决方案,认为它可能不像你希望的那么干净。

This thread提到了一种让GtkAppChooser显示全部"的方法,但它实际上并未显示您已安装的所有应用程序。然而,由此我能够弄清楚GtkAppChooser如何使用Gio.AppInfoGio.AppInfo.get_all()(这是PyObject),它返回所有应用程序的完整Gio.AppInfos列表已安装,只要他们有.desktop文件。

所以,我的解决方案"是编写我自己的应用程序选择器,它从Gio.AppInfo.get_all()获取应用程序列表。

我已经清理了我之前的解决方案并编写了一个课程' AllAppChooser'继承Gtk.Dialog,提供更多的自定义。完成的对话框如下所示:

enter image description here

使用的代码:

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gio


class AllAppChooser(Gtk.Dialog):
    """Provide a dialog to select an app from all those installed.

    The regular Gtk.AppChooserDialog does not seem to provide any way to allow
    selection from all installed apps, so this dialog serves as a replacement.

    """
    def __init__(self, parent=None):
        super().__init__(self)

        self.set_default_size(350, 400)
        self.set_icon_name('gtk-search')
        self.set_title('App Chooser')
        if parent:
            self.set_parent(parent)

        self.content_box = self.get_content_area()
        self.content_box.set_margin_left(8)
        self.content_box.set_margin_right(8)
        self.content_box.set_margin_top(8)
        self.content_box.set_margin_bottom(8)
        self.content_box.set_spacing(8)

        self.button_box = self.get_action_area()
        self.button_box.set_margin_left(4)
        self.button_box.set_margin_right(4)
        self.button_box.set_margin_top(4)
        self.button_box.set_margin_bottom(4)

        self.label = Gtk.Label('Choose An Application')
        self.content_box.pack_start(self.label, False, False, 0)

        self.list_store = Gtk.ListStore(str, str, int)

        pixbuf_renderer = Gtk.CellRendererPixbuf()
        text_renderer = Gtk.CellRendererText()
        icon_column = Gtk.TreeViewColumn('icon', pixbuf_renderer, icon_name=1)
        text_column = Gtk.TreeViewColumn('text', text_renderer, text=0)

        self.tree_view = Gtk.TreeView()
        self.tree_view.set_model(self.list_store)
        self.tree_view.set_headers_visible(False)
        self.tree_view.append_column(icon_column)
        self.tree_view.append_column(text_column)

        self.view_port = Gtk.Viewport()
        self.view_port.add(self.tree_view)

        self.scroll_window = Gtk.ScrolledWindow()
        self.scroll_window.add(self.view_port)
        self.content_box.pack_start(self.scroll_window, True, True, 0)

        self.ok_button = self.add_button(Gtk.STOCK_OK, 1)
        self.ok_button.connect('clicked', self.on_ok)

        self.cancel_button = self.add_button(Gtk.STOCK_CANCEL, 0)

        self.selected_app = None
        self.app_list = []

    def populate_app_list(self):
        """Populate the list of apps with all installed apps.

        Icons are provided by icon-name, however some apps may return a full
        path to a custom icon rather than a themed-icon name, or even no name
        at all. In these cases the generic 'gtk-missing-icon' icon is used.

        """
        self.app_list = Gio.AppInfo.get_all()
        for i in range(len(self.app_list)):
            gio_icon = self.app_list[i].get_icon()
            app_icon = 'gtk-missing-icon'
            if gio_icon:
                app_icon = gio_icon.to_string()
            app_name = self.app_list[i].get_display_name()
            self.list_store.append([app_name, app_icon, i])

        self.list_store.set_sort_column_id(0, Gtk.SortType.ASCENDING)

    def run(self):
        """Run the dialog to get a selected app."""
        self.populate_app_list()
        self.show_all()
        super().run()
        self.destroy()
        return self.selected_app

    def set_label(self, text):
        """Set the label text, \"Choose An App\" by default."""
        self.label.set_text(text)

    def on_ok(self, button):
        """Get Gio.AppInfo of selected app when user presses OK."""
        selection = self.tree_view.get_selection()
        tree_model, tree_iter = selection.get_selected()
        app_index = tree_model.get_value(tree_iter, 2)
        self.selected_app = self.app_list[app_index]

然后运行类似于常规对话框:

app_chooser = AllAppChooser()
application = app_chooser.run()

如果用户退出对话框或按下取消,则结果将为“无”,但如果他们选择了应用程序,则run()将返回应用程序的Gio.AppInfo对象,然后您可以执行此操作如你所愿。例如,要启动新选择的应用程序:

application.launch()

我觉得现在这是一个相对可靠的解决方案,但我仍然欢迎其他建议。另外,如果有一种方法可以在Gtk中执行此操作而无需执行所有这些操作,我仍然希望听到它。