将自定义作者类别添加到Gtk :: AboutDialog类

时间:2011-09-26 23:15:38

标签: c++ gtkmm

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

  • set_artists()
  • set_authors()
  • set_documenters()
  • set_translator_credits()

但我想添加一个自定义类别。现在我有一个接受一堆插件的程序,所以在启动它扫描插件时我想在你点击显示所有插件作者姓名的信用点时在about屏幕上填充“插件”页面(删除当然重复)。逻辑已经存在,但将它们添加到他们当然不属于的艺术家或纪录片类别看起来很奇怪。

除了滚动自己的类别之外,还有一种简单的方法来添加新类别吗?

1 个答案:

答案 0 :(得分:2)

好问题!在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 1\nPlugin 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中,这要困难得多,尽管可能并非不可能。您必须使用在正常处理程序之后运行的处理程序连接到Credits按钮的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 1\nPlugin 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;
    }
}