John554
John554

Reputation: 303

GTK-rs getting input from GTK::Entry

I have a small gtk-rs application where I am trying to display an input field and get the input from the user. At the moment I can't get the input from the input field when the user clicks the button. I know button.connect_clicked is where I need to do this but I don't know how?

My build_ui method:

use gtk::prelude::*;
use gtk::{Application, ApplicationWindow, Button, Orientation};

pub fn build_ui(app: &Application) {
    let button = Button::builder()
        .label("Submit")
        .margin_top(12)
        .margin_bottom(12)
        .margin_start(12)
        .margin_end(12)
        .build();

    let input = gtk::Entry::builder()
        .placeholder_text("input")
        .margin_top(12)
        .margin_bottom(12)
        .margin_start(12)
        .margin_end(12)
        .build();

    let gtk_box = gtk::Box::builder()
        .orientation(Orientation::Vertical)
        .build();
    gtk_box.append(&input);
    gtk_box.append(&button);

    button.connect_clicked(move | _button| {
        println!("{}", input.display()); 
    });

    let window = ApplicationWindow::builder()
        .application(app)
        .title("gtk-app")
        .child(&gtk_box)
        .default_height(720)
        .default_width(360)
        .build();

    window.present();
}

main.rs:

const APP_ID: &str = "org.my-gtk-app";

fn main() {
    // Create a new application
    let app = Application::builder().application_id(APP_ID).build();

    // Connect to "activate" signal of `app`
    app.connect_activate(home::build_ui);

    // Run the application
    app.run();
}

I have found this question which is almost exactly the same however when I try and implement the solution all of the .add methods throw an error stating:

the following trait bounds were not satisfied: `ApplicationWindow: IsA<CellArea>` which is required by `ApplicationWindow: gtk4::prelude::CellAreaExt`

EDIT: Also Gtk::Entry does not have a .get_text() method according to the compiler. After doing a bit more googling around this it seems that GTK3 had a get_text method for Gtk::Entry however Gtk4 does not.

So does anyone know how to get the text from a Gtk::Entry object when using Gtk4?

EDIT 2: I think I needed to use the .display() method however when I run the code now I don't get the text input from the user. input.display() just returns an empty string. I have updated the code samples to reflect these changes.

Upvotes: 1

Views: 562

Answers (1)

frankenapps
frankenapps

Reputation: 8281

The Entry does have a text() method which gives you a GString (because Entry implements Editable), that can be converted to a rust str using as_str().

So in order to get the current text from an entry, you can do the following:

let my_input_value = my_input.text().as_str();

For completeness, here is the updated build_ui function:

pub fn build_ui(app: &Application) {
    let button = Button::builder()
        .label("Submit")
        .margin_top(12)
        .margin_bottom(12)
        .margin_start(12)
        .margin_end(12)
        .build();

    let input = gtk::Entry::builder()
        .placeholder_text("input")
        .margin_top(12)
        .margin_bottom(12)
        .margin_start(12)
        .margin_end(12)
        .build();

    let gtk_box = gtk::Box::builder()
        .orientation(Orientation::Vertical)
        .build();
    gtk_box.append(&input);
    gtk_box.append(&button);

    button.connect_clicked(move | _button| {
        println!("{}", input.text().as_str()); 
    });

    let window = ApplicationWindow::builder()
        .application(app)
        .title("gtk-app")
        .child(&gtk_box)
        .default_height(720)
        .default_width(360)
        .build();

    window.present();
}

Edit

Because GString implements Display the following works as well:

println!("{}", input.text());

Upvotes: 2

Related Questions