mmstick / gtkrs-tutorials

2021 Tutorial for GTK-rs
38 stars 4 forks source link

Why async_channel instead of glib builtin? #8

Closed kugel- closed 2 years ago

kugel- commented 2 years ago

Hello, thanks for the invaluable guide, it helped me a lot!

Especially the section about using channels to communicate widget events. However, I'm curious as to why the async_channel crate is used when glib offers the needed functionality: glib::MainContext::channel

As glib is foundational for gtk anyway you could simply get rid of the async_channel dependency,

I was able to achieve the tutorials goals using the following: main.rs:

    let (tx, rx) = glib::MainContext::channel(glib::Priority::default());
    let mut app = app::App::new(tx);

    // GLib has an executor in the background that will
    // asynchronously handle our events on this thread
    rx.attach(Some(&glib::MainContext::default()), move |ev| -> Continue {
        println!("event");
        app.event_handler(ev);
        Continue(true)
    });

app.rs

    pub fn new(tx: Sender<AppEvents>) -> Self
    { 
        …
        let tx_c = tx.clone();
        btn.connect_clicked(move |_| {
            let _ = tx_c.send(AppEvents::Clicked).unwrap();
        });
    }

    pub fn event_handler(&mut self, ev: AppEvents)
    {
        match ev {
            AppEvents::Clicked => { … }
        }
    }
mmstick commented 2 years ago

It is not compatible with async code.

kugel- commented 2 years ago

Okay. I'm getting started with Rust and have no async code in my toy project. Might be helpful if your wonderful tutorial would at least mention it, I found it easier to get started than with async_channel.

mmstick commented 2 years ago

I'd recommend building GTK4 applications with Relm4 instead right now. It'll take care of this and more: https://github.com/Relm4/Relm4/