3

I am trying to write simple GTK application in Rust, but faced with problem that I cannot add signal to menu item. There is simplified code to reproduce problem:

Glade file ("interface.glade"):

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.16.1 -->
<interface>
  <requires lib="gtk+" version="3.10"/>
  <object class="GtkWindow" id="window1">
    <property name="can_focus">False</property>
    <child>
      <object class="GtkBox" id="box1">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="orientation">vertical</property>
        <child>
          <object class="GtkMenuBar" id="menubar1">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <child>
              <object class="GtkMenuItem" id="menuitem1">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="label" translatable="yes">File</property>
                <property name="use_underline">True</property>
                <child type="submenu">
                  <object class="GtkMenu" id="menu1">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <child>
                      <object class="GtkImageMenuItem" id="FileMenu">
                        <property name="label">gtk-new</property>
                        <property name="visible">True</property>
                        <property name="can_focus">False</property>
                        <property name="use_underline">True</property>
                        <property name="use_stock">True</property>
                      </object>
                    </child>
                  </object>
                </child>
              </object>
            </child>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <placeholder/>
        </child>
      </object>
    </child>
  </object>
</interface>

Rust code ("main.rs"):

extern crate gtk;

mod example {
    use gtk;
    use gtk::traits::*;
    use gtk::signal::Inhibit;
    use gtk::widgets::{
        Builder,
        MenuItem
    };
    use gtk::Window;

    pub fn main() {
        gtk::init().unwrap_or_else(|_| panic!("Failed to initialize GTK."));
        let builder = Builder::new_from_file("./interface.glade").unwrap();
        let window: Window = builder.get_object("window1").unwrap();

        window.connect_delete_event(|_, _| {
            gtk::main_quit();
            Inhibit(true)
        });

        let file_menu: MenuItem = builder.get_object("FileMenu").unwrap();
        file_menu.connect_activate(|_| {
            println!("Activated");
        });

        window.show_all();
        gtk::main();
    }
}

fn main() {
    example::main()
}

And when I try to compile it, I get an error:

src/main.rs:24:19: 26:11 error: no method named `connect_activate` found for type `gtk::widgets::menu_item::MenuItem` in the current scope
src/main.rs:24         file_menu.connect_activate(|_| {
src/main.rs:25             println!("Activated");
src/main.rs:26         });
src/main.rs:24:19: 26:11 note: the method `connect_activate` exists but the following trait bounds were not satisfied: `gtk::widgets::menu_item::MenuItem : gtk::traits::button::ButtonTrait`

Am I doing something wrong?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Lodin
  • 2,028
  • 2
  • 18
  • 29
  • Please include what version of the crates you are using. If I try to compile your example with `gtk 0.0.2`, I get 3 unrelated errors. – Shepmaster Jul 12 '15 at 15:07

1 Answers1

3

Am I doing something wrong?

Yep! You aren't reading and addressing the error message:

the method connect_activate exists but the following trait bounds were not satisfied: gtk::widgets::menu_item::MenuItem : gtk::traits::button::ButtonTrait

Granted, this error message is worded in an obtuse manner. It's saying that the type MenuItem does not implement the trait ButtonTrait. To be honest, this is the first time I've see this particular wording of the error message, so I might be a bit wrong. If you check out the documentation(1) for MenuItem though, you can see that it does not implement ButtonTrait. This precludes you from calling the method.

I don't know what a suitable workaround is. I don't see any examples that use MenuItem. The 3 linked example projects don't use it either. It's entirely possible that it simply hasn't had all of the appropriate traits implemented yet. Perhaps this would be a good chance for you to get some commits into an up-and-coming project! ^_^

I also couldn't find any fallback methods or traits that would allow you to call connect directly.

(1): I wish I could link to the docs, but there are no officially-hosted versions I can find.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • Honestly, I've read the error message but thought that I forgot to include some traits etc. It often happens when I use rust. But now I understood that it is a bug and as you say I can try to fix library code. Thank you for answer. – Lodin Jul 13 '15 at 12:00
  • 1
    @Lodin: I am in your boat, the error messages related to absent methods are not crystal clear; many times the compiler has recommended me to "use the trait" when it was already used and the issue was not satisfying the bounds... – Matthieu M. Jul 13 '15 at 12:54