0

I would like to add characters to an input field using Rust gtk4. I've created the entry field as such (please assume I have a main function that runs the app and I another function that creates the UI):

let input = Entry::builder()
    .placeholder_text("Enter input")
    .build();

And a button for the character '1':

let one_button = Button::builder()
    .label("1")
    .margin_top(12)
    .margin_start(12)
    .margin_end(12)
    .build();

I want for when I clicked the button one_button I get the character '1' on the entry field. To do this I thought to create an empty string and pass it in when the button is clicked where I would push the character '1' into it. As such,

let entry = String::new();
one_button.connect_clicked(clone!(@strong entry =>
        move |_| {    
            entry.push_str("1");
            input.set_text(&entry);
        }
    ));

but I get the following error:

cannot borrow `entry` as mutable, as it is not declared as mutable

Is there a better way to do this?

cafce25
  • 15,907
  • 4
  • 25
  • 31
Shane Gervais
  • 107
  • 12

1 Answers1

1

There is no need to do all these shenanigans inside your click handler. Just get the old value and append the 1 to it like so:

one_button.connect_clicked(move |_| {
    let mut old_input_text = input.text().to_string();
    old_input_text.push_str("1");
    input.set_text(&old_input_text);
});

Here is full sample which I would have advised you to post, so that people can reproduce your issue more easily:

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

const APP_ID: &str = "org.gtk_rs.HelloWorld";

fn main() -> glib::ExitCode {
    let app = Application::builder().application_id(APP_ID).build();
    app.connect_activate(build_ui);

    app.run()
}

fn build_ui(app: &Application) {
    let vertical_stack = gtk::Box::builder()
        .spacing(5)
        .orientation(Orientation::Vertical)
        .margin_top(12)
        .margin_bottom(12)
        .margin_start(12)
        .margin_end(12)
        .build();

    let one_button = Button::builder().label("Press me!").build();

    vertical_stack.append(&one_button);

    let input = Entry::builder()
        .placeholder_text("I will contain ones...")
        .build();
    vertical_stack.append(&input);

    one_button.connect_clicked(move |_| {
        let mut old_input_text = input.text().to_string();
        old_input_text.push_str("1");
        input.set_text(&old_input_text);
    });

    let window = ApplicationWindow::builder()
        .application(app)
        .title("My GTK App")
        .child(&vertical_stack)
        .build();

    window.present();
}

With this dependecy inside the Cargo.toml:

[dependencies]
gtk = { version = "0.6.4", package = "gtk4", features = ["v4_6"] }
frankenapps
  • 5,800
  • 6
  • 28
  • 69