我是 Rust 和 GTK 的新手。我想在初始化我的
glib::MainContext::channel()
之前创建一对 gtk::Application
。我相信这可以完全理解为std::sync::mpsc
。虽然我可以创建 rx/tx 通道对并保存它,但我不确定如何将 Receiver
传递到 gtk::Application::connect_activate()
信号处理程序中,以便我可以 .attach()
它。
例如,我修改了这个样本:
struct MyData {
ready_tx: glib::Sender<i32>,
//ready_rx: glib::Receiver<i32>,
}
fn setup() -> MyData {
let (ready_tx, ready_rx) = glib::MainContext::channel(glib::Priority::default());
MyData {
ready_tx,
//ready_rx,
}
}
fn main() {
let data = setup();
//
// Setup other threads by cloning data.sender
//
let application = gtk::Application::new(
Some("com.github.gtk-rs.examples.cairo_threads"),
Default::default(),
);
application.connect_activate(move |app| {
build_ui(&app, &data)
});
application.run();
}
fn build_ui(application: >k::Application, data: &MyData) {
...
data.ready_rx.attach( {
...
});
}
上面的代码可以编译并运行(忽略已删除的
build_ui
),但有一个明显的问题:ready_tx
实际上并未包含在内。
这样做会导致“发生移动,因为
data.ready_rx
具有类型 glib::Receiver<i32>
,它没有实现 Copy
内的 build_ui()
特征”。
我希望
Receiver<i32>
的所有权从 setup()
函数转移到 main
,并最终被 build_ui()
函数消耗,但我不确定如何到达那里或我做什么我失踪了。我不确定为什么需要 Copy
,但我知道我不能 .clone()
Receiver
。
有什么想法吗?
我想这样做,因为我需要先设置一些额外的线程,在初始化 GTK GUI 之前,这些线程需要引用
Sender
。我还没有找到任何在 glib::MainContext::channel()
函数之外创建 build_ui()
对的好例子。
我应该考虑其他方法吗?
如果您只需要
Receiver
一次,请将 Option<Receiver>
和 take().unwrap()
存储在 build_ui()
中,为此您将需要对 MyData
的可变引用。
如果您无法提供可变引用(我相信GTK就是这种情况),您可以存储一个
Cell<Option<Receiver>>
,然后take().unwrap()
它。这只需要共享引用,因为 Cell
具有内部可变性。