将 WebView 传递给多个 gtk::Button 回调时,有没有办法避免克隆?
Is there a way to avoid cloning when passing a WebView to multiple gtk::Button callbacks?
我正在用 gtk 制作一个迷你网络浏览器。这段代码工作正常,但我想避免所有正在使用的克隆。
由于闭包的所有权错误,我不能多次使用 web_view
对象。
extern crate gio;
extern crate gtk;
extern crate webkit2gtk;
use gio::prelude::*;
use gtk::prelude::*;
use gtk::{Application, ApplicationWindow, Button, Entry};
use webkit2gtk::{WebView, WebViewExt};
fn main() {
let application =
Application::new(Some("com.github.gtk-rs.examples.basic"), Default::default())
.expect("failed to initialize GTK application");
application.connect_activate(|app| {
let window = ApplicationWindow::new(app);
window.set_title("Web Browser");
window.set_default_size(1024, 768);
let button_back = Button::new_with_label("Back");
let button_next = Button::new_with_label("Next");
let button_reload = Button::new_with_label("Reload");
let url_entry = Entry::new();
url_entry.set_text("https://www.google.com");
let button_go = Button::new_with_label("Go");
let web_view = WebView::new();
web_view.load_uri("https://www.google.com");
let clone1: WebView = web_view.clone();
let clone2: WebView = web_view.clone();
let clone3: WebView = web_view.clone();
let clone4: WebView = web_view.clone();
button_back.connect_clicked(move |_| {
clone1.go_back();
});
button_next.connect_clicked(move |_| {
clone2.go_forward();
});
button_reload.connect_clicked(move |_| {
clone3.reload();
});
button_go.connect_clicked(move |_| {
clone4.load_uri(&url_entry.get_buffer().get_text());
});
window.show_all();
});
application.run(&[]);
}
这些是我的依赖版本:
[dependencies]
gtk = "0.8.1"
gio = "0.8.1"
webkit2gtk = "0.9.2"
特征 gtk::ButtonExt
的方法 connect_clicked
的签名是
fn connect_clicked<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId
不,没有。
'static
回调定义禁止它引用任何临时变量,并强制它移动并拥有它使用的任何值。这是故意的,因为回调将比创建它的函数更有效。
gtk 的 WebView
表现得像 Rc
,所以克隆非常便宜,并且不复制任何东西。它仅执行簿记以帮助回调商定哪一个将是最后一个被销毁,因此哪个将释放底层 WebView
数据。
a clone!
macro in glib 可以帮助制作这些克隆,而无需手动命名额外的变量。
我正在用 gtk 制作一个迷你网络浏览器。这段代码工作正常,但我想避免所有正在使用的克隆。
由于闭包的所有权错误,我不能多次使用 web_view
对象。
extern crate gio;
extern crate gtk;
extern crate webkit2gtk;
use gio::prelude::*;
use gtk::prelude::*;
use gtk::{Application, ApplicationWindow, Button, Entry};
use webkit2gtk::{WebView, WebViewExt};
fn main() {
let application =
Application::new(Some("com.github.gtk-rs.examples.basic"), Default::default())
.expect("failed to initialize GTK application");
application.connect_activate(|app| {
let window = ApplicationWindow::new(app);
window.set_title("Web Browser");
window.set_default_size(1024, 768);
let button_back = Button::new_with_label("Back");
let button_next = Button::new_with_label("Next");
let button_reload = Button::new_with_label("Reload");
let url_entry = Entry::new();
url_entry.set_text("https://www.google.com");
let button_go = Button::new_with_label("Go");
let web_view = WebView::new();
web_view.load_uri("https://www.google.com");
let clone1: WebView = web_view.clone();
let clone2: WebView = web_view.clone();
let clone3: WebView = web_view.clone();
let clone4: WebView = web_view.clone();
button_back.connect_clicked(move |_| {
clone1.go_back();
});
button_next.connect_clicked(move |_| {
clone2.go_forward();
});
button_reload.connect_clicked(move |_| {
clone3.reload();
});
button_go.connect_clicked(move |_| {
clone4.load_uri(&url_entry.get_buffer().get_text());
});
window.show_all();
});
application.run(&[]);
}
这些是我的依赖版本:
[dependencies]
gtk = "0.8.1"
gio = "0.8.1"
webkit2gtk = "0.9.2"
特征 gtk::ButtonExt
的方法 connect_clicked
的签名是
fn connect_clicked<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId
不,没有。
'static
回调定义禁止它引用任何临时变量,并强制它移动并拥有它使用的任何值。这是故意的,因为回调将比创建它的函数更有效。
gtk 的 WebView
表现得像 Rc
,所以克隆非常便宜,并且不复制任何东西。它仅执行簿记以帮助回调商定哪一个将是最后一个被销毁,因此哪个将释放底层 WebView
数据。
a clone!
macro in glib 可以帮助制作这些克隆,而无需手动命名额外的变量。