Gtk-rs show_about_dialog problem

Hello, I'm having some problems with gtk-rs. I was trying to show the about dialog when a button is clicked. This is my code:

use gtk::{prelude::*, Application, glib, ApplicationWindow, Button};
const APP_ID: &str = "com.testgtk.Test";

fn main() -> glib::ExitCode{
    // Create a new application
    let app = Application::builder()
        .application_id(APP_ID)
        .build();
    
    // Connect to "activate" signal of `app`
    app.connect_activate(build_ui);
    
    // Run the application
    app.run()
}

fn build_ui(app: &Application) {
    // create a button with label and margins
    let button = Button::builder()
        .label("Press me")
        .margin_top(12)
        .margin_bottom(12)
        .margin_start(12)
        .margin_end(12)
        .build();
    
    // Connect to "clicked" signal of `button`
    button.connect_clicked(|button| {
        button.set_label("Hello World");
        let name: String = String::from("Hello");
        let  args = [("program-name", name)];
        gtk::show_about_dialog(None, &args[..]);
    });

    // Create window
    let window = ApplicationWindow::builder()
        .application(app)
        .title("My GTK app")
        .child(&button)
        .build();
    // Present window
    window.present();
}

The problem is that when compiling it gives this error:

error[E0308]: mismatched types
   --> src/main.rs:33:38
    |
33  |         gtk::show_about_dialog(None, &args[..]);
    |         ----------------------       ^^^^^^^^^ expected `&[(&str, &dyn ToValue)]`, found `&[(&str, String)]`
    |         |
    |         arguments to this function are incorrect
    |
    = note: expected reference `&[(&str, &dyn ToValue)]`
               found reference `&[(&str, std::string::String)]`

Looking at the docs here the ToValue trait should be implemented for String.
Thanks for the help

I have found a solution, here is the correct code:

fn build_ui(app: &Application) {
    let window = ApplicationWindow::builder().application(app)
        .title("My GTK app")
        .build();
    // create a button with label and margins
    let button = Button::builder()
        .label("Press me")
        .margin_top(12)
        .margin_bottom(12)
        .margin_start(12)
        .margin_end(12)
        .build();
    // Connect to "clicked" signal of `button`
    button.connect_clicked(|button| {
        button.set_label("Hello World");
        let name = &String::from("Program one") as &dyn ToValue;
        let  args = [("program-name", name)];
        gtk::show_about_dialog::<Window>(None, &args[..]);
    });

    // Create window
    window.set_child(Some(&button));
    // Present window
    window.present();
}

As stated in this stackoverflow answer: A trait object is a different type and often a different size from the underlying type; So we need to perform a conversion. We can do that in various ways:

fn do_the_thing<'a, I, T: 'a>(things: I) -> Vec<&'a dyn ToValue>
where
    I: IntoIterator<Item = &'a T>,
    T: ToValue,
{
    things.into_iter().map(|x| x as &dyn ToValue).collect()
}
  1. Using as &dyn ToValue like in the example before

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.