gtk-rs / gtk3-rs

Rust bindings for GTK 3
https://gtk-rs.org
MIT License
508 stars 90 forks source link

[HELP] Access gtk_sys::GtkWidget from gtk::GtkToggleButton #853

Closed flosse closed 4 months ago

flosse commented 4 months ago

My code base currently uses only gtk_sys but I want to migrate to gtk step by step. Now to avoid refactoring all at once, it would be helpful, if I can access the underlying data.

Let's say I want to migrate this:

struct Ui {
  bt_spdif: *mut gtk_sys::GtkWidget
  // ...
}

impl Ui {
  pub fn new() -> Self {
    unsafe{
      let label_text = CString::new("SPDIF").unwrap();
      let bt_spdif = gtk_toggle_button_new_with_label(label_text.as_ptr());
      Self { bt_spdif }
    }
  }
}

The new code would look like this:

struct Ui {
  bt_spdif: gtk::ToggleButton
  // ...
}

impl Ui {
  pub fn new() -> Self {
      let bt_spdif = ToggleButton::with_label("SPDIF");
      Self { bt_spdif }
    }
  }
}

But at some other point I still want to access the *mut gtk_sys::GtkWidget pointer, e.g. to use g_signal_connect_data like here:


g_signal_connect_data(                                          

    gs.ui.bt_spdif as *mut _, // <-- here we access it

    CStr::from_bytes_with_nul_unchecked(b"toggled\0").as_ptr(), 
    Some(mem::transmute(on_bt_toggled_spdif as *const ())),     
    gs as *mut _ as *mut c_void,                                
    None,                                                       
    0,                                                          
);                                                              
sdroege commented 4 months ago

The correct way to get the underlying C pointer is widget.to_glib_none().0, widget.to_glib_full() or widget.as_ptr() depending on the context. Please check the implementation of the bindings for lots of examples of this.

flosse commented 4 months ago

@sdroege Thanks a lot for that fast reply! :pray: This is exactly what I was looking for! :+1: