我有一个gtk-rs
应用程序,当用户点击提交按钮时,Gtk::Entry
用于获取用户输入。所有内容都会编译并运行,但我无法在处理按钮按下的方法之外获取用户输入。
我可以检查是否从按钮单击处理程序内部正确地收集了输入,但是从方法外部获取字符串目前不起作用。
我发现了类似的问题,花了很多时间在谷歌上搜索这个问题,但到目前为止,我还没有找到这个问题的解决方案。事实上,我甚至没有发现任何人问同样的问题,这让我觉得要么我问错了问题,要么我试图以一种非常糟糕的方式来做这件事。
代码就在这里,我想在button.connect_clicked
方法外得到user_input
变量。
代码:
use gtk::prelude::*;
use gtk::{Button, Orientation};
use std::cell::RefCell;
use std::rc::Rc;
pub fn login_view() -> (gtk::Box, String) {
let button = Button::builder()
.label("Submit")
.margin_top(6)
.margin_bottom(12)
.margin_start(12)
.margin_end(12)
.build();
let input = gtk::Entry::builder()
.placeholder_text("input")
.margin_top(12)
.margin_bottom(6)
.margin_start(12)
.margin_end(12)
.build();
let login_box = gtk::Box::builder()
.orientation(Orientation::Vertical)
.build();
login_box.append(&input);
login_box.append(&button);
let mut user_input = Rc::new(RefCell::new(String::new()));
let user_clone = user_input.clone();
button.connect_clicked(move |_| {
user_input.replace((format!("{}", input.text())));
println!("user input = {}", user_input.borrow().to_string());
input.set_text("");
});
println!("user_clone: {}", user_clone.borrow().to_string());
return (login_box, user_clone.borrow().to_string());
}
输出:
user_clone:
user input = dsfdsfds // this line repeats as many times as you hit the button.
这可能是一个潜在的异步问题,即在收集用户输入之前调用println!("user_clone: {}", user_clone.borrow().to_string());
,然后再也不运行,但如果是这种情况,我也不知道如何处理这种情况,因为connect_clicked
方法并没有真正完成,它只是在每次单击按钮时运行。
最终的目标是得到输入值并将其存储在一个结构体中,所以无论如何,我可以将这个输入值存储到一个已经声明的结构体中,这将是理想的。
1条答案
按热度按时间xwbd5t1u1#
我们已经开始走上正确的道路,我们使用了
Rc<RefCell<String>>
来共享所有权,并保持可变性,所以不是只返回函数末尾的内容,而是可以返回整个user_clone
。但是你我很快就会意识到,图形应用程序通常是多线程的,这是有原因的,因此Rc<...>
必须是Send
或Sync
或两者都有。所以我建议换成Arc<Mutex<String>>
(或者用RwLock
替换Mutex
)然后你可以把返回的
Arc<Mutex<String>>
放到你想要原始String
的结构体中,无论何时你从它读取,你都会得到最新的版本。