向Gtk::AboutDialog类添加自定义Authors类别

Adding a custom Authors category to Gtk::AboutDialog class

本文关键字:自定义 Authors 添加 类别 Gtk AboutDialog      更新时间:2023-10-16

我想知道是否有一种方法可以通过gtkmm在Gtk::AboutDialog类中设置自定义作者类别。我知道有以下方法:

  • set_artists ()
  • set_author ()
  • set_documenters ()
  • set_translator_credits ()

但是我想添加一个自定义类别。现在我有一个接受一堆插件的程序,所以在启动时,当它扫描插件时,我想在关于屏幕上填充一个"插件"页面,一旦你点击credit,显示所有插件作者的名字(当然删除重复的)。逻辑已经存在,但是将他们添加到艺术家或文档者类别中看起来很奇怪,因为他们肯定不属于这些类别。

除了滚动我自己的类别外,有没有简单的方法来添加新类别?

好问题!在GTK 3中,这相当容易。您必须对About对话框的内部子对话框进行一些操作,这些操作在将来的版本中可能会更改,因此请注意!

我用Vala写了一个简单的例子,它可以做你想做的事情。这对我来说更快,因为我几乎从不使用Gtkmm。不过翻译起来应该不会太难。

using Gtk;
int main(string[] args)
{
    Gtk.init(ref args);
    var dialog = new AboutDialog();
    // Fetch internal children, using trickery
    var box = dialog.get_child() as Box;
    Box? box2 = null;
    ButtonBox? buttons = null;
    Notebook? notebook = null;
    box.forall( (child) => {
        if(child.name == "GtkBox")
            box2 = child as Box;
        else if(child.name == "GtkButtonBox")
            buttons = child as ButtonBox;
    });
    box2.forall( (child) => { 
        if(child.name == "GtkNotebook")
            notebook = child as Notebook;
    });
    // Add a new page to the notebook (put whatever widgets you want in it)
    var plugin_page_index = notebook.append_page(new Label("Plugin 1nPlugin 2"),
        new Label("Plugins"));
    // Add a button that toggles whether the page is visible
    var button = new ToggleButton.with_label("Plugins");
    button.clicked.connect( (button) => {
        notebook.page = (button as ToggleButton).active? plugin_page_index : 0;
    });
    buttons.pack_start(button);
    buttons.set_child_secondary(button, true);
    // Set some other parameters
    dialog.program_name = "Test Program";
    dialog.logo_icon_name = Gtk.Stock.ABOUT;
    dialog.version = "0.1";
    dialog.authors = { "Author 1", "Author 2" };
    dialog.show_all(); // otherwise the new widgets are invisible
    dialog.run();
    return 0;
}

在GTK 2中,这要困难得多,尽管可能不是不可能。你必须连接到信用按钮的clicked信号,在正常处理程序之后运行的处理程序,然后获得一个顶级窗口列表,并寻找打开的新窗口。然后,您可以在该窗口的GtkNotebook中添加另一个页面。

我建议这样做有点不同:添加一个插件按钮的操作区域,打开自己的窗口。这样你就不用在内部子节点上瞎折腾了。下面是另一个Vala示例:

using Gtk;
class PluginsAboutDialog : AboutDialog {
    private Dialog _plugins_window;
    private Widget _plugins_widget;
    public Widget plugins_widget { get {
        return _plugins_widget;
    }
    set {
        var content_area = _plugins_window.get_content_area() as VBox;
        if(_plugins_widget != null)
            content_area.remove(_plugins_widget);
        _plugins_widget = value;
        content_area.pack_start(value);
    }}
    public PluginsAboutDialog() {
        _plugins_window = new Dialog();
        _plugins_window.title = "Plugins";
        _plugins_window.add_buttons(Stock.CLOSE, ResponseType.CLOSE, null);
        _plugins_window.response.connect((widget, response) => { widget.hide(); });
        var buttons = get_action_area() as HButtonBox;
        // Add a button that opens a plugins window
        var button = new Button.with_label("Plugins");
        button.clicked.connect( (button) => {
            _plugins_window.show_all();
            _plugins_window.run();
        });
        button.show();
        buttons.pack_start(button);
        buttons.set_child_secondary(button, true);
    }
    public static int main(string[] args) {
        Gtk.init(ref args);
        var dialog = new PluginsAboutDialog();
        // Make a widget for the plugins window
        var can_be_any_widget = new Label("Plugin 1nPlugin 2");
        dialog.plugins_widget = can_be_any_widget;
        // Set some other parameters
        dialog.program_name = "Test Program";
        dialog.logo_icon_name = Gtk.Stock.ABOUT;
        dialog.version = "0.1";
        dialog.authors = { "Author 1", "Author 2" };
        dialog.run();
        return 0;
    }
}