Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用rust gnome时,如何将自己的数据发送到GTK回调?_Gtk_Rust_Rust Gnome - Fatal编程技术网

使用rust gnome时,如何将自己的数据发送到GTK回调?

使用rust gnome时,如何将自己的数据发送到GTK回调?,gtk,rust,rust-gnome,Gtk,Rust,Rust Gnome,。。。或者,如何为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::Widge

。。。或者,如何为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::drawingara
而不是我的
FractalWidget
。我一直在努力调用带有闭包的
connect\u draw
,但没有在其中使用
result
(我尝试了
Box
,然后
将结果移动到lambda中,但我是新手,所以可能有一些方法我没有尝试过)


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

好的,下面是一些实际工作的代码,主要是通过使用
Arc
插入普通
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();
}
extern板条箱开罗;
外部板条箱gtk;
使用cairo::Context;
使用gtk::信号::抑制;
使用gtk::signal::WidgetSignals;
使用gtk::traits::ContainerTrait;
使用gtk::traits::WidgetTrait;
使用std::sync::{Arc,Mutex};
结构MyWidget{
小部件:gtk::DrawingArea,
foo:u32,
}
impl-MyWidget{
fn new()->Arc{
让结果=弧::新(互斥体::新(MyWidget{
小部件:gtk::DrawingArea::new().unwrap(),
傅:17
}));
设r2=result.clone();
result.lock().unwrap().widget.connect|u draw(move|u w,c|{
r2.锁定().展开().重绘(c)
});
结果
}
fn修改(&mut self,x:u32){
self.foo+=x;
self.widget.queue_draw();
}
fn重画(&self,uquo:Context)->禁止{
println!(“应该为{}重新绘制,self.foo);
抑制(真)
}
}
fn main(){
gtk::init().ok();
让window=gtk::window::new(gtk::WindowType::TopLevel).unwrap();
let area=MyWidget::new();
添加(&area.lock().unwrap().widget);
window.connect_delete_事件(| |,|{
gtk::main_quit();
抑制(真)
});
设a1=area.clone();
窗口。连接按键释放事件(移动、事件){
a1.锁定().展开().修改(3);
抑制(真)
});
设a2=area.clone();
窗口。连接按钮释放事件(移动事件){
a2.锁定().展开().修改(17);
抑制(真)
});
window.show_all();
gtk::main();
}

如果有人有更好的答案,我会把这个答案标记为正确答案,至少等几天。

好的,我试着让它更准确一点。。。现在redraw函数尝试使用FractalWidget的一个成员,就像它是w的一个成员一样,这显然不起作用。事实上,我已经找到了一种方法,所以我也会添加一个答案。哈哈,我发现,这通常是创建MCVE的好处之一。它迫使你从一个新的角度来看待问题,真正关注错误^_^请注意,更新后的代码仍然存在错误(未终止的字符串、缺少分号、缺少导入、未定义的变量
区域
,…)。只有当我们能够将它粘贴到一个全新的文件中并使其工作时,它才真正有用。事实上,我在尝试使它MCVE:ish之前找到了我的半解决方案,但我原则上同意…:-)你知道如何在gtk rs的
绘图区域内绘制像素吗?@Moebius:嗯,有点。因为我画了很多像素,所以我把它们放在一个Pixbuf中,然后使用set_source_Pixbuf(…)、rectangle(…)和fill()将Pixbuf复制到上下文中。可能不是最有效的方法。