gpt4 book ai didi

gtk - 使用 rust-gnome 时如何将自己的数据获取到 GTK 回调?

转载 作者:行者123 更新时间:2023-11-29 08:00:39 26 4
gpt4 key购买 nike

... 或者,我如何子类化 gtk::Widget?

我的 Cargo.toml 中有以下依赖项:

[dependencies]
num = "*"
gtk = "*"
cairo-rs = "*"
gdk = "*"
time = "*"

我想创建自己的小部件类型(用于渲染分形)。我有:

extern crate cairo;
extern crate gtk;

use cairo::Context;
use gtk::signal::Inhibit;
use gtk::signal::WidgetSignals;
use gtk::traits::ContainerTrait;
use gtk::traits::WidgetTrait;

struct MyWidget {
widget: gtk::DrawingArea,
foo: u32,
}

impl MyWidget {
fn new() -> MyWidget {
let result = MyWidget {
widget: gtk::DrawingArea::new().unwrap(),
foo: 17
};
result.widget.connect_draw(move |_w, c| {
// Cannot do: result.redraw(c)
Inhibit(true)
});
result
}
fn modify(&mut self, x: u32) {
self.foo += x;
self.widget.queue_draw();
}
fn redraw(&self, _ : Context) -> Inhibit {
println!("Should redraw for {}", self.foo);
Inhibit(true)
}
}

fn main() {
gtk::init().ok();
let window = gtk::Window::new(gtk::WindowType::TopLevel).unwrap();

let area = MyWidget::new();
window.add(&area.widget);
window.connect_delete_event(|_, _| {
gtk::main_quit();
Inhibit(true)
});
window.connect_key_release_event(move |_w, _event| {
// Cannot do: area.modify(3);
Inhibit(true)
});
window.connect_button_release_event(move |_w, _event| {
// Cannot do: area.modify(17);
Inhibit(true)
});

window.show_all();
gtk::main();
}

但是当redraw被调用,w 当然是 gtk::DrawingArea而不是我的FractalWidget .我努力调用connect_draw关闭,但无法使用 result在其中(我已经尝试过 Box 将结果和 move 放入 lambda,但我是新手,所以可能有些方法我没有尝试过)。

所以,我的实际问题是:有没有办法将更多数据发送到 rust-gnome 重绘方法(和其他类似的回调),或者有没有办法扩展小部件结构以包含我自己的数据?

最佳答案

好的,这里有一些实际有效的代码,主要是通过使用 Arc<Mutex<MyWidget>> insead of plain MyWidget .这仍然感觉很笨拙,因为在进入闭包并将互斥量锁定在其中之前我需要一个显式克隆,但这可能是一件好事(即使只有一个线程用于 gtk 事件)。也许冗长可以通过宏来修复...

extern crate cairo;
extern crate gtk;

use cairo::Context;
use gtk::signal::Inhibit;
use gtk::signal::WidgetSignals;
use gtk::traits::ContainerTrait;
use gtk::traits::WidgetTrait;
use std::sync::{Arc,Mutex};

struct MyWidget {
widget: gtk::DrawingArea,
foo: u32,
}

impl MyWidget {
fn new() -> Arc<Mutex<MyWidget>> {
let result = Arc::new(Mutex::new(MyWidget {
widget: gtk::DrawingArea::new().unwrap(),
foo: 17
}));
let r2 = result.clone();
result.lock().unwrap().widget.connect_draw(move |_w, c| {
r2.lock().unwrap().redraw(c)
});
result
}
fn modify(&mut self, x: u32) {
self.foo += x;
self.widget.queue_draw();
}
fn redraw(&self, _ : Context) -> Inhibit {
println!("Should redraw for {}", self.foo);
Inhibit(true)
}
}

fn main() {
gtk::init().ok();
let window = gtk::Window::new(gtk::WindowType::TopLevel).unwrap();

let area = MyWidget::new();
window.add(&area.lock().unwrap().widget);
window.connect_delete_event(|_, _| {
gtk::main_quit();
Inhibit(true)
});
let a1 = area.clone();
window.connect_key_release_event(move |_w, _event| {
a1.lock().unwrap().modify(3);
Inhibit(true)
});
let a2 = area.clone();
window.connect_button_release_event(move |_w, _event| {
a2.lock().unwrap().modify(17);
Inhibit(true)
});

window.show_all();
gtk::main();
}

我会至少等几天,然后将此答案标记为正确,以防有人有更好的答案。

关于gtk - 使用 rust-gnome 时如何将自己的数据获取到 GTK 回调?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31595115/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com